Repository: FlyGoat/CSMWrap Branch: main Commit: 808ac8ea5393 Files: 80 Total size: 1.4 MB Directory structure: gitextract_bu0ihczz/ ├── .github/ │ ├── dependabot.yml │ └── workflows/ │ └── build.yml ├── .gitignore ├── .gitmodules ├── GNUmakefile ├── LICENSE ├── README.md ├── seabios-config └── src/ ├── acpi.c ├── ap_trampoline.asm ├── apic.c ├── apic.h ├── arch/ │ ├── ia32/ │ │ └── Thunk16.asm │ └── x86_64/ │ └── Thunk16.asm ├── bios_proxy.c ├── bios_proxy.h ├── bootdev.c ├── bootdev.h ├── config.c ├── config.h ├── coreboot.c ├── csmwrap.c ├── csmwrap.h ├── e820.c ├── edk2/ │ ├── Acpi.h │ ├── Acpi10.h │ ├── Acpi20.h │ ├── Acpi30.h │ ├── Acpi40.h │ ├── Acpi50.h │ ├── Acpi51.h │ ├── Acpi60.h │ ├── Acpi61.h │ ├── Acpi62.h │ ├── Acpi63.h │ ├── Acpi64.h │ ├── Acpi65.h │ ├── AcpiAml.h │ ├── Coreboot.h │ ├── E820.h │ ├── Edk2Compat.h │ ├── LegacyBios.h │ ├── LegacyRegion2.h │ ├── Pci.h │ ├── Pci22.h │ ├── Pci23.h │ ├── Pci30.h │ ├── PciCodeId.h │ ├── PciExpress21.h │ ├── PciExpress30.h │ ├── PciExpress31.h │ ├── PciExpress40.h │ ├── PciExpress50.h │ └── PciExpress60.h ├── intel_workarounds.c ├── io.h ├── iommu.c ├── iommu.h ├── libc.c ├── libc.h ├── mptable.c ├── mptable.h ├── oprom.c ├── oprom.h ├── pci.c ├── pci.h ├── pir.c ├── pir.h ├── printf.c ├── printf.h ├── qsort.c ├── qsort.h ├── time.c ├── time.h ├── uacpi_config.h ├── unlock_region.c ├── video.c ├── video.h ├── x86thunk.c └── x86thunk.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: github-actions directory: "/" schedule: interval: "daily" target-branch: main ================================================ FILE: .github/workflows/build.yml ================================================ name: Build on: push: branches: ['**'] tags: ['[0-9]*'] pull_request: workflow_dispatch: jobs: build: runs-on: ubuntu-latest container: archlinux:latest permissions: contents: write steps: - name: Install distro deps run: pacman --noconfirm -Syu && pacman --needed --noconfirm -S base-devel python git vim nasm - name: Mark workspace safe for git run: git config --global --add safe.directory '*' - uses: actions/checkout@v6 with: submodules: true fetch-depth: 0 fetch-tags: true - name: make x86_64 run: | make ARCH=x86_64 mkdir -p bin cp bin-x86_64/csmwrap.efi bin/csmwrapx64.efi - name: make ia32 run: | make ARCH=ia32 mkdir -p bin cp bin-ia32/csmwrap.efi bin/csmwrapia32.efi - uses: actions/upload-artifact@v7 with: name: csmwrap.efi path: bin/*.efi - name: Create draft release if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v3 with: draft: true fail_on_unmatched_files: true files: | bin/csmwrapx64.efi bin/csmwrapia32.efi ================================================ FILE: .gitignore ================================================ /compile_commands.json /.cache /boot /edk2-ovmf /src/bins /bin-* /obj-* ================================================ FILE: .gitmodules ================================================ [submodule "freestnd-c-hdrs"] path = freestnd-c-hdrs url = https://github.com/osdev0/freestnd-c-hdrs-0bsd.git [submodule "cc-runtime"] path = cc-runtime url = https://github.com/osdev0/cc-runtime.git [submodule "picoefi"] path = picoefi url = https://github.com/PicoEFI/PicoEFI.git [submodule "nanoprintf"] path = nanoprintf url = https://github.com/charlesnicholson/nanoprintf.git [submodule "seabios"] path = seabios url = https://github.com/CSMWrap/seabios-csmwrap.git [submodule "uACPI"] path = uACPI url = https://github.com/uACPI/uACPI.git [submodule "flanterm"] path = flanterm url = https://github.com/Mintsuki/Flanterm.git ================================================ FILE: GNUmakefile ================================================ # Nuke built-in rules. .SUFFIXES: # This is the name that our final executable will have. # Change as needed. override OUTPUT := csmwrap # Target architecture to build for. Default to x86_64. ARCH := x86_64 # Install prefix; /usr/local is a good, standard default pick. PREFIX := /usr/local # Check if the architecture is supported. ifeq ($(filter $(ARCH),ia32 x86_64),) $(error Architecture $(ARCH) not supported) endif # Default user QEMU flags. These are appended to the QEMU command calls. QEMUFLAGS := -m 2G -smp 2 # User controllable host C compiler. HOST_CC := cc # User controllable toolchain and toolchain prefix. TOOLCHAIN := TOOLCHAIN_PREFIX := ifneq ($(TOOLCHAIN),) ifeq ($(TOOLCHAIN_PREFIX),) TOOLCHAIN_PREFIX := $(TOOLCHAIN)- endif endif # User controllable C compiler command. ifneq ($(TOOLCHAIN_PREFIX),) CC := $(TOOLCHAIN_PREFIX)gcc else CC := cc endif # User controllable linker command. LD := $(TOOLCHAIN_PREFIX)ld # User controllable objcopy command. OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy # User controllable objdump command. OBJDUMP := $(TOOLCHAIN_PREFIX)objdump # User controllable strip command. STRIP := $(TOOLCHAIN_PREFIX)strip # Defaults overrides for variables if using "llvm" as toolchain. ifeq ($(TOOLCHAIN),llvm) CC := clang LD := ld.lld endif # User controllable C flags. CFLAGS := -g -O2 -pipe # User controllable C preprocessor flags. We set none by default. CPPFLAGS := # User controllable nasm flags. NASMFLAGS := -g # User controllable linker flags. We set none by default. LDFLAGS := # User controllable version string. BUILD_VERSION := $(shell git describe --tags --always 2>/dev/null || echo "Unknown") # Check if CC is Clang. override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep -q '^Target: '; echo $$?) # Save user CFLAGS, CPPFLAGS, and LDFLAGS before we append internal flags. override USER_CFLAGS := $(CFLAGS) override USER_CPPFLAGS := $(CPPFLAGS) override USER_LDFLAGS := $(LDFLAGS) override define SEABIOS_CALL $(MAKE) -C seabios $(1) \ HOSTCC="$(HOST_CC)" \ CC="$(CC)" \ LD="$(LD)" \ OBJCOPY="$(OBJCOPY)" \ OBJDUMP="$(OBJDUMP)" \ STRIP="$(STRIP)" \ CFLAGS="$(USER_CFLAGS)" \ CPPFLAGS="$(USER_CPPFLAGS)" \ LDFLAGS="$(USER_LDFLAGS)" \ EXTRAVERSION=\"$(SEABIOS_EXTRAVERSION)\" endef # Internal C flags that should not be changed by the user. override CFLAGS += \ -Wall \ -Wextra \ -std=gnu11 \ -nostdinc \ -ffreestanding \ -fno-stack-protector \ -fno-stack-check \ -fno-delete-null-pointer-checks \ -fshort-wchar \ -fno-lto \ -fPIE \ -ffunction-sections \ -fdata-sections # Internal C preprocessor flags that should not be changed by the user. override CPPFLAGS := \ -I src \ -I picoefi/inc \ -I flanterm/src \ -I uACPI/include \ -DUACPI_OVERRIDE_CONFIG \ -DBUILD_VERSION=\"$(BUILD_VERSION)\" \ -isystem freestnd-c-hdrs/include \ $(CPPFLAGS) \ -MMD \ -MP obj-$(ARCH)/flanterm/src/flanterm_backends/fb.c.o: override CPPFLAGS += \ -DFLANTERM_FB_DISABLE_BUMP_ALLOC # Internal nasm flags that should not be changed by the user. override NASMFLAGS := \ $(patsubst -g,-g -F dwarf,$(NASMFLAGS)) \ -Wall # Architecture specific internal flags. ifeq ($(ARCH),ia32) ifeq ($(CC_IS_CLANG),1) override CC += \ -target i686-unknown-none-elf endif override CFLAGS += \ -m32 \ -march=i686 \ -mabi=sysv \ -mno-80387 \ -mno-mmx \ -malign-double override LDFLAGS += \ -m elf_i386 override NASMFLAGS := \ -f elf32 \ $(NASMFLAGS) endif ifeq ($(ARCH),x86_64) ifeq ($(CC_IS_CLANG),1) override CC += \ -target x86_64-unknown-none-elf endif override CFLAGS += \ -m64 \ -march=x86-64 \ -mabi=sysv \ -mno-80387 \ -mno-mmx \ -mno-sse \ -mno-sse2 \ -mno-red-zone override LDFLAGS += \ -m elf_x86_64 override NASMFLAGS := \ -f elf64 \ $(NASMFLAGS) endif # Internal linker flags that should not be changed by the user. override LDFLAGS += \ -nostdlib \ -pie \ -z text \ -z max-page-size=0x1000 \ --gc-sections \ -T picoefi/$(ARCH)/link_script.lds # Use "find" to glob all *.c, *.S, and *.asm files in the tree # (except the src/arch/* directories, as those are gonna be added # in the next step). override SRCFILES := $(shell find -L src cc-runtime/src picoefi/$(ARCH) flanterm/src uACPI/source -type f -not -path 'src/arch/*' 2>/dev/null | LC_ALL=C sort) # Add architecture specific files, if they exist. override SRCFILES += $(shell find -L src/arch/$(ARCH) -type f 2>/dev/null | LC_ALL=C sort) # Obtain the object and header dependencies file names. override CFILES := $(filter %.c,$(SRCFILES)) override ASFILES := $(filter %.S,$(SRCFILES)) ifneq ($(filter $(ARCH),ia32 x86_64),) override NASMFILES := $(filter %.asm,$(SRCFILES)) endif override OBJ := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.o) $(ASFILES:.S=.S.o)) ifneq ($(filter $(ARCH),ia32 x86_64),) override OBJ += $(addprefix obj-$(ARCH)/,$(NASMFILES:.asm=.asm.o)) endif override HEADER_DEPS := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.d) $(ASFILES:.S=.S.d)) # Default target. This must come first, before header dependencies. .PHONY: all all: $(MAKE) seabios $(MAKE) bin-$(ARCH)/$(OUTPUT).efi # Include header dependencies. -include $(HEADER_DEPS) obj-$(ARCH)/src/csmwrap.c.o: src/bins/Csm16.h obj-$(ARCH)/src/video.c.o: src/bins/vgabios.h obj-$(ARCH)/src/printf.c.o: override CPPFLAGS += \ -I nanoprintf # Rule to convert the final ELF executable to a .EFI PE executable. bin-$(ARCH)/$(OUTPUT).efi: bin-$(ARCH)/$(OUTPUT) GNUmakefile mkdir -p "$(dir $@)" $(OBJCOPY) -O binary $< $@ dd if=/dev/zero of=$@ bs=4096 count=0 seek=$$(( ($$(wc -c < $@) + 4095) / 4096 )) 2>/dev/null # Link rules for the final executable. bin-$(ARCH)/$(OUTPUT): GNUmakefile picoefi/$(ARCH)/link_script.lds $(OBJ) mkdir -p "$(dir $@)" $(LD) $(LDFLAGS) $(OBJ) -o $@ # Compilation rules for *.c files. obj-$(ARCH)/%.c.o: %.c GNUmakefile mkdir -p "$(dir $@)" $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ # Compilation rules for *.S files. obj-$(ARCH)/%.S.o: %.S GNUmakefile mkdir -p "$(dir $@)" $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ ifneq ($(filter $(ARCH),ia32 x86_64),) # Compilation rules for *.asm (nasm) files. obj-$(ARCH)/%.asm.o: %.asm GNUmakefile mkdir -p "$(dir $@)" nasm $(NASMFLAGS) $< -o $@ endif # Rules to download the UEFI firmware per architecture for testing. edk2-ovmf: curl -L https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/edk2-ovmf.tar.gz | gunzip | tar -xf - # Rules for running our executable in QEMU. .PHONY: run run: all edk2-ovmf mkdir -p boot/EFI/BOOT ifeq ($(ARCH),ia32) cp bin-$(ARCH)/$(OUTPUT).efi boot/EFI/BOOT/BOOTIA32.EFI qemu-system-i386 \ -M q35 \ -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ -drive file=fat:rw:boot \ $(QEMUFLAGS) endif ifeq ($(ARCH),x86_64) cp bin-$(ARCH)/$(OUTPUT).efi boot/EFI/BOOT/BOOTX64.EFI qemu-system-x86_64 \ -M q35 \ -drive if=pflash,unit=0,format=raw,file=edk2-ovmf/ovmf-code-$(ARCH).fd,readonly=on \ -drive file=fat:rw:boot \ $(QEMUFLAGS) endif rm -rf boot # Remove object files and the final executable. .PHONY: clean clean: seabios/.config $(call SEABIOS_CALL,clean) rm -rf bin-$(ARCH) obj-$(ARCH) # Remove everything built and generated including downloaded dependencies. .PHONY: distclean distclean: seabios/.config $(call SEABIOS_CALL,distclean) rm -rf src/bins rm -rf bin-* obj-* .cache compile_commands.json edk2-ovmf # Install the final built executable to its final on-root location. .PHONY: install install: all install -d "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" install -m 644 bin-$(ARCH)/$(OUTPUT).efi "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH).efi" # Try to undo whatever the "install" target did. .PHONY: uninstall uninstall: rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH).efi" -rmdir "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" # SeaBIOS build targets. SEABIOS_EXTRAVERSION := -CSMWrap-$(BUILD_VERSION) .PHONY: seabios seabios: seabios/.config $(call SEABIOS_CALL,) src/bins/Csm16.h: GNUmakefile seabios/out/Csm16.bin mkdir -p src/bins cd seabios/out && xxd -i Csm16.bin >../../src/bins/Csm16.h src/bins/vgabios.h: GNUmakefile seabios/out/vgabios.bin mkdir -p src/bins cd seabios/out && xxd -i vgabios.bin >../../src/bins/vgabios.h seabios/.config: GNUmakefile seabios-config cp seabios-config seabios/.config $(call SEABIOS_CALL,olddefconfig) ================================================ FILE: LICENSE ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: README.md ================================================

CSMWrap

Build Status Discord

CSMWrap logo

CSMWrap is an EFI application designed to be a drop-in solution to enable legacy BIOS booting on modern UEFI-only (class 3) systems. It achieves this by wrapping a Compatibility Support Module (CSM) build of the [SeaBIOS project](https://www.seabios.org/) as an out-of-firmware EFI application, effectively creating a compatibility layer for traditional PC BIOS operation. Logo art by [conkkerxd](https://github.com/conkkerxd). ## Executive Summary The idea is to drop the 64-bit or 32-bit version of CSMWrap (depending on the hardware, dropping both also works) into a `/EFI/BOOT/` directory on a FAT (12, 16, or 32) partition on the medium containing the legacy BIOS OS. UEFI firmware will pick this up and show the medium as a bootable device. Ideally, that's all that would be needed. 1. **Download:** Get the latest `csmwrap.efi` from the [Releases page](https://github.com/CSMWrap/CSMWrap/releases). 2. **Deploy:** Copy `csmwrap.efi` to a FAT-formatted partition, typically as `/EFI/BOOT/BOOTX64.EFI` (for 64-bit) or `/EFI/BOOT/BOOTIA32.EFI` (for 32-bit) (the hardcoded path is needed so that the firmware picks it up automatically). 3. **Boot:** Select the UEFI boot entry for the drive onto which CSMWrap was deployed. It is highly recommended that the partition table used is MBR (MS-DOS partition table), as UEFI firmwares are perfectly capable of booting off of this format, and because it is the most compatible with most legacy OSes one may want to boot. ## Additional Prerequisites ### Secure Boot Secure boot should be disabled unless one wants to manually sign the CSMWrap EFI application, which is possible, but beyond the scope of this README. ### Firmware Settings CSMWrap is designed to be as drop-in as possible, without requiring changes to firmware for settings that may not even be exposed (depending on the firmware), or that might conflict with other UEFI OSes being multi-booted on the system. That said, if at all possible, disabling these settings is highly recommended for best legacy OS compatibility: 1. **X2APIC** Additional settings to try to disable if things still do not work (ideally this should *not* be necessary, please report an issue if you need this on your hardware!): 1. **Above 4G Decoding** 2. **Resizable BAR/Smart Access Memory** ### Video Card Considerations CSMWrap also wraps the "SeaVGABIOS" module of SeaBIOS for providing a bare bones implementation of a legacy Video BIOS. That said, SeaVGABIOS is far from ideal, and many, **many** things requiring more direct access to legacy video modes won't work properly (e.g. pretty much all MS-DOS games, MS-DOS Editor, etc.). More modern OSes using the VESA BIOS extensions (VBE) standard only (e.g. more modern Windows NT, Linux, etc.) should still work fine, though. Therefore it is **highly recommended**, if possible, to install a legacy-capable video card. If one is present, its Video BIOS will be used instead of SeaVGABIOS, providing a much better, pretty much native-like, experience. ## Configuration CSMWrap supports an optional INI-style configuration file. Place a file named `csmwrap.ini` in the same directory as the CSMWrap EFI executable (e.g. `/EFI/BOOT/csmwrap.ini`). If the file is absent, sensible defaults are used. ### Options | Key | Type | Default | Description | |-----|------|---------|-------------| | `serial` | bool | `false` | Enable serial debug output | | `serial_port` | hex/int | `0x3f8` | Serial I/O port address (COM1=`0x3f8`, COM2=`0x2f8`, COM3=`0x3e8`, COM4=`0x2e8`) | | `serial_baud` | int | `115200` | Serial baud rate | | `vgabios` | string | *(empty)* | Path to a custom VBIOS file on the ESP (e.g. `\EFI\CSMWrap\vgabios.bin`). When empty, the card's built-in OpROM is used, and, failing that, SeaVGABIOS is used | | `iommu_disable` | bool | `true` | Disable IOMMUs (Intel VT-d / AMD-Vi) before legacy boot | | `verbose` | bool | `false` | Show debug output on screen via Flanterm | | `vga` | PCI address | *(empty)* | PCI address of the VGA card to use (e.g. `00:02.0`). Format: `BB:DD.F` (hex). When empty, the first available card is used | | `system_thread` | int/hex | *(auto)* | APIC ID of the logical CPU to reserve as the CSMWrap system thread (see [the FAQs](#frequently-asked-questions)). Must be an enabled AP (not the BSP) and have an APIC ID below `0xFF`/`255`. When empty, CSMWrap auto-picks the highest-ID AP below `0xFF`/`255`. The selected CPU is hidden from the OS in both the MADT and the MP table | | `cpu_allowlist` | int/hex list | *(unset)* | Comma-separated list of APIC IDs of logical CPUs that should be exposed to the OS in the MADT and the MP table. Each entry is either a single ID or an inclusive range `N-M` (e.g. `0,2-4,7`). An empty value (`cpu_allowlist =`) is itself a setting and means "hide every AP" (only the BSP stays visible). The BSP is always exposed regardless. The system thread is always hidden regardless. Mutually exclusive with `cpu_blocklist` | | `cpu_blocklist` | int/hex list | *(unset)* | Comma-separated list of APIC IDs of logical CPUs that should be hidden from the OS in the MADT and the MP table. Each entry is either a single ID or an inclusive range `N-M` (e.g. `5-7`). An empty value (`cpu_blocklist =`) is a no-op for visibility but still claims the slot, so `cpu_allowlist` cannot also be set. The BSP is always exposed regardless. The system thread is always hidden regardless. Mutually exclusive with `cpu_allowlist` | Boolean values accept `true`/`yes`/`1` and `false`/`no`/`0` (case-insensitive). Comments start with `;` or `#`. ### Example ```ini ; CSMWrap configuration serial = true serial_port = 0x3f8 serial_baud = 115200 vgabios = \EFI\CSMWrap\vgabios.bin iommu_disable = true ; Pin the system thread to APIC ID 7 and hide APIC IDs 4 through 6 from the OS. system_thread = 7 cpu_blocklist = 4-6 ``` ## Frequently Asked Questions ### Is this an emulator? No! At least not in the sense of it being a full-screened emulator window. Running a legacy OS with CSMWrap means that it is *natively* running on the system. CSMWrap attempts to recreate, natively, and as closely as possible, a legacy BIOS PC environment on modern UEFI class 3 systems. ### I booted a multi-core capable OS and I am missing a logical processor (thread), what gives? This is expected. CSMWrap reserves 1 logical processor for "system" use due to the limitations of running out-of-firmware and not being able to use [SMM (System Management Mode)](https://en.wikipedia.org/wiki/System_Management_Mode). Therefore, this means that CSMWrap **does not support running on systems with only 1 logical processor (i.e. only 1 core and no SMT/hyperthreading)**. That said, most systems that CSMWrap targets (i.e. modern UEFI class 3 systems) will definitely have way more than a single logical processor, so this is mostly a non-issue. ### Does CSMWrap have any advantages over native CSM? Yes! Native CSM firmware is often riddled with issues and hardly tested against legacy OSes anymore. CSMWrap ships a reliable, free, and open-source legacy BIOS implementation - SeaBIOS - and it is tested against legacy OSes. Issues affecting modern, commonly shipped CSM implementations do not affect CSMWrap, like for example: - Dirty control register values at handoff. (This is something that [cregfix](https://github.com/mintsuki/cregfix) was created to work around). - Legacy BIOS routines failing to reliably run when called from Virtual 8086 Mode. EMM386, Windows 3.x under 386 enhanced mode, and more, are affected by this issue and it results in crashes. The reason for this is a bit technical for this README file, but CSMWrap is not affected. And when it comes to improvements that are not necessarily bugs in CSM implementations, CSMWrap, amongst other things: - Generates MP tables for legacy OSes that support the legacy Intel MultiProcessor Specification standard but not ACPI. - Allows one to select a non-primary video card for VGA output which native CSM implementations do not allow. This is useful for multi-booting modern and legacy OSes. ## Contributing Contributions are welcome! Whether it's reporting bugs, suggesting features, improving documentation, or submitting code changes, your help is appreciated. Additionally, one can join our [Discord server](https://discord.gg/3CCgJpzNXH) for any project-related discussion, or to otherwise chat with likeminded people. ## Credits & Acknowledgements * The **[SeaBIOS project](https://www.seabios.org/)** for their CSM and VBIOS code. * **[PicoEFI](https://github.com/PicoEFI/PicoEFI)** for the EFI C runtime, build system, and headers. * **[EDK2 (TianoCore)](https://github.com/tianocore/edk2)** for UEFI specifications and some code snippets. * **[uACPI](https://github.com/uACPI/uACPI)** for ACPI table handling. * **@CanonKong** for test feedback and general knowledge. * All contributors and testers from the community! ================================================ FILE: seabios-config ================================================ CONFIG_CSM=y # CONFIG_FLASH_FLOPPY is not set # CONFIG_VGAHOOKS is not set # CONFIG_TCGBIOS is not set CONFIG_VGA_COREBOOT=y ================================================ FILE: src/acpi.c ================================================ #include #include #include #include #include #include "csmwrap.h" #include #include #include uintptr_t g_rsdp = 0; static inline const char *uacpi_log_level_to_string(uacpi_log_level lvl) { switch (lvl) { case UACPI_LOG_DEBUG: return "DEBUG"; case UACPI_LOG_TRACE: return "TRACE"; case UACPI_LOG_INFO: return "INFO"; case UACPI_LOG_WARN: return "WARN"; case UACPI_LOG_ERROR: default: return "ERROR"; } } void uacpi_kernel_log(enum uacpi_log_level lvl, const char *text) { printf("[uACPI][%s] %s", uacpi_log_level_to_string(lvl), text); } void *uacpi_kernel_map(uacpi_phys_addr addr, EFI_UNUSED uacpi_size len) { return (void*)((uintptr_t)addr); } void uacpi_kernel_unmap(EFI_UNUSED void *ptr, EFI_UNUSED uacpi_size len) { } uacpi_status uacpi_kernel_pci_device_open(uacpi_pci_address address, uacpi_handle *out_handle) { void *handle; if (gBS->AllocatePool(EfiLoaderData, sizeof(struct pci_address), &handle) != EFI_SUCCESS) { return UACPI_STATUS_OUT_OF_MEMORY; } struct pci_address *pci_address = (struct pci_address *)handle; pci_address->segment = address.segment; pci_address->bus = address.bus; pci_address->slot = address.device; pci_address->function = address.function; *out_handle = handle; return UACPI_STATUS_OK; } void uacpi_kernel_pci_device_close(uacpi_handle handle) { gBS->FreePool(handle); } uacpi_status uacpi_kernel_pci_read8(uacpi_handle device, uacpi_size offset, uacpi_u8 *value) { *value = pci_read8((struct pci_address *)device, offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_pci_read16(uacpi_handle device, uacpi_size offset, uacpi_u16 *value) { *value = pci_read16((struct pci_address *)device, offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_pci_read32(uacpi_handle device, uacpi_size offset, uacpi_u32 *value) { *value = pci_read32((struct pci_address *)device, offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value) { pci_write8((struct pci_address *)device, offset, value); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value) { pci_write16((struct pci_address *)device, offset, value); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value) { pci_write32((struct pci_address *)device, offset, value); return UACPI_STATUS_OK; } struct mapped_io { uacpi_io_addr base; uacpi_size len; }; uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle) { void *handle; if (gBS->AllocatePool(EfiLoaderData, sizeof(struct mapped_io), &handle) != EFI_SUCCESS) { return UACPI_STATUS_OUT_OF_MEMORY; } struct mapped_io *io = (struct mapped_io *)handle; io->base = base; io->len = len; *out_handle = handle; return UACPI_STATUS_OK; } void uacpi_kernel_io_unmap(uacpi_handle handle) { gBS->FreePool(handle); } uacpi_status uacpi_kernel_io_read8(uacpi_handle handle, uacpi_size offset, uacpi_u8 *out_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } *out_value = inb(io->base + offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_io_read16(uacpi_handle handle, uacpi_size offset, uacpi_u16 *out_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } *out_value = inw(io->base + offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_io_read32(uacpi_handle handle, uacpi_size offset, uacpi_u32 *out_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } *out_value = inl(io->base + offset); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_io_write8(uacpi_handle handle, uacpi_size offset, uacpi_u8 in_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } outb(io->base + offset, in_value); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_io_write16(uacpi_handle handle, uacpi_size offset, uacpi_u16 in_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } outw(io->base + offset, in_value); return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_io_write32(uacpi_handle handle, uacpi_size offset, uacpi_u32 in_value) { struct mapped_io *io = (struct mapped_io *)handle; if (offset >= io->len) { return UACPI_STATUS_INVALID_ARGUMENT; } outl(io->base + offset, in_value); return UACPI_STATUS_OK; } uacpi_interrupt_state uacpi_kernel_disable_interrupts(void) { uacpi_interrupt_state flags; asm volatile ("pushf; pop %0; cli" : "=rm"(flags) :: "memory"); return flags; } void uacpi_kernel_restore_interrupts(uacpi_interrupt_state state) { asm volatile ("push %0; popf" :: "rm"(state) : "memory", "cc"); } uacpi_handle uacpi_kernel_create_spinlock(void) { void *handle; if (gBS->AllocatePool(EfiLoaderData, 0x1, &handle) != EFI_SUCCESS) { return NULL; } return handle; } void uacpi_kernel_free_spinlock(uacpi_handle handle) { gBS->FreePool(handle); } uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle handle) { (void)handle; return 0; } void uacpi_kernel_unlock_spinlock(uacpi_handle handle, uacpi_cpu_flags cpu_flags) { (void)handle; (void)cpu_flags; } uacpi_handle uacpi_kernel_create_event(void) { void *handle; if (gBS->AllocatePool(EfiLoaderData, 0x1, &handle) != EFI_SUCCESS) { return NULL; } return handle; } void uacpi_kernel_free_event(uacpi_handle handle) { gBS->FreePool(handle); } uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle handle, uacpi_u16 timeout) { (void)handle; (void)timeout; return UACPI_TRUE; } void uacpi_kernel_signal_event(uacpi_handle handle) { (void)handle; } void uacpi_kernel_reset_event(uacpi_handle handle) { (void)handle; } uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void) { return get_nanoseconds_since_boot(); } void uacpi_kernel_stall(uacpi_u8 usec) { gBS->Stall(usec); } void uacpi_kernel_sleep(uacpi_u64 msec) { gBS->Stall(msec * 1000); } uacpi_thread_id uacpi_kernel_get_thread_id(void) { return (uacpi_thread_id)1; } uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *request) { (void)request; return UACPI_STATUS_UNIMPLEMENTED; } uacpi_status uacpi_kernel_install_interrupt_handler( uacpi_u32 irq, uacpi_interrupt_handler handler, uacpi_handle ctx, uacpi_handle *out_irq_handle) { (void)irq; (void)handler; (void)ctx; (void)out_irq_handle; return UACPI_STATUS_OK; } uacpi_status uacpi_kernel_uninstall_interrupt_handler(uacpi_interrupt_handler handler, uacpi_handle irq_handle) { (void)handler; (void)irq_handle; return UACPI_STATUS_UNIMPLEMENTED; } uacpi_status uacpi_kernel_schedule_work(uacpi_work_type work_type, uacpi_work_handler handler, uacpi_handle ctx) { (void)work_type; (void)handler; (void)ctx; return UACPI_STATUS_UNIMPLEMENTED; } uacpi_status uacpi_kernel_wait_for_work_completion(void) { return UACPI_STATUS_UNIMPLEMENTED; } void *uacpi_kernel_alloc(uacpi_size size) { void *result; if (gBS->AllocatePool(EfiLoaderData, size, &result) != EFI_SUCCESS) { return NULL; } return result; } void uacpi_kernel_free(void *mem) { if (mem != NULL) { gBS->FreePool(mem); } } uacpi_handle uacpi_kernel_create_mutex(void) { void *handle; if (gBS->AllocatePool(EfiLoaderData, 0x1, &handle) != EFI_SUCCESS) { return NULL; } return handle; } void uacpi_kernel_free_mutex(uacpi_handle handle) { gBS->FreePool(handle); } uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle handle, uacpi_u16 timeout) { (void)handle; (void)timeout; return UACPI_STATUS_OK; } void uacpi_kernel_release_mutex(uacpi_handle handle) { (void)handle; } uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *rsdp) { if (!g_rsdp) { return UACPI_STATUS_NOT_FOUND; } *rsdp = g_rsdp; return UACPI_STATUS_OK; } static void *early_table_buffer; bool acpi_init(struct csmwrap_priv *priv) { UINTN i; EFI_GUID acpiGuid = ACPI_TABLE_GUID; EFI_GUID acpi2Guid = ACPI_20_TABLE_GUID; void *table_target = priv->csm_bin + (priv->csm_efi_table->AcpiRsdPtrPointer - priv->csm_bin_base); for (i = 0; i < gST->NumberOfTableEntries; i++) { EFI_CONFIGURATION_TABLE *table; table = gST->ConfigurationTable + i; if (!efi_guidcmp(table->VendorGuid, acpi2Guid)) { printf("Found ACPI 2.0 RSDT at %x, copied to %x\n", (uintptr_t)table->VendorTable, (uintptr_t)table_target); memcpy(table_target, table->VendorTable, sizeof(EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)); g_rsdp = (uintptr_t)table->VendorTable; break; } } if (g_rsdp == 0) { for (i = 0; i < gST->NumberOfTableEntries; i++) { EFI_CONFIGURATION_TABLE *table; table = gST->ConfigurationTable + i; if (!efi_guidcmp(table->VendorGuid, acpiGuid)) { printf("Found ACPI 1.0 RSDT at %x, copied to %x\n", (uintptr_t)table->VendorTable, (uintptr_t)table_target); memcpy(table_target, table->VendorTable, sizeof(EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)); g_rsdp = (uintptr_t)table->VendorTable; break; } } } if (g_rsdp) { const size_t table_buffer_size = 4096; if (gBS->AllocatePool(EfiLoaderData, table_buffer_size, &early_table_buffer) != EFI_SUCCESS) { return false; } enum uacpi_status uacpi_status; uacpi_status = uacpi_setup_early_table_access(early_table_buffer, table_buffer_size); if (uacpi_status != UACPI_STATUS_OK) { printf("uACPI early table setup failed: %s\n", uacpi_status_to_string(uacpi_status)); return false; } return true; } printf("No ACPI RSDT found\n"); return false; } /* * Initialize ACPI namespace without running _INI methods. * This is sufficient for PCI root bridge discovery via _CRS evaluation. * Avoids side effects like changing power button behavior. */ bool acpi_namespace_init(void) { enum uacpi_status uacpi_status; uacpi_status = uacpi_initialize(UACPI_FLAG_NO_ACPI_MODE); if (uacpi_status != UACPI_STATUS_OK) { printf("uACPI initialization failed: %s\n", uacpi_status_to_string(uacpi_status)); return false; } uacpi_status = uacpi_namespace_load(); if (uacpi_status != UACPI_STATUS_OK) { printf("uACPI namespace load failed: %s\n", uacpi_status_to_string(uacpi_status)); return false; } /* Note: We intentionally skip uacpi_namespace_initialize() which runs _INI methods */ return true; } ================================================ FILE: src/ap_trampoline.asm ================================================ ; AP Trampoline for BIOS Proxy Helper Core ; This code is copied to 0x7000 and runs when an AP wakes from SIPI ; AP starts at CS:IP = 0x0700:0x0000 = linear 0x7000 ; ; This trampoline stays in 16-bit real mode and jumps to the SeaBIOS ; 16-bit entry point, which handles the GDT load and 32-bit mode switch. bits 16 section .rodata ; APIC MSR %define MSR_IA32_APIC_BASE 0x1B %define APIC_BASE_EXTD (1 << 10) %define APIC_BASE_EN (1 << 11) ; AMD MTRR MSR addresses %define MSR_SYS_CFG 0xC0010010 %define SYS_CFG_MTRR_FIX_DRAM_EN (1 << 18) %define SYS_CFG_MTRR_FIX_DRAM_MOD_EN (1 << 19) ; Fixed MTRRs for conventional memory (0x00000-0x9FFFF) %define AMD_MTRR_FIX64k_00000 0x250 ; 0x00000-0x7FFFF (512KB, 8x64KB) %define AMD_MTRR_FIX16k_80000 0x258 ; 0x80000-0x9FFFF (128KB, 8x16KB) %define AMD_MTRR_FIX16k_A0000 0x259 ; 0xA0000-0xBFFFF (VGA, 128KB, 8x16KB) ; Fixed MTRRs for BIOS region (0xC0000-0xFFFFF) %define AMD_MTRR_FIX4k_C0000 0x268 %define AMD_MTRR_FIX4k_C8000 0x269 %define AMD_MTRR_FIX4k_D0000 0x26A %define AMD_MTRR_FIX4k_D8000 0x26B %define AMD_MTRR_FIX4k_E0000 0x26C %define AMD_MTRR_FIX4k_E8000 0x26D %define AMD_MTRR_FIX4k_F0000 0x26E %define AMD_MTRR_FIX4k_F8000 0x26F ; WB_DRAM = 0x1E per segment (8 segments per MSR = 0x1E1E1E1E1E1E1E1E) %define MTRR_WB_DRAM_LO 0x1E1E1E1E %define MTRR_WB_DRAM_HI 0x1E1E1E1E global ap_trampoline_start ap_trampoline_start: cli cld ; Set up DS=0 so we can read from trampoline data area xor ax, ax mov ds, ax mov es, ax mov ss, ax jmp 0x0000:word (0x7000 + .reload_cs - ap_trampoline_start) .reload_cs: ; ======================================== ; AMD MTRR unlock for low memory (00000-FFFFF) ; Sets conventional memory and BIOS region to WB_DRAM ; Required for helper core to access EBDA and F-segment ; Skipped on Intel (PAM registers are global, already unlocked by BSP) ; Skipped if region is already writable (e.g., under hypervisors) ; ======================================== ; First test if the BIOS region is already writable ; Try writing a test pattern to 0xF0000 and reading it back ; Use segmentation: 0xF000:0x0000 = linear 0xF0000 ; Save and restore original value to avoid corrupting CSM code mov ax, 0xF000 mov fs, ax mov eax, [fs:0] ; save original value mov ebx, eax xor eax, 0xFFFFFFFF ; flip all bits to create test pattern mov [fs:0], eax ; try to write cmp [fs:0], eax ; did the write succeed? mov [fs:0], ebx ; restore original (regardless of result) je .skip_mtrr_unlock ; Region already writable, skip MTRR unlock ; Region not writable - check if this is AMD ; On Intel, PAM registers are global so BSP unlock applies to all cores ; If we get here on Intel, something is wrong - halt mov eax, 0 cpuid cmp ebx, 0x68747541 ; "Auth" (AuthenticAMD) jne .unlock_failed ; Not AMD and not writable - halt ; AMD APM Vol 2 §7.6.3: disable cache and flush around MTRR change. ; Paging is off in real mode so no TLB / PGE handling is required. ; (CD=1, NW=1) is unsupported per Intel SDM Vol 3A §11.5.3. mov eax, cr0 mov edi, eax ; save CR0 or eax, 0x40000000 ; CR0.CD = 1 and eax, ~0x20000000 ; CR0.NW = 0 mov cr0, eax wbinvd ; AMD system with locked region - attempt MTRR unlock ; Enable MTRR modification: set SYS_CFG.MtrrFixDramModEn (bit 19) mov ecx, MSR_SYS_CFG rdmsr or eax, SYS_CFG_MTRR_FIX_DRAM_MOD_EN wrmsr ; Set conventional memory (00000-9FFFF) to WB_DRAM mov eax, MTRR_WB_DRAM_LO mov edx, MTRR_WB_DRAM_HI mov ecx, AMD_MTRR_FIX64k_00000 ; 0x00000-0x7FFFF wrmsr mov ecx, AMD_MTRR_FIX16k_80000 ; 0x80000-0x9FFFF (includes EBDA) wrmsr ; Set VGA region (A0000-BFFFF) to UC (MMIO) xor eax, eax xor edx, edx mov ecx, AMD_MTRR_FIX16k_A0000 wrmsr ; Set BIOS region (C0000-FFFFF) to WB_DRAM mov eax, MTRR_WB_DRAM_LO mov edx, MTRR_WB_DRAM_HI mov ecx, AMD_MTRR_FIX4k_C0000 wrmsr mov ecx, AMD_MTRR_FIX4k_C8000 wrmsr mov ecx, AMD_MTRR_FIX4k_D0000 wrmsr mov ecx, AMD_MTRR_FIX4k_D8000 wrmsr mov ecx, AMD_MTRR_FIX4k_E0000 wrmsr mov ecx, AMD_MTRR_FIX4k_E8000 wrmsr mov ecx, AMD_MTRR_FIX4k_F0000 wrmsr mov ecx, AMD_MTRR_FIX4k_F8000 wrmsr ; Disable modification, enable fixed MTRR DRAM attributes mov ecx, MSR_SYS_CFG rdmsr and eax, ~SYS_CFG_MTRR_FIX_DRAM_MOD_EN or eax, SYS_CFG_MTRR_FIX_DRAM_EN wrmsr wbinvd mov cr0, edi ; restore CR0 ; Verify the unlock worked by testing write again ; FS still points to 0xF000 from earlier ; Save and restore original value to avoid corrupting CSM code mov eax, [fs:0] ; save original value mov ebx, eax xor eax, 0xFFFFFFFF ; flip all bits to create test pattern mov [fs:0], eax ; try to write cmp [fs:0], eax ; did the write succeed? mov [fs:0], ebx ; restore original (regardless of result) jne .unlock_failed ; MTRR unlock didn't help - halt .skip_mtrr_unlock: ; Continue to load registers and jump to SeaBIOS jmp .continue_boot .unlock_failed: ; Region still not writable - halt so BSP detects timeout hlt jmp .unlock_failed .continue_boot: ; Hardware-disable LAPIC to prevent the legacy OS from sending IPIs ; (including INIT) to this core. The helper core communicates via ; memory mailbox only and does not need interrupt delivery. ; Must clear both EN (bit 11) and EXTD (bit 10) simultaneously ; to correctly transition from x2APIC mode to disabled state. ; ; If the AP came up already in x2APIC mode (EXTD set), the BSP-side ; apic_prepare_for_legacy() must have left x2APIC alone, meaning the ; mode is locked (e.g. Nova Lake xAPIC deprecation) or the silicon has ; no xAPIC support at all. In either case clearing EXTD here would #GP, ; so we leave the APIC enabled. A legacy OS cannot send x2APIC-mode ; IPIs via MMIO anyway, so the helper stays unreachable to it. mov ecx, MSR_IA32_APIC_BASE rdmsr test eax, APIC_BASE_EXTD jnz .skip_apic_disable and eax, ~(APIC_BASE_EN | APIC_BASE_EXTD) wrmsr .skip_apic_disable: ; Load 32-bit values into registers for SeaBIOS ; (16-bit mode can still use 32-bit registers with operand size prefix) mov ebx, [0x7000 + trampoline_mailbox - ap_trampoline_start] mov esp, [0x7000 + trampoline_stack - ap_trampoline_start] mov esi, (0x7000 + trampoline_helper_ready - ap_trampoline_start) ; Far jump to SeaBIOS 16-bit entry point (segment:offset) jmp far [0x7000 + trampoline_target16 - ap_trampoline_start] ; --- Data area (filled in by C code) --- align 4 trampoline_mailbox: dd 0 trampoline_stack: dd 0 ; Far pointer for 16-bit jump: offset (16-bit) then segment (16-bit) trampoline_target16: dw 0 ; offset dw 0 ; segment trampoline_helper_ready: dd 0 ap_trampoline_end: global ap_trampoline_size ap_trampoline_size: equ (ap_trampoline_end - ap_trampoline_start) ; Export size and offsets for C code global ap_trampoline_size_value ap_trampoline_size_value: dd ap_trampoline_size global ap_trampoline_mailbox_offset ap_trampoline_mailbox_offset: dd (trampoline_mailbox - ap_trampoline_start) global ap_trampoline_stack_offset ap_trampoline_stack_offset: dd (trampoline_stack - ap_trampoline_start) global ap_trampoline_target16_offset ap_trampoline_target16_offset: dd (trampoline_target16 - ap_trampoline_start) global ap_trampoline_helper_ready_offset ap_trampoline_helper_ready_offset: dd (trampoline_helper_ready - ap_trampoline_start) section .note.GNU-stack noalloc noexec nowrite progbits ================================================ FILE: src/apic.c ================================================ /* * APIC handling for legacy BIOS compatibility * * Modern UEFI systems boot with x2APIC enabled, which prevents legacy PIC * interrupts (like IRQ0 timer) from reaching the CPU. This module handles * the transition to a state compatible with legacy BIOS operation. * * References: * - Intel 64 Architecture x2APIC Specification * - EDK2 BaseXApicX2ApicLib * - Linux kernel x86/apic code */ #include #include #include #include #include #include #include /* MSR addresses */ #define MSR_IA32_APIC_BASE 0x1B #define MSR_IA32_ARCH_CAPABILITIES 0x10A #define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD /* IA32_APIC_BASE bits */ #define APIC_BASE_BSP (1ULL << 8) /* Bootstrap processor */ #define APIC_BASE_EXTD (1ULL << 10) /* x2APIC mode enable */ #define APIC_BASE_EN (1ULL << 11) /* APIC global enable */ #define APIC_BASE_ADDR_MASK 0xFFFFFFFFFFFFF000ULL /* IA32_ARCH_CAPABILITIES bits */ #define ARCH_CAP_XAPIC_DISABLE (1ULL << 21) /* IA32_XAPIC_DISABLE_STATUS exists */ /* IA32_XAPIC_DISABLE_STATUS bits */ #define XAPIC_DISABLE_LEGACY_DISABLED (1ULL << 0) /* xAPIC mode locked out */ /* x2APIC MSR addresses (base 0x800, offset = xAPIC offset >> 4) */ #define X2APIC_MSR_SIVR 0x80F /* Spurious Interrupt Vector (0xF0 >> 4) */ #define X2APIC_MSR_LVT_CMCI 0x82F /* LVT CMCI (0x2F0 >> 4) */ #define X2APIC_MSR_LVT_TIMER 0x832 /* LVT Timer (0x320 >> 4) */ #define X2APIC_MSR_LVT_THERMAL 0x833 /* LVT Thermal (0x330 >> 4) */ #define X2APIC_MSR_LVT_PMC 0x834 /* LVT PMC (0x340 >> 4) */ #define X2APIC_MSR_LVT_LINT0 0x835 /* LVT LINT0 (0x350 >> 4) */ #define X2APIC_MSR_LVT_LINT1 0x836 /* LVT LINT1 (0x360 >> 4) */ #define X2APIC_MSR_LVT_ERROR 0x837 /* LVT Error (0x370 >> 4) */ #define X2APIC_MSR_VERSION 0x803 /* Version (0x030 >> 4) */ #define X2APIC_MSR_TPR 0x808 /* Task Priority (0x080 >> 4) */ /* xAPIC MMIO offsets (from APIC base, typically 0xFEE00000) */ #define XAPIC_VERSION_OFFSET 0x030 #define XAPIC_TPR_OFFSET 0x080 #define XAPIC_SIVR_OFFSET 0x0F0 #define XAPIC_LVT_CMCI_OFFSET 0x2F0 #define XAPIC_LVT_TIMER_OFFSET 0x320 #define XAPIC_LVT_THERMAL_OFFSET 0x330 #define XAPIC_LVT_PMC_OFFSET 0x340 #define XAPIC_LVT_LINT0_OFFSET 0x350 #define XAPIC_LVT_LINT1_OFFSET 0x360 #define XAPIC_LVT_ERROR_OFFSET 0x370 /* LVT register bits */ #define LVT_VECTOR_MASK 0xFF #define LVT_DELIVERY_MODE_SHIFT 8 #define LVT_DELIVERY_MODE_MASK (0x7 << LVT_DELIVERY_MODE_SHIFT) #define LVT_DELIVERY_FIXED (0 << LVT_DELIVERY_MODE_SHIFT) #define LVT_DELIVERY_NMI (4 << LVT_DELIVERY_MODE_SHIFT) #define LVT_DELIVERY_EXTINT (7 << LVT_DELIVERY_MODE_SHIFT) #define LVT_POLARITY_ACTIVE_LOW (1 << 13) #define LVT_TRIGGER_LEVEL (1 << 15) #define LVT_MASK (1 << 16) /* Spurious Interrupt Vector Register bits */ #define SIVR_VECTOR_MASK 0xFF #define SIVR_APIC_ENABLE (1 << 8) #define SIVR_FOCUS_DISABLE (1 << 9) /* * Check if x2APIC mode is locked and cannot be disabled. * Returns true if x2APIC is locked (will #GP on disable attempt). */ static bool x2apic_is_locked(void) { uint32_t eax, ebx, ecx, edx; /* Check CPUID for IA32_ARCH_CAPABILITIES support (leaf 7, ECX bit 29) */ asm volatile ("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(7), "c"(0)); if (!(edx & (1 << 29))) { /* IA32_ARCH_CAPABILITIES not supported, no lock possible */ return false; } /* Check if IA32_XAPIC_DISABLE_STATUS MSR exists */ uint64_t arch_cap = rdmsr(MSR_IA32_ARCH_CAPABILITIES); if (!(arch_cap & ARCH_CAP_XAPIC_DISABLE)) { /* MSR not supported, no lock possible */ return false; } /* Read the lock status */ uint64_t xapic_status = rdmsr(MSR_IA32_XAPIC_DISABLE_STATUS); return !!(xapic_status & XAPIC_DISABLE_LEGACY_DISABLED); } static bool lvt_should_mask(uint32_t lvt) { switch ((lvt >> LVT_DELIVERY_MODE_SHIFT) & 7) { case 0b000: /* Fixed */ case 0b001: /* Lowest Priority */ case 0b100: /* NMI */ case 0b111: /* ExtINT */ return true; default: /* SMI, INIT, Reserved */ return false; } } /* MADT NMI routing (loaded once by apic_prepare_for_legacy). */ static uint8_t g_nmi_lint = 1; /* default: NMI on LINT1 */ static uint16_t g_nmi_madt_flags = 0; /* MADT polarity/trigger flags */ static void load_nmi_madt_info(void) { struct uacpi_table madt_table; if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK) { return; } struct acpi_madt *madt = (struct acpi_madt *)madt_table.virt_addr; uint8_t *entry = (uint8_t *)(madt + 1); uint8_t *end = (uint8_t *)madt + madt->hdr.length; while (entry < end) { struct acpi_entry_hdr *hdr = (struct acpi_entry_hdr *)entry; if (hdr->length < 2) break; if (hdr->type == ACPI_MADT_ENTRY_TYPE_LAPIC_NMI) { struct acpi_madt_lapic_nmi *nmi = (struct acpi_madt_lapic_nmi *)entry; g_nmi_lint = nmi->lint & 1; g_nmi_madt_flags = nmi->flags; break; } if (hdr->type == ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC_NMI) { struct acpi_madt_x2apic_nmi *nmi = (struct acpi_madt_x2apic_nmi *)entry; g_nmi_lint = nmi->lint & 1; g_nmi_madt_flags = nmi->flags; break; } entry += hdr->length; } uacpi_table_unref(&madt_table); } /* Build the LVT value (delivery mode + polarity/trigger) for one LINT pin. * The pin matching MADT's NMI routing gets NMI delivery with MADT-supplied * polarity/trigger; the other gets ExtINT (edge, active high). */ static uint32_t lint_lvt_value(int pin) { if (pin == g_nmi_lint) { uint32_t val = LVT_DELIVERY_NMI; if ((g_nmi_madt_flags & ACPI_MADT_POLARITY_MASK) == ACPI_MADT_POLARITY_ACTIVE_LOW) val |= LVT_POLARITY_ACTIVE_LOW; if ((g_nmi_madt_flags & ACPI_MADT_TRIGGERING_MASK) == ACPI_MADT_TRIGGERING_LEVEL) val |= LVT_TRIGGER_LEVEL; return val; } return LVT_DELIVERY_EXTINT; } /* * Configure LAPIC for legacy BIOS operation in x2APIC mode (MSR access). * Sets up LINT0/LINT1 per MADT-reported NMI routing (default: LINT1=NMI). * * Note: The LAPIC ignores trigger mode for ExtINT and NMI delivery modes, * always using edge-triggered internally. */ static void x2apic_configure_for_legacy(void) { uint64_t val; uint32_t max_lvt = ((uint32_t)rdmsr(X2APIC_MSR_VERSION) >> 16) & 0xFF; /* Clear task priority to allow all interrupts */ wrmsr(X2APIC_MSR_TPR, 0); /* Mask stale LVT entries to prevent unexpected interrupts. * Only mask entries with Fixed, Lowest Priority, NMI, or ExtINT delivery * mode. Leave SMI, INIT, and reserved delivery modes untouched as firmware * may rely on them (e.g. thermal management via SMI). */ uint64_t lvt; lvt = rdmsr(X2APIC_MSR_LVT_TIMER); if (lvt_should_mask(lvt)) wrmsr(X2APIC_MSR_LVT_TIMER, lvt | LVT_MASK); lvt = rdmsr(X2APIC_MSR_LVT_ERROR); if (lvt_should_mask(lvt)) wrmsr(X2APIC_MSR_LVT_ERROR, lvt | LVT_MASK); if (max_lvt >= 4) { lvt = rdmsr(X2APIC_MSR_LVT_PMC); if (lvt_should_mask(lvt)) wrmsr(X2APIC_MSR_LVT_PMC, lvt | LVT_MASK); } if (max_lvt >= 5) { lvt = rdmsr(X2APIC_MSR_LVT_THERMAL); if (lvt_should_mask(lvt)) wrmsr(X2APIC_MSR_LVT_THERMAL, lvt | LVT_MASK); } if (max_lvt >= 6) { lvt = rdmsr(X2APIC_MSR_LVT_CMCI); if (lvt_should_mask(lvt)) wrmsr(X2APIC_MSR_LVT_CMCI, lvt | LVT_MASK); } /* Configure LINT0 / LINT1: one gets NMI (per MADT), the other ExtINT. */ val = rdmsr(X2APIC_MSR_LVT_LINT0); printf(" x2APIC LINT0 before: 0x%08lx\n", (uint32_t)val); val &= ~(LVT_VECTOR_MASK | LVT_DELIVERY_MODE_MASK | LVT_TRIGGER_LEVEL | LVT_POLARITY_ACTIVE_LOW | LVT_MASK); val |= lint_lvt_value(0); wrmsr(X2APIC_MSR_LVT_LINT0, val); printf(" x2APIC LINT0 after: 0x%08lx\n", (uint32_t)rdmsr(X2APIC_MSR_LVT_LINT0)); val = rdmsr(X2APIC_MSR_LVT_LINT1); printf(" x2APIC LINT1 before: 0x%08lx\n", (uint32_t)val); val &= ~(LVT_VECTOR_MASK | LVT_DELIVERY_MODE_MASK | LVT_TRIGGER_LEVEL | LVT_POLARITY_ACTIVE_LOW | LVT_MASK); val |= lint_lvt_value(1); wrmsr(X2APIC_MSR_LVT_LINT1, val); printf(" x2APIC LINT1 after: 0x%08lx\n", (uint32_t)rdmsr(X2APIC_MSR_LVT_LINT1)); /* Configure Spurious Interrupt Vector Register: * - APIC software enable (bit 8) - required for LAPIC to work * - Spurious vector = 0x0F (matches legacy 8259 PIC IRQ7 spurious interrupt) */ val = rdmsr(X2APIC_MSR_SIVR); printf(" x2APIC SIVR before: 0x%08lx\n", (uint32_t)val); val &= ~SIVR_VECTOR_MASK; val |= SIVR_APIC_ENABLE | 0x0F; wrmsr(X2APIC_MSR_SIVR, val); printf(" x2APIC SIVR after: 0x%08lx\n", (uint32_t)rdmsr(X2APIC_MSR_SIVR)); } /* * Configure LAPIC for legacy BIOS operation in xAPIC mode (MMIO access). * Sets up LINT0 for ExtINT, LINT1 for NMI per Intel SDM Appendix D. * * Note: The LAPIC ignores trigger mode for ExtINT and NMI delivery modes, * always using edge-triggered internally. We set edge-triggered explicitly * to match Intel's documented example (0x0700 for ExtINT, 0x0400 for NMI). */ static void xapic_configure_for_legacy(uintptr_t apic_base) { volatile uint32_t *lint0_reg = (volatile uint32_t *)(apic_base + XAPIC_LVT_LINT0_OFFSET); volatile uint32_t *lint1_reg = (volatile uint32_t *)(apic_base + XAPIC_LVT_LINT1_OFFSET); volatile uint32_t *sivr_reg = (volatile uint32_t *)(apic_base + XAPIC_SIVR_OFFSET); uint32_t val; uint32_t max_lvt = (*(volatile uint32_t *)(apic_base + XAPIC_VERSION_OFFSET) >> 16) & 0xFF; /* Clear task priority to allow all interrupts */ *(volatile uint32_t *)(apic_base + XAPIC_TPR_OFFSET) = 0; /* Mask stale LVT entries to prevent unexpected interrupts. * Only mask entries with Fixed, Lowest Priority, NMI, or ExtINT delivery * mode. Leave SMI, INIT, and reserved delivery modes untouched as firmware * may rely on them (e.g. thermal management via SMI). */ uint32_t lvt; lvt = *(volatile uint32_t *)(apic_base + XAPIC_LVT_TIMER_OFFSET); if (lvt_should_mask(lvt)) *(volatile uint32_t *)(apic_base + XAPIC_LVT_TIMER_OFFSET) = lvt | LVT_MASK; lvt = *(volatile uint32_t *)(apic_base + XAPIC_LVT_ERROR_OFFSET); if (lvt_should_mask(lvt)) *(volatile uint32_t *)(apic_base + XAPIC_LVT_ERROR_OFFSET) = lvt | LVT_MASK; if (max_lvt >= 4) { lvt = *(volatile uint32_t *)(apic_base + XAPIC_LVT_PMC_OFFSET); if (lvt_should_mask(lvt)) *(volatile uint32_t *)(apic_base + XAPIC_LVT_PMC_OFFSET) = lvt | LVT_MASK; } if (max_lvt >= 5) { lvt = *(volatile uint32_t *)(apic_base + XAPIC_LVT_THERMAL_OFFSET); if (lvt_should_mask(lvt)) *(volatile uint32_t *)(apic_base + XAPIC_LVT_THERMAL_OFFSET) = lvt | LVT_MASK; } if (max_lvt >= 6) { lvt = *(volatile uint32_t *)(apic_base + XAPIC_LVT_CMCI_OFFSET); if (lvt_should_mask(lvt)) *(volatile uint32_t *)(apic_base + XAPIC_LVT_CMCI_OFFSET) = lvt | LVT_MASK; } /* Configure LINT0 / LINT1: one gets NMI (per MADT), the other ExtINT. */ val = *lint0_reg; printf(" xAPIC LINT0 before: 0x%08x\n", val); val &= ~(LVT_VECTOR_MASK | LVT_DELIVERY_MODE_MASK | LVT_TRIGGER_LEVEL | LVT_POLARITY_ACTIVE_LOW | LVT_MASK); val |= lint_lvt_value(0); *lint0_reg = val; printf(" xAPIC LINT0 after: 0x%08x\n", *lint0_reg); val = *lint1_reg; printf(" xAPIC LINT1 before: 0x%08x\n", val); val &= ~(LVT_VECTOR_MASK | LVT_DELIVERY_MODE_MASK | LVT_TRIGGER_LEVEL | LVT_POLARITY_ACTIVE_LOW | LVT_MASK); val |= lint_lvt_value(1); *lint1_reg = val; printf(" xAPIC LINT1 after: 0x%08x\n", *lint1_reg); /* Configure Spurious Interrupt Vector Register: * - APIC software enable (bit 8) - required for LAPIC to work * - Spurious vector = 0x0F (matches legacy 8259 PIC IRQ7 spurious interrupt) */ val = *sivr_reg; printf(" xAPIC SIVR before: 0x%08x\n", val); val &= ~SIVR_VECTOR_MASK; val |= SIVR_APIC_ENABLE | 0x0F; *sivr_reg = val; printf(" xAPIC SIVR after: 0x%08x\n", *sivr_reg); } /* * Prepare APIC for legacy BIOS operation. * * This function handles the APIC configuration needed for legacy software * that expects PIC interrupts (especially IRQ0 timer) to work correctly. * * Strategy: Keep LAPIC enabled in xAPIC mode with LINT0 configured for * ExtINT passthrough. This matches QEMU's default behavior and is the * standard configuration for legacy BIOS systems. * * - If in x2APIC mode (not locked): transition to xAPIC, configure ExtINT * - If in x2APIC mode (locked): configure ExtINT via MSR (cannot leave x2APIC) * - If already in xAPIC mode: configure ExtINT via MMIO */ void apic_prepare_for_legacy(void) { uint64_t apic_base_msr; uintptr_t apic_base_addr; bool lapic_enabled, x2apic_enabled; printf("Configuring APIC for legacy BIOS compatibility...\n"); load_nmi_madt_info(); printf(" NMI on LINT%u (MADT flags 0x%04x)\n", g_nmi_lint, g_nmi_madt_flags); /* Read current APIC state */ apic_base_msr = rdmsr(MSR_IA32_APIC_BASE); apic_base_addr = apic_base_msr & APIC_BASE_ADDR_MASK; lapic_enabled = !!(apic_base_msr & APIC_BASE_EN); x2apic_enabled = !!(apic_base_msr & APIC_BASE_EXTD); printf(" IA32_APIC_BASE: 0x%016lx (addr=0x%lx, EN=%d, x2APIC=%d, BSP=%d)\n", apic_base_msr, apic_base_addr, lapic_enabled, x2apic_enabled, !!(apic_base_msr & APIC_BASE_BSP)); if (!lapic_enabled) { printf(" LAPIC disabled, enabling in xAPIC mode\n"); apic_base_msr |= APIC_BASE_EN; apic_base_msr &= ~APIC_BASE_EXTD; wrmsr(MSR_IA32_APIC_BASE, apic_base_msr); apic_base_addr = apic_base_msr & APIC_BASE_ADDR_MASK; xapic_configure_for_legacy(apic_base_addr); printf(" APIC configuration complete\n"); return; } if (x2apic_enabled) { /* Check if x2APIC mode is locked */ bool locked = x2apic_is_locked(); printf(" x2APIC lock status: %s\n", locked ? "LOCKED" : "not locked"); if (!locked) { /* * Transition from x2APIC to xAPIC mode. * Cannot go directly x2APIC -> xAPIC (causes #GP). * Must disable first, then re-enable in xAPIC mode. */ printf(" Transitioning x2APIC -> xAPIC mode\n"); /* Step 1: Disable LAPIC (clear both EN and EXTD) */ apic_base_msr &= ~(APIC_BASE_EN | APIC_BASE_EXTD); wrmsr(MSR_IA32_APIC_BASE, apic_base_msr); /* Step 2: Re-enable in xAPIC mode (set EN, keep EXTD clear) */ apic_base_msr |= APIC_BASE_EN; wrmsr(MSR_IA32_APIC_BASE, apic_base_msr); /* Verify transition */ apic_base_msr = rdmsr(MSR_IA32_APIC_BASE); printf(" IA32_APIC_BASE after: 0x%016lx (EN=%d, x2APIC=%d)\n", apic_base_msr, !!(apic_base_msr & APIC_BASE_EN), !!(apic_base_msr & APIC_BASE_EXTD)); /* Now configure LAPIC via MMIO */ xapic_configure_for_legacy(apic_base_addr); } else { /* * x2APIC is locked. Cannot leave x2APIC mode without #GP. * Configure LAPIC for legacy operation via MSR. */ printf(" x2APIC locked, configuring for legacy via MSR\n"); x2apic_configure_for_legacy(); } } else { /* * Already in xAPIC mode. Configure LAPIC via MMIO. * This matches QEMU's default LAPIC configuration. */ printf(" Configuring xAPIC for legacy operation\n"); xapic_configure_for_legacy(apic_base_addr); } printf(" APIC configuration complete\n"); } ================================================ FILE: src/apic.h ================================================ /* * APIC handling for legacy BIOS compatibility */ #ifndef _APIC_H #define _APIC_H /* * Prepare APIC for legacy BIOS operation. * * Disables LAPIC or configures it for ExtINT passthrough so that * legacy 8259 PIC interrupts (especially IRQ0 timer) can reach the CPU. * * Must be called after ExitBootServices but before CSM initialization. */ void apic_prepare_for_legacy(void); #endif /* _APIC_H */ ================================================ FILE: src/arch/ia32/Thunk16.asm ================================================ ;------------------------------------------------------------------------------ ; ; Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: ; ; Thunk.asm ; ; Abstract: ; ; Real mode thunk ; ;------------------------------------------------------------------------------ %define THUNK_ATTRIBUTE_BIG_REAL_MODE 0x00000001 %define THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 0x00000002 %define THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL 0x00000004 %define ASM_PFX(name) name global ASM_PFX(m16Size) global ASM_PFX(mThunk16Attr) global ASM_PFX(m16Gdt) global ASM_PFX(m16GdtrBase) global ASM_PFX(mTransition) global ASM_PFX(m16Start) struc IA32_REGS ._EDI: resd 1 ._ESI: resd 1 ._EBP: resd 1 ._ESP: resd 1 ._EBX: resd 1 ._EDX: resd 1 ._ECX: resd 1 ._EAX: resd 1 ._DS: resw 1 ._ES: resw 1 ._FS: resw 1 ._GS: resw 1 ._EFLAGS: resd 1 ._EIP: resd 1 ._CS: resw 1 ._SS: resw 1 .size: endstruc ;; .const SECTION .data ; ; These are global constant to convey information to C code. ; ASM_PFX(m16Size) DW ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start) ASM_PFX(mThunk16Attr) DW _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start) ASM_PFX(m16Gdt) DW _NullSegDesc - ASM_PFX(m16Start) ASM_PFX(m16GdtrBase) DW _16GdtrBase - ASM_PFX(m16Start) ASM_PFX(mTransition) DW _EntryPoint - ASM_PFX(m16Start) SECTION .text ASM_PFX(m16Start): SavedGdt: dw 0 dd 0 ;------------------------------------------------------------------------------ ; _BackFromUserCode() takes control in real mode after 'retf' has been executed ; by user code. It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _BackFromUserCode: ; ; The order of saved registers on the stack matches the order they appears ; in IA32_REGS structure. This facilitates wrapper function to extract them ; into that structure. ; BITS 16 push ss push cs ; ; Note: We can't use o32 on the next instruction because of a bug ; in NASM 2.09.04 through 2.10rc1. ; call dword .Base ; push eip .Base: pushfd cli ; disable interrupts push gs push fs push es push ds pushad mov edx, strict dword 0 .ThunkAttrEnd: test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 jz .1 mov ax, 2401h int 15h cli ; disable interrupts jnc .2 .1: test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL jz .2 in al, 92h or al, 2 out 92h, al ; deactivate A20M# .2: xor eax, eax mov ax, ss lea ebp, [esp + IA32_REGS.size] mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp mov bx, [bp - IA32_REGS.size + IA32_REGS._EIP] shl eax, 4 ; shl eax, 4 add ebp, eax ; add ebp, eax mov eax, strict dword 0 .SavedCr4End: mov cr4, eax o32 lgdt [cs:bx + (SavedGdt - .Base)] mov eax, strict dword 0 .SavedCr3End: mov cr3, eax ; restore page tables before enabling paging mov eax, strict dword 0 .SavedCr0End: mov cr0, eax mov ax, strict word 0 .SavedSsEnd: mov ss, eax mov esp, strict dword 0 .SavedEspEnd: o32 retf ; return to protected mode _EntryPoint: DD _ToUserCode - ASM_PFX(m16Start) DW 8h _16Idtr: DW (1 << 10) - 1 DD 0 _16Gdtr_zero: DW 0 DD 0 _16Gdtr: DW GdtEnd - _NullSegDesc - 1 _16GdtrBase: DD 0 ;------------------------------------------------------------------------------ ; _ToUserCode() takes control in real mode before passing control to user code. ; It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _ToUserCode: BITS 16 mov dx, ss mov ss, cx ; set new segment selectors mov ds, cx mov es, cx mov fs, cx mov gs, cx and byte [edi + 5], 0xFD ; clear TSS busy bit for next ltr mov cx, TSS_SEL ltr cx mov cr0, eax ; real mode starts at next instruction ; which (per SDM) *must* be a far JMP. jmp 0:strict word 0 .RealAddrEnd: mov cr4, ebp xor eax, eax mov cr3, eax ; clear stale page table pointer mov ss, si ; set up 16-bit stack segment xchg esp, ebx ; set up 16-bit stack pointer mov bp, [esp + IA32_REGS.size] mov [cs:bp + (_BackFromUserCode.SavedSsEnd - 2 - _BackFromUserCode)], dx mov [cs:bp + (_BackFromUserCode.SavedEspEnd - 4 - _BackFromUserCode)], ebx lidt [cs:bp + (_16Idtr - _BackFromUserCode)] lgdt [cs:bp + (_16Gdtr_zero - _BackFromUserCode)] popad pop ds pop es pop fs pop gs popfd o32 retf ; transfer control to user code ALIGN 16 _NullSegDesc DQ 0 _16CsDesc: DW -1 DW 0 DB 0 DB 9bh DB 8fh ; 16-bit segment, 4GB limit DB 0 _16DsDesc: DW -1 DW 0 DB 0 DB 93h DB 8fh ; 16-bit segment, 4GB limit DB 0 _TssSeg: DW 0FFFFh ; Limit (match BIOS default) DW 0 ; Base 15:0 DB 0 ; Base 23:16 DB 89h ; P=1, DPL=0, Type=9 (available TSS) DB 0 ; G=0, Limit 19:16=0 DB 0 ; Base 31:24 TSS_SEL equ _TssSeg - _NullSegDesc GdtEnd: ;------------------------------------------------------------------------------ ; IA32_REGISTER_SET * ; EFIAPI ; InternalAsmThunk16 ( ; IN IA32_REGISTER_SET *RegisterSet, ; IN OUT VOID *Transition ; ); ;------------------------------------------------------------------------------ global ASM_PFX(InternalAsmThunk16) ASM_PFX(InternalAsmThunk16): BITS 32 push ebp push ebx push esi push edi push ds push es push fs push gs mov esi, [esp + 36] ; esi <- RegSet, the 1st parameter movzx edx, word [esi + IA32_REGS._SS] mov edi, [esi + IA32_REGS._ESP] add edi, - (IA32_REGS.size + 4) ; reserve stack space mov ebx, edi ; ebx <- stack offset imul eax, edx, 16 ; eax <- edx * 16 push IA32_REGS.size / 4 add edi, eax ; edi <- linear address of 16-bit stack pop ecx rep movsd ; copy RegSet mov eax, [esp + 40] ; eax <- address of transition code mov esi, edx ; esi <- 16-bit stack segment lea edx, [eax + (_BackFromUserCode.SavedCr0End - ASM_PFX(m16Start))] mov ecx, eax and ecx, 0fh shl eax, 12 lea ecx, [ecx + (_BackFromUserCode - ASM_PFX(m16Start))] mov ax, cx stosd ; [edi] <- return address of user code add eax, _ToUserCode.RealAddrEnd - _BackFromUserCode mov [edx + (_ToUserCode.RealAddrEnd - 4 - _BackFromUserCode.SavedCr0End)], eax sgdt [edx + (SavedGdt - _BackFromUserCode.SavedCr0End)] sidt [esp + 36] ; save IDT stack in argument space mov eax, cr0 mov [edx - 4], eax ; save CR0 in _BackFromUserCode.SavedCr0End - 4 mov eax, 00000010h ; clear all bits except ET mov ebp, cr4 mov [edx + (_BackFromUserCode.SavedCr4End - 4 - _BackFromUserCode.SavedCr0End)], ebp xor ebp, ebp ; zero out CR4 push eax ; save CR0 value (0x10) mov eax, cr3 mov [edx + (_BackFromUserCode.SavedCr3End - 4 - _BackFromUserCode.SavedCr0End)], eax pop eax ; restore CR0 value lea edi, [edx + (_TssSeg - _BackFromUserCode.SavedCr0End)] push 10h pop ecx ; ecx <- selector for data segments lgdt [edx + (_16Gdtr - _BackFromUserCode.SavedCr0End)] pushfd ; Save df/if indeed call dword far [edx + (_EntryPoint - _BackFromUserCode.SavedCr0End)] popfd lidt [esp + 36] ; restore protected mode IDTR lea eax, [ebp - IA32_REGS.size] ; eax <- the address of IA32_REGS pop gs pop fs pop es pop ds pop edi pop esi pop ebx pop ebp ret ================================================ FILE: src/arch/x86_64/Thunk16.asm ================================================ ;------------------------------------------------------------------------------ ; ; Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: ; ; Thunk.asm ; ; Abstract: ; ; Real mode thunk ; ;------------------------------------------------------------------------------ %define THUNK_ATTRIBUTE_BIG_REAL_MODE 0x00000001 %define THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 0x00000002 %define THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL 0x00000004 %define ASM_PFX(name) name global ASM_PFX(m16Size) global ASM_PFX(mThunk16Attr) global ASM_PFX(m16Gdt) global ASM_PFX(m16GdtrBase) global ASM_PFX(mTransition) global ASM_PFX(m16Start) struc IA32_REGS ._EDI: resd 1 ._ESI: resd 1 ._EBP: resd 1 ._ESP: resd 1 ._EBX: resd 1 ._EDX: resd 1 ._ECX: resd 1 ._EAX: resd 1 ._DS: resw 1 ._ES: resw 1 ._FS: resw 1 ._GS: resw 1 ._EFLAGS: resq 1 ._EIP: resd 1 ._CS: resw 1 ._SS: resw 1 .size: endstruc SECTION .data ; ; These are global constant to convey information to C code. ; ASM_PFX(m16Size) DW ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start) ASM_PFX(mThunk16Attr) DW _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start) ASM_PFX(m16Gdt) DW _NullSeg - ASM_PFX(m16Start) ASM_PFX(m16GdtrBase) DW _16GdtrBase - ASM_PFX(m16Start) ASM_PFX(mTransition) DW _EntryPoint - ASM_PFX(m16Start) SECTION .text ASM_PFX(m16Start): SavedGdt: dw 0 dq 0 ;------------------------------------------------------------------------------ ; _BackFromUserCode() takes control in real mode after 'retf' has been executed ; by user code. It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _BackFromUserCode: ; ; The order of saved registers on the stack matches the order they appears ; in IA32_REGS structure. This facilitates wrapper function to extract them ; into that structure. ; BITS 16 push ss push cs ; ; Note: We can't use o32 on the next instruction because of a bug ; in NASM 2.09.04 through 2.10rc1. ; call dword .Base ; push eip .Base: push dword 0 ; reserved high order 32 bits of EFlags pushfd cli ; disable interrupts push gs push fs push es push ds pushad mov edx, strict dword 0 .ThunkAttrEnd: test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 jz .1 mov ax, 2401h int 15h cli ; disable interrupts jnc .2 .1: test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL jz .2 in al, 92h or al, 2 out 92h, al ; deactivate A20M# .2: xor eax, eax mov ax, ss lea ebp, [esp + IA32_REGS.size] mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp mov ebx, [bp - IA32_REGS.size + IA32_REGS._EIP] shl eax, 4 ; shl eax, 4 add ebp, eax ; add ebp, eax mov eax, cs shl eax, 4 lea eax, [eax + ebx + (.X64JmpEnd - .Base)] mov [cs:bx + (.X64JmpEnd - 6 - .Base)], eax mov eax, strict dword 0 .SavedCr4End: mov cr4, eax o32 lgdt [cs:bx + (SavedGdt - .Base)] mov ecx, 0c0000080h mov eax, strict dword 0 .SavedEFERLowEnd: mov edx, strict dword 0 .SavedEFERHighEnd: wrmsr mov eax, strict dword 0 .SavedCr3End: mov cr3, eax ; restore page tables before enabling paging mov eax, strict dword 0 .SavedCr0End: mov cr0, eax jmp 0:strict dword 0 .X64JmpEnd: BITS 64 nop mov rsp, strict qword 0 .SavedSpEnd: nop ret _EntryPoint: DD _ToUserCode - ASM_PFX(m16Start) DW CODE16 _16Gdtr: DW GDT_SIZE - 1 _16GdtrBase: DQ 0 _16Idtr: DW (1 << 10) - 1 DD 0 _16Gdtr_zero: DW 0 DD 0 ;------------------------------------------------------------------------------ ; _ToUserCode() takes control in real mode before passing control to user code. ; It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _ToUserCode: BITS 16 mov ss, dx ; set new segment selectors mov ds, dx mov es, dx mov fs, dx mov gs, dx and byte [edi + 5], 0xFD ; clear TSS busy bit for next ltr mov cx, TSS_SEL ltr cx mov ecx, 0c0000080h mov cr0, eax ; real mode starts at next instruction xor eax, eax mov cr3, eax ; clear stale page table pointer xor edx, edx wrmsr mov cr4, ebp mov ss, si ; set up 16-bit stack segment mov esp, ebx ; set up 16-bit stack pointer call dword .Base ; push eip .Base: pop ebp ; ebp <- address of .Base push word [dword esp + IA32_REGS.size + 2] lea ax, [bp + (.RealMode - .Base)] push ax retf ; execution begins at next instruction .RealMode: o32 lidt [cs:bp + (_16Idtr - .Base)] o32 lgdt [cs:bp + (_16Gdtr_zero - .Base)] popad pop ds pop es pop fs pop gs popfd lea esp, [esp + 4] ; skip high order 32 bits of EFlags o32 retf ; transfer control to user code ALIGN 8 CODE16 equ _16Code - $ DATA16 equ _16Data - $ DATA32 equ _32Data - $ _NullSeg DQ 0 _16Code: DW -1 DW 0 DB 0 DB 9bh DB 8fh ; 16-bit segment, 4GB limit DB 0 _16Data: DW -1 DW 0 DB 0 DB 93h DB 8fh ; 16-bit segment, 4GB limit DB 0 _32Data: DW -1 DW 0 DB 0 DB 93h DB 0cfh ; 16-bit segment, 4GB limit DB 0 _TssSeg: DW 0FFFFh ; Limit (match BIOS default) DW 0 ; Base 15:0 DB 0 ; Base 23:16 DB 89h ; P=1, DPL=0, Type=9 (available TSS) DB 0 ; G=0, Limit 19:16=0 DB 0 ; Base 31:24 DD 0 ; Base 63:32 (64-bit TSS descriptor DD 0 ; requires 16 bytes in long mode) TSS_SEL equ _TssSeg - _NullSeg GDT_SIZE equ $ - _NullSeg ;------------------------------------------------------------------------------ ; IA32_REGISTER_SET * ; EFIAPI ; InternalAsmThunk16 ( ; IN IA32_REGISTER_SET *RegisterSet, ; IN OUT VOID *Transition ; ); ;------------------------------------------------------------------------------ global ASM_PFX(InternalAsmThunk16) ASM_PFX(InternalAsmThunk16): BITS 64 push rbp push rbx push rsi push rdi mov ebx, ds push rbx ; Save ds segment register on the stack mov ebx, es push rbx ; Save es segment register on the stack mov ebx, ss push rbx ; Save ss segment register on the stack push fs push gs mov rsi, rcx movzx r8d, word [rsi + IA32_REGS._SS] mov edi, [rsi + IA32_REGS._ESP] lea rdi, [edi - (IA32_REGS.size + 4)] imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16 mov ebx, edi ; ebx <- stack for 16-bit code push IA32_REGS.size / 4 add edi, eax ; edi <- linear address of 16-bit stack pop rcx rep movsd ; copy RegSet lea ecx, [rdx + (_BackFromUserCode.SavedCr4End - ASM_PFX(m16Start))] mov eax, edx ; eax <- transition code address and edx, 0fh shl eax, 12 ; segment address in high order 16 bits lea ax, [rdx + (_BackFromUserCode - ASM_PFX(m16Start))] ; offset address stosd ; [edi] <- return address of user code sgdt [rsp + 60h] ; save GDT stack in argument space movzx r10, word [rsp + 60h] ; r10 <- GDT limit lea r11, [rcx + (ASM_PFX(InternalAsmThunk16) - _BackFromUserCode.SavedCr4End) + 0xf] and r11, ~0xf ; r11 <- 16-byte aligned shadowed GDT table in real mode buffer mov [rcx + (SavedGdt - _BackFromUserCode.SavedCr4End)], r10w ; save the limit of shadowed GDT table mov [rcx + (SavedGdt - _BackFromUserCode.SavedCr4End) + 2], r11 ; save the base address of shadowed GDT table mov rsi, [rsp + 62h] ; rsi <- the original GDT base address xchg rcx, r10 ; save rcx to r10 and initialize rcx to be the limit of GDT table inc rcx ; rcx <- the size of memory to copy xchg rdi, r11 ; save rdi to r11 and initialize rdi to the base address of shadowed GDT table rep movsb ; perform memory copy to shadow GDT table mov rcx, r10 ; restore the orignal rcx before memory copy mov rdi, r11 ; restore the original rdi before memory copy sidt [rsp + 50h] ; save IDT stack in argument space mov rax, cr0 mov [rcx + (_BackFromUserCode.SavedCr0End - 4 - _BackFromUserCode.SavedCr4End)], eax mov eax, 00000010h ; clear all bits except ET push rax push rcx push rdx mov ecx, 0c0000080h rdmsr btr eax, 10 ; Reset LMA flag to avoid crash on AMD Zen CPUs mov r10d, eax mov r11d, edx pop rdx pop rcx pop rax mov [rcx + (_BackFromUserCode.SavedEFERLowEnd - 4 - _BackFromUserCode.SavedCr4End)], r10d mov [rcx + (_BackFromUserCode.SavedEFERHighEnd - 4 - _BackFromUserCode.SavedCr4End)], r11d mov rbp, cr4 mov [rcx - 4], ebp ; save CR4 in _BackFromUserCode.SavedCr4End - 4 xor ebp, ebp ; zero out CR4 push rax ; save CR0 value (0x10) mov rax, cr3 mov [rcx + (_BackFromUserCode.SavedCr3End - 4 - _BackFromUserCode.SavedCr4End)], eax pop rax ; restore CR0 value lea edi, [rcx + (_TssSeg - _BackFromUserCode.SavedCr4End)] mov esi, r8d ; esi <- 16-bit stack segment push DATA32 pop rdx ; rdx <- 32-bit data segment selector lgdt [rcx + (_16Gdtr - _BackFromUserCode.SavedCr4End)] mov ss, edx pushfq lea edx, [rdx + DATA16 - DATA32] lea r8, [REL .RetFromRealMode] push r8 mov r8d, cs mov [rcx + (_BackFromUserCode.X64JmpEnd - 2 - _BackFromUserCode.SavedCr4End)], r8w mov [rcx + (_BackFromUserCode.SavedSpEnd - 8 - _BackFromUserCode.SavedCr4End)], rsp jmp dword far [rcx + (_EntryPoint - _BackFromUserCode.SavedCr4End)] .RetFromRealMode: popfq lgdt [rsp + 60h] ; restore protected mode GDTR lidt [rsp + 50h] ; restore protected mode IDTR lea eax, [rbp - IA32_REGS.size] pop gs pop fs pop rbx mov ss, ebx pop rbx mov es, ebx pop rbx mov ds, ebx pop rdi pop rsi pop rbx pop rbp ret ================================================ FILE: src/bios_proxy.c ================================================ /* * BIOS Proxy Helper Core Support * * Starts a dedicated CPU core to handle BIOS calls when the main core * is running in V86 mode (under EMM386). The helper core stays in * protected mode and can execute call32 normally. */ #include #include #include #include #include #include #include #include /* Must match the signature in SeaBIOS stacks.c so it can find the mailbox. */ #define BIOS_PROXY_SIGNATURE 0x79787250504D5343ULL /* "CSMPPrxy" */ /* Authoritative size of the helper core's stack. SeaBIOS does not allocate * or switch stacks for the helper - it runs every dispatched func_ptr (reset * path, V86 BIOS handlers via call32_proxy, etc.) on this exact buffer - so * this has to be deep enough for the worst-case proxied call chain. */ #define HELPER_STACK_SIZE 32768 struct bios_proxy_mailbox { uint64_t signature; volatile uint32_t request_pending; uint32_t func_ptr; uint32_t arg_eax; uint32_t arg_edx; uint32_t arg_ecx; uint32_t result; uint32_t helper_core_id; /* UEFI reset callback fields (populated by CSMWrap) */ uint32_t reset_cr3; uint32_t reset_fn_lo; uint32_t reset_fn_hi; }; /* Separately allocated stack for helper core */ static uint8_t *helper_stack_buffer = NULL; /* Local APIC register offsets (xAPIC MMIO mode) */ #define LAPIC_ID 0x020 #define LAPIC_ICR_LOW 0x300 #define LAPIC_ICR_HIGH 0x310 /* APIC MSRs */ #define IA32_APIC_BASE_MSR 0x1B #define APIC_BASE_ADDR_MASK 0xFFFFFFFFFFFFF000ULL /* Bits 12-51 contain base address */ #define APIC_BASE_EXTD (1 << 10) /* x2APIC mode enabled */ /* x2APIC MSRs */ #define X2APIC_ICR 0x830 #define X2APIC_ID 0x802 /* Get the LAPIC base address from IA32_APIC_BASE MSR */ static uintptr_t get_lapic_base(void) { return (uintptr_t)(rdmsr(IA32_APIC_BASE_MSR) & APIC_BASE_ADDR_MASK); } /* AP trampoline will be placed here */ #define AP_TRAMPOLINE_ADDR 0x7000 #define AP_TRAMPOLINE_VECTOR 0x07 /* SIPI vector = addr / 0x1000 */ static struct bios_proxy_mailbox *mailbox = NULL; static uintptr_t mailbox_offset = 0; static int selected_ap_id = -1; static uint64_t reset_cr3_value = 0; /* * Build minimal identity-mapping page tables for the 64-bit reset path. * Maps the first 4GB using 2MB pages (works on all x86-64 CPUs). * * Layout (6 pages = 24KB): * Page 0: PML4 (1 entry → PDPT) * Page 1: PDPT (4 entries → PD[0..3]) * Pages 2-5: PD[0..3] (512 × 2MB entries each = 1GB per PD) */ #define PT_P (1ULL << 0) /* Present */ #define PT_RW (1ULL << 1) /* Read/Write */ #define PT_PS (1ULL << 7) /* Page Size (2MB) */ #define RESET_PT_PAGES 6 static int build_reset_page_tables(void) { EFI_PHYSICAL_ADDRESS pt_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiRuntimeServicesData, RESET_PT_PAGES, &pt_addr ); if (EFI_ERROR(status)) { printf("Failed to allocate reset page tables\n"); return -1; } memset((void *)(uintptr_t)pt_addr, 0, RESET_PT_PAGES * 4096); uint64_t *pml4 = (uint64_t *)(uintptr_t)pt_addr; uint64_t *pdpt = (uint64_t *)(uintptr_t)(pt_addr + 0x1000); /* PML4[0] → PDPT */ pml4[0] = (pt_addr + 0x1000) | PT_P | PT_RW; /* PDPT[0..3] → PD[0..3], each covering 1GB */ for (int i = 0; i < 4; i++) { uint64_t pd_phys = pt_addr + 0x2000 + (uint64_t)i * 0x1000; pdpt[i] = pd_phys | PT_P | PT_RW; /* Fill PD with 512 × 2MB identity-mapped pages */ uint64_t *pd = (uint64_t *)(uintptr_t)pd_phys; for (int j = 0; j < 512; j++) { uint64_t phys = ((uint64_t)i * 512 + j) * 0x200000ULL; pd[j] = phys | PT_P | PT_RW | PT_PS; } } reset_cr3_value = pt_addr; printf("Reset page tables at %p (4GB identity map, 2MB pages)\n", (void *)(uintptr_t)pt_addr); return 0; } /* Detect if running in x2APIC mode */ static int is_x2apic_mode(void) { uint64_t apic_base = rdmsr(IA32_APIC_BASE_MSR); return (apic_base & APIC_BASE_EXTD) != 0; } /* * Find the BIOS proxy mailbox in the CSM binary by scanning for signature. */ static uintptr_t find_proxy_mailbox(void *csm_base, size_t csm_size) { uint64_t *ptr = (uint64_t *)csm_base; uint64_t *end = (uint64_t *)((uint8_t *)csm_base + csm_size - sizeof(struct bios_proxy_mailbox)); while (ptr < end) { if (*ptr == BIOS_PROXY_SIGNATURE) { return (uintptr_t)ptr - (uintptr_t)csm_base; } ptr++; } return 0; } /* Signature before 16-bit helper entry: "PRXY16EP" */ #define HELPER_16_ENTRY_SIGNATURE 0x5045363159585250ULL /* * Find the bios_proxy_helper_16_entry in the CSM binary by scanning for signature. * Returns the linear address of the entry point. */ static uint32_t find_helper_16_entry(void *csm_base, size_t csm_size, uintptr_t final_base) { /* Signature is 8-byte aligned in romlayout.S */ uint64_t *base = (uint64_t *)csm_base; uint64_t *end = (uint64_t *)((uint8_t *)csm_base + csm_size - 16); for (uint64_t *ptr = base; ptr < end; ptr++) { if (*ptr == HELPER_16_ENTRY_SIGNATURE) { uint32_t offset_in_binary = ((uint8_t *)ptr - (uint8_t *)csm_base) + 8; /* Skip signature */ return (uint32_t)final_base + offset_in_binary; } } return 0; } /* Trampoline from assembly file */ extern uint8_t ap_trampoline_start[]; extern uint32_t ap_trampoline_size_value; extern uint32_t ap_trampoline_mailbox_offset; extern uint32_t ap_trampoline_stack_offset; extern uint32_t ap_trampoline_target16_offset; extern uint32_t ap_trampoline_helper_ready_offset; /* * Create AP trampoline code at AP_TRAMPOLINE_ADDR * target16_addr is a linear address which will be converted to segment:offset */ static void create_ap_trampoline(uint32_t target16_addr, uint32_t mailbox_addr, uint32_t stack_top) { uint8_t *tramp = (uint8_t *)AP_TRAMPOLINE_ADDR; uint32_t size = ap_trampoline_size_value; /* Convert linear address to segment:offset for far jump * SeaBIOS is at 0xF0000 and expects CS=0xF000 (uses %cs: prefix for data access) */ uint16_t target_segment = 0xF000; uint16_t target_offset = (uint16_t)(target16_addr - 0xF0000); memcpy(tramp, ap_trampoline_start, size); *(uint32_t *)(tramp + ap_trampoline_mailbox_offset) = mailbox_addr; *(uint32_t *)(tramp + ap_trampoline_stack_offset) = stack_top; /* Far pointer: offset first, then segment (little-endian) */ *(uint16_t *)(tramp + ap_trampoline_target16_offset) = target_offset; *(uint16_t *)(tramp + ap_trampoline_target16_offset + 2) = target_segment; } /* * Wait for ICR delivery to complete (xAPIC mode only) */ static void wait_icr_idle_xapic(uintptr_t lapic_base) { volatile uint32_t *icr_low = (volatile uint32_t *)(lapic_base + LAPIC_ICR_LOW); int count = 0; while (*icr_low & (1 << 12)) { asm volatile ("pause"); if (++count > 1000000) return; } } /* * Send INIT-SIPI sequence (xAPIC MMIO mode) */ static void start_ap_xapic(uint32_t apic_id) { uintptr_t lapic_base = get_lapic_base(); volatile uint32_t *icr_high = (volatile uint32_t *)(lapic_base + LAPIC_ICR_HIGH); volatile uint32_t *icr_low = (volatile uint32_t *)(lapic_base + LAPIC_ICR_LOW); uint32_t dest = (apic_id & 0xFF) << 24; /* xAPIC physical destination is 8-bit */ wait_icr_idle_xapic(lapic_base); *icr_high = dest; *icr_low = 0x4500; /* INIT */ stall(10000); wait_icr_idle_xapic(lapic_base); *icr_high = dest; *icr_low = 0x4600 | AP_TRAMPOLINE_VECTOR; /* SIPI */ stall(200); wait_icr_idle_xapic(lapic_base); *icr_high = dest; *icr_low = 0x4600 | AP_TRAMPOLINE_VECTOR; /* SIPI (retry) */ wait_icr_idle_xapic(lapic_base); } /* * Send INIT-SIPI sequence (x2APIC MSR mode) */ static void start_ap_x2apic(uint32_t apic_id) { wrmsr(X2APIC_ICR, ((uint64_t)apic_id << 32) | 0x4500); /* INIT */ stall(10000); wrmsr(X2APIC_ICR, ((uint64_t)apic_id << 32) | 0x4600 | AP_TRAMPOLINE_VECTOR); /* SIPI */ stall(200); wrmsr(X2APIC_ICR, ((uint64_t)apic_id << 32) | 0x4600 | AP_TRAMPOLINE_VECTOR); /* SIPI (retry) */ } static void start_ap(uint32_t apic_id) { if (is_x2apic_mode()) { start_ap_x2apic(apic_id); } else { start_ap_xapic(apic_id); } } static uint32_t get_bsp_apic_id(void) { if (is_x2apic_mode()) { return (uint32_t)rdmsr(X2APIC_ID); } uintptr_t lapic_base = get_lapic_base(); volatile uint32_t *lapic_id_reg = (volatile uint32_t *)(lapic_base + LAPIC_ID); return (*lapic_id_reg >> 24) & 0xFF; } /* * Walk the MADT and check if the given APIC ID names an enabled AP that * we can deliver INIT-SIPI to (i.e. xAPIC-addressable: id < 0xFF). */ static bool madt_apic_id_is_valid_ap(uint32_t apic_id, uint32_t bsp_id) { if (apic_id == bsp_id || apic_id >= 0xFF) return false; struct uacpi_table madt_table; if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK) { return false; } struct acpi_madt *madt = (struct acpi_madt *)madt_table.virt_addr; uint8_t *entry = (uint8_t *)(madt + 1); uint8_t *end = (uint8_t *)madt + madt->hdr.length; bool ok = false; while (entry < end) { uint8_t type = entry[0]; uint8_t len = entry[1]; if (len < 2) break; if (type == ACPI_MADT_ENTRY_TYPE_LAPIC) { struct acpi_madt_lapic *lapic = (struct acpi_madt_lapic *)entry; if (lapic->id == apic_id && (lapic->flags & ACPI_PIC_ENABLED)) { ok = true; break; } } else if (type == ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC) { struct acpi_madt_x2apic *x2apic = (struct acpi_madt_x2apic *)entry; if (x2apic->id == apic_id && (x2apic->flags & ACPI_PIC_ENABLED)) { ok = true; break; } } entry += len; } uacpi_table_unref(&madt_table); return ok; } /* * Find an available AP to use as the system thread by parsing the MADT. * * If the user has pinned a specific APIC ID via the 'system_thread' config * key, validate and use that. Otherwise, return the highest APIC ID AP so * the system thread is least likely to be the one the OS would use first. */ static int find_available_ap(void) { uint32_t bsp_id = get_bsp_apic_id(); if (gConfig.system_thread_specified) { uint32_t want = gConfig.system_thread_apic_id; if (!madt_apic_id_is_valid_ap(want, bsp_id)) { printf("BIOS proxy: configured system_thread APIC ID %u is not " "a usable AP (must be enabled, not BSP %u, and < 0xFF)\n", want, bsp_id); return -1; } printf("BIOS proxy: using configured system thread (APIC ID %u)\n", want); return (int)want; } struct uacpi_table madt_table; if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK) { return -1; } struct acpi_madt *madt = (struct acpi_madt *)madt_table.virt_addr; uint8_t *entry = (uint8_t *)(madt + 1); uint8_t *end = (uint8_t *)madt + madt->hdr.length; int highest_ap_id = -1; while (entry < end) { uint8_t type = entry[0]; uint8_t len = entry[1]; if (len < 2) break; if (type == ACPI_MADT_ENTRY_TYPE_LAPIC) { struct acpi_madt_lapic *lapic = (struct acpi_madt_lapic *)entry; if ((lapic->flags & 0x3) && lapic->id != bsp_id) { if (lapic->id > highest_ap_id) highest_ap_id = lapic->id; } } else if (type == ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC) { struct acpi_madt_x2apic *x2apic = (struct acpi_madt_x2apic *)entry; /* Only consider APs with xAPIC-addressable IDs (<255) so we can deliver INIT-SIPI; ID 0xFF is broadcast in physical dest mode */ if ((x2apic->flags & 0x3) && x2apic->id != bsp_id && x2apic->id < 0xFF) { if ((int)x2apic->id > highest_ap_id) highest_ap_id = x2apic->id; } } entry += len; } uacpi_table_unref(&madt_table); return highest_ap_id; } /* * Compute ACPI table checksum (sum of all bytes must be 0) */ static uint8_t acpi_checksum(void *data, size_t len) { uint8_t sum = 0; uint8_t *p = (uint8_t *)data; for (size_t i = 0; i < len; i++) { sum += p[i]; } return sum; } static void acpi_fix_checksum(struct acpi_sdt_hdr *hdr) { hdr->checksum = 0; hdr->checksum = -acpi_checksum(hdr, hdr->length); } /* Pointers to allocated patched tables */ static void *patched_madt = NULL; static void *patched_rsdt = NULL; static void *patched_xsdt = NULL; /* * Decide whether a CPU MADT entry should appear in the OS-visible MADT. * * - The system thread (helper core) is always hidden. * - The BSP is always kept (we run on it; the OS must see it). * - Otherwise the user-configured allow/block list decides. */ static bool cpu_visible_to_os(uint32_t apic_id, uint32_t bsp_id, int helper_apic_id) { if (helper_apic_id >= 0 && apic_id == (uint32_t)helper_apic_id) return false; if (apic_id == bsp_id) return true; return config_cpu_in_filter(apic_id); } /* * Create a patched MADT with the helper core entry removed and any CPUs * filtered out by the user's cpu_allowlist / cpu_blocklist also removed. * Returns the new MADT or NULL on failure. */ static struct acpi_madt *create_patched_madt(int helper_apic_id) { struct uacpi_table madt_table; if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK) { return NULL; } struct acpi_madt *orig_madt = (struct acpi_madt *)madt_table.virt_addr; uint32_t orig_len = orig_madt->hdr.length; uint32_t bsp_id = get_bsp_apic_id(); /* First pass: find entries to remove and calculate new size */ uint8_t *entry = (uint8_t *)(orig_madt + 1); uint8_t *end = (uint8_t *)orig_madt + orig_len; uint32_t removed_bytes = 0; uint32_t removed_count = 0; bool found_helper = false; while (entry < end) { uint8_t type = entry[0]; uint8_t len = entry[1]; if (len < 2) break; uint32_t cpu_id; bool is_cpu = false; if (type == ACPI_MADT_ENTRY_TYPE_LAPIC) { cpu_id = ((struct acpi_madt_lapic *)entry)->id; is_cpu = true; } else if (type == ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC) { cpu_id = ((struct acpi_madt_x2apic *)entry)->id; is_cpu = true; } if (is_cpu) { if (helper_apic_id >= 0 && cpu_id == (uint32_t)helper_apic_id) found_helper = true; if (!cpu_visible_to_os(cpu_id, bsp_id, helper_apic_id)) { removed_bytes += len; removed_count++; } } entry += len; } if (helper_apic_id >= 0 && !found_helper) { printf("Warning: helper core APIC ID %d not found in MADT\n", helper_apic_id); uacpi_table_unref(&madt_table); return NULL; } /* Allocate new MADT (must be < 4GB for legacy OS) */ uint32_t new_len = orig_len - removed_bytes; EFI_PHYSICAL_ADDRESS new_madt_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiACPIReclaimMemory, (new_len + 4095) / 4096, &new_madt_addr ); if (EFI_ERROR(status)) { printf("Failed to allocate memory for patched MADT\n"); uacpi_table_unref(&madt_table); return NULL; } struct acpi_madt *new_madt = (struct acpi_madt *)(uintptr_t)new_madt_addr; /* Copy MADT header */ memcpy(new_madt, orig_madt, sizeof(struct acpi_madt)); /* Copy entries, skipping helper core and any filtered-out CPUs */ uint8_t *dst = (uint8_t *)(new_madt + 1); entry = (uint8_t *)(orig_madt + 1); while (entry < end) { uint8_t type = entry[0]; uint8_t len = entry[1]; if (len < 2) break; bool skip = false; if (type == ACPI_MADT_ENTRY_TYPE_LAPIC) { uint32_t id = ((struct acpi_madt_lapic *)entry)->id; if (!cpu_visible_to_os(id, bsp_id, helper_apic_id)) skip = true; } else if (type == ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC) { uint32_t id = ((struct acpi_madt_x2apic *)entry)->id; if (!cpu_visible_to_os(id, bsp_id, helper_apic_id)) skip = true; } if (!skip) { memcpy(dst, entry, len); dst += len; } entry += len; } /* Update header */ new_madt->hdr.length = new_len; acpi_fix_checksum(&new_madt->hdr); uacpi_table_unref(&madt_table); printf("Created patched MADT at %p (removed %u CPU entries, " "system thread APIC ID %d)\n", (void *)new_madt, removed_count, helper_apic_id); return new_madt; } /* * Create patched RSDT with updated MADT pointer. */ static struct acpi_rsdt *create_patched_rsdt(struct acpi_rsdp *rsdp, uintptr_t new_madt_addr) { if (!rsdp->rsdt_addr) { return NULL; } struct acpi_rsdt *orig_rsdt = (struct acpi_rsdt *)(uintptr_t)rsdp->rsdt_addr; uint32_t len = orig_rsdt->hdr.length; size_t num_entries = (len - sizeof(struct acpi_sdt_hdr)) / sizeof(uint32_t); /* Allocate new RSDT */ EFI_PHYSICAL_ADDRESS new_rsdt_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiACPIReclaimMemory, (len + 4095) / 4096, &new_rsdt_addr ); if (EFI_ERROR(status)) { printf("Failed to allocate memory for patched RSDT\n"); return NULL; } struct acpi_rsdt *new_rsdt = (struct acpi_rsdt *)(uintptr_t)new_rsdt_addr; memcpy(new_rsdt, orig_rsdt, len); /* Find and update all MADT entries (some firmware lists it more than once) */ for (size_t i = 0; i < num_entries; i++) { struct acpi_sdt_hdr *hdr = (struct acpi_sdt_hdr *)(uintptr_t)new_rsdt->entries[i]; if (hdr && memcmp(hdr->signature, ACPI_MADT_SIGNATURE, 4) == 0) { new_rsdt->entries[i] = (uint32_t)new_madt_addr; } } acpi_fix_checksum(&new_rsdt->hdr); printf("Created patched RSDT at %p\n", (void *)new_rsdt); return new_rsdt; } /* * Create patched XSDT with updated MADT pointer. */ static struct acpi_xsdt *create_patched_xsdt(struct acpi_rsdp *rsdp, uintptr_t new_madt_addr) { if (rsdp->revision < 2 || !rsdp->xsdt_addr) { return NULL; } struct acpi_xsdt *orig_xsdt = (struct acpi_xsdt *)(uintptr_t)rsdp->xsdt_addr; uint32_t len = orig_xsdt->hdr.length; size_t num_entries = (len - sizeof(struct acpi_sdt_hdr)) / sizeof(uint64_t); /* Allocate new XSDT */ EFI_PHYSICAL_ADDRESS new_xsdt_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiACPIReclaimMemory, (len + 4095) / 4096, &new_xsdt_addr ); if (EFI_ERROR(status)) { printf("Failed to allocate memory for patched XSDT\n"); return NULL; } struct acpi_xsdt *new_xsdt = (struct acpi_xsdt *)(uintptr_t)new_xsdt_addr; memcpy(new_xsdt, orig_xsdt, len); /* Find and update all MADT entries (some firmware lists it more than once) */ for (size_t i = 0; i < num_entries; i++) { struct acpi_sdt_hdr *hdr = (struct acpi_sdt_hdr *)(uintptr_t)new_xsdt->entries[i]; if (hdr && memcmp(hdr->signature, ACPI_MADT_SIGNATURE, 4) == 0) { new_xsdt->entries[i] = (uint64_t)new_madt_addr; } } acpi_fix_checksum(&new_xsdt->hdr); printf("Created patched XSDT at %p\n", (void *)new_xsdt); return new_xsdt; } /* * Patch ACPI tables to hide the helper core from the OS. * Updates the RSDP copy in CSM region to point to patched tables. */ static int patch_acpi_hide_helper(void *rsdp_copy, int helper_apic_id) { extern uintptr_t g_rsdp; /* Original RSDP from acpi.c */ if (!g_rsdp) { printf("No RSDP available for MADT patching\n"); return -1; } struct acpi_rsdp *orig_rsdp = (struct acpi_rsdp *)g_rsdp; struct acpi_rsdp *copy_rsdp = (struct acpi_rsdp *)rsdp_copy; /* Create patched MADT */ struct acpi_madt *new_madt = create_patched_madt(helper_apic_id); if (!new_madt) { return -1; } patched_madt = new_madt; /* Create patched RSDT */ struct acpi_rsdt *new_rsdt = create_patched_rsdt(orig_rsdp, (uintptr_t)new_madt); if (new_rsdt) { patched_rsdt = new_rsdt; copy_rsdp->rsdt_addr = (uint32_t)(uintptr_t)new_rsdt; } /* Create patched XSDT (if ACPI 2.0+) */ struct acpi_xsdt *new_xsdt = create_patched_xsdt(orig_rsdp, (uintptr_t)new_madt); if (new_xsdt) { patched_xsdt = new_xsdt; copy_rsdp->xsdt_addr = (uint64_t)(uintptr_t)new_xsdt; } /* Fix RSDP checksums */ copy_rsdp->checksum = 0; copy_rsdp->checksum = -acpi_checksum(copy_rsdp, 20); /* First 20 bytes for ACPI 1.0 */ if (copy_rsdp->revision >= 2) { copy_rsdp->extended_checksum = 0; copy_rsdp->extended_checksum = -acpi_checksum(copy_rsdp, copy_rsdp->length); } printf("ACPI tables patched to hide helper core (APIC ID %d)\n", helper_apic_id); return 0; } static void *saved_csm_base = NULL; static size_t saved_csm_size = 0; static void *saved_rsdp_copy = NULL; /* * Initialize the BIOS proxy helper core. * Call after CSM binary is loaded but before ExitBootServices. * * Parameters: * csm_base - Pointer to the loaded CSM binary * csm_size - Size of the CSM binary * rsdp_copy - Pointer to the RSDP copy in CSM region (for MADT patching) */ int bios_proxy_init(void *csm_base, size_t csm_size, void *rsdp_copy) { printf("Initializing BIOS proxy helper core...\n"); saved_csm_base = csm_base; saved_csm_size = csm_size; saved_rsdp_copy = rsdp_copy; mailbox_offset = find_proxy_mailbox(csm_base, csm_size); if (!mailbox_offset) { printf("BIOS proxy mailbox not found\n"); return -1; } selected_ap_id = find_available_ap(); if (selected_ap_id < 0) { printf("No AP available for BIOS proxy\n"); return -1; } /* Patch ACPI tables to hide the helper core from the OS */ if (rsdp_copy) { if (patch_acpi_hide_helper(rsdp_copy, selected_ap_id) < 0) { printf("Warning: Failed to patch MADT, OS may see helper core\n"); /* Continue anyway - helper will still work */ } } /* Build identity-mapping page tables for the 64-bit reset path */ if (build_reset_page_tables() < 0) { printf("Warning: UEFI reset callback will not be available\n"); } /* Allocate stack for helper core (must be < 4GB) */ EFI_PHYSICAL_ADDRESS stack_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiRuntimeServicesData, (HELPER_STACK_SIZE + 4095) / 4096, &stack_addr ); if (EFI_ERROR(status)) { printf("Failed to allocate helper stack\n"); return -1; } helper_stack_buffer = (uint8_t *)(uintptr_t)stack_addr; printf("BIOS proxy ready (AP %d)\n", selected_ap_id); return 0; } /* * Start the helper core. * Call after ExitBootServices. */ int bios_proxy_start_helper(uintptr_t csm_final_base) { if (!mailbox_offset || !saved_csm_base || selected_ap_id < 0) { return -1; } uint32_t target16_addr = find_helper_16_entry(saved_csm_base, saved_csm_size, csm_final_base); if (!target16_addr) { return -1; } mailbox = (struct bios_proxy_mailbox *)(csm_final_base + mailbox_offset); /* Populate UEFI reset callback fields in the mailbox */ if (reset_cr3_value && gRT && gRT->ResetSystem) { uint64_t fn = (uint64_t)(uintptr_t)gRT->ResetSystem; mailbox->reset_cr3 = (uint32_t)reset_cr3_value; mailbox->reset_fn_lo = (uint32_t)fn; mailbox->reset_fn_hi = (uint32_t)(fn >> 32); printf("UEFI ResetSystem callback at %p (CR3=%p)\n", (void *)(uintptr_t)fn, (void *)(uintptr_t)reset_cr3_value); } else { mailbox->reset_cr3 = 0; mailbox->reset_fn_lo = 0; mailbox->reset_fn_hi = 0; printf("Warning: UEFI ResetSystem callback not available\n"); } if (!helper_stack_buffer) { return -1; } uint32_t stack_top = (uint32_t)(uintptr_t)(helper_stack_buffer + HELPER_STACK_SIZE); create_ap_trampoline(target16_addr, (uint32_t)(uintptr_t)mailbox, stack_top); start_ap(selected_ap_id); /* Wait for helper to signal ready */ volatile uint32_t *helper_ready = (volatile uint32_t *)(uintptr_t)(AP_TRAMPOLINE_ADDR + ap_trampoline_helper_ready_offset); for (int timeout = 0; timeout < 100; timeout++) { asm volatile ("" ::: "memory"); if (*helper_ready) { return 0; } stall(10000); } return -1; } /* * Get the APIC ID of the helper core. * Returns -1 if no helper core has been selected. */ int bios_proxy_get_helper_apic_id(void) { return selected_ap_id; } ================================================ FILE: src/bios_proxy.h ================================================ /* * BIOS Proxy Helper Core Support * * Provides a dedicated CPU core to handle BIOS calls when the main core * is running in V86 mode (under EMM386). */ #ifndef _BIOS_PROXY_H #define _BIOS_PROXY_H #include #include /* * Initialize the BIOS proxy helper core. * Call this after CSM binary is loaded but before Legacy16Boot. * * @param csm_base Base address of the loaded CSM binary * @param csm_size Size of the CSM binary in bytes * @param rsdp_copy Pointer to the RSDP copy in CSM region (for MADT patching) * If NULL, MADT patching is skipped. * @return 0 on success, -1 on failure */ int bios_proxy_init(void *csm_base, size_t csm_size, void *rsdp_copy); /* * Start the helper core. * Call this after ExitBootServices when we have full control of the system, * and after the CSM binary has been copied to its final location. * * @param csm_final_base The address where the CSM binary was copied to * @return 0 on success, -1 on failure */ int bios_proxy_start_helper(uintptr_t csm_final_base); /* * Get the APIC ID of the helper core. * Returns -1 if no helper core has been selected. * Used by mptable generation to exclude the helper from MP tables. */ int bios_proxy_get_helper_apic_id(void); #endif /* _BIOS_PROXY_H */ ================================================ FILE: src/bootdev.c ================================================ #include #include #include #include /* * Boot device detection and BBS table building for CSMWrap * * This module detects which drive CSMWrap was booted from and creates * a BBS table that prioritizes that drive for SeaBIOS boot order. */ /* * Parse device path to extract boot device information */ static bool parse_device_path(EFI_DEVICE_PATH_PROTOCOL *device_path, struct boot_device_info *info) { EFI_DEVICE_PATH_PROTOCOL *node; bool found_pci = false; if (!device_path || !info) { return false; } memset(info, 0, sizeof(*info)); info->device_type = BBS_HARDDISK; /* Default to hard disk */ /* Walk the device path to extract information */ for (node = device_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { uint8_t type = DevicePathType(node); uint8_t subtype = DevicePathSubType(node); switch (type) { case HARDWARE_DEVICE_PATH: if (subtype == HW_PCI_DP) { PCI_DEVICE_PATH *pci = (PCI_DEVICE_PATH *)node; info->bus = 0; /* Will be updated if we find ACPI path first */ info->device = pci->Device; info->function = pci->Function; found_pci = true; } break; case MESSAGING_DEVICE_PATH: switch (subtype) { case MSG_SATA_DP: { SATA_DEVICE_PATH *sata = (SATA_DEVICE_PATH *)node; info->sata_port = sata->HBAPortNumber; info->device_type = BBS_HARDDISK; } break; case MSG_USB_DP: info->is_usb = true; info->device_type = BBS_USB; break; case MSG_ATAPI_DP: { ATAPI_DEVICE_PATH *atapi = (ATAPI_DEVICE_PATH *)node; /* Check if this is a CD-ROM based on typical ATAPI usage */ (void)atapi; /* May use later for more specific detection */ } break; case MSG_SCSI_DP: info->device_type = BBS_HARDDISK; break; } break; case MEDIA_DEVICE_PATH: switch (subtype) { case MEDIA_HARDDRIVE_DP: info->device_type = BBS_HARDDISK; break; case MEDIA_CDROM_DP: info->device_type = BBS_CDROM; break; } break; } } info->valid = found_pci; return found_pci; } /* * Get PCI bus number by walking up to the PCI I/O protocol */ static bool get_pci_location(EFI_HANDLE device_handle, struct boot_device_info *info) { EFI_STATUS status; EFI_GUID pci_io_guid = EFI_PCI_IO_PROTOCOL_GUID; EFI_GUID device_path_guid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_DEVICE_PATH_PROTOCOL *device_path; EFI_PCI_IO_PROTOCOL *pci_io; EFI_HANDLE pci_handle; UINTN seg, bus, dev, func; /* First get the device path */ status = gBS->HandleProtocol(device_handle, &device_path_guid, (void **)&device_path); if (EFI_ERROR(status) || !device_path) { printf("bootdev: Failed to get device path: %d\n", (int)status); return false; } /* Parse the device path for basic info */ parse_device_path(device_path, info); /* Try to find PCI I/O protocol on this device path */ status = gBS->LocateDevicePath(&pci_io_guid, &device_path, &pci_handle); if (EFI_ERROR(status)) { printf("bootdev: No PCI I/O on device path: %d\n", (int)status); return info->valid; /* Return what we got from device path parsing */ } /* Get the PCI I/O protocol */ status = gBS->HandleProtocol(pci_handle, &pci_io_guid, (void **)&pci_io); if (EFI_ERROR(status)) { printf("bootdev: Failed to get PCI I/O protocol: %d\n", (int)status); return info->valid; } /* Get the actual PCI location */ status = pci_io->GetLocation(pci_io, &seg, &bus, &dev, &func); if (EFI_ERROR(status)) { printf("bootdev: Failed to get PCI location: %d\n", (int)status); return info->valid; } info->bus = (uint8_t)bus; info->device = (uint8_t)dev; info->function = (uint8_t)func; info->valid = true; /* Read PCI class code from config space offset 0x0B (class) and 0x0A (subclass) */ uint8_t class_code[2]; status = pci_io->Pci.Read(pci_io, EfiPciIoWidthUint8, 0x0A, 2, class_code); if (!EFI_ERROR(status)) { info->pci_subclass = class_code[0]; /* Offset 0x0A */ info->pci_class = class_code[1]; /* Offset 0x0B */ } printf("bootdev: PCI location %02x:%02x.%x class=%02x subclass=%02x\n", info->bus, info->device, info->function, info->pci_class, info->pci_subclass); return true; } /* * Check if two boot device info structures match (same controller) */ static bool devices_match(const struct boot_device_info *a, const struct boot_device_info *b) { if (!a->valid || !b->valid) { return false; } return (a->bus == b->bus && a->device == b->device && a->function == b->function); } /* * Get device type string for debug output */ static const char *device_type_str(uint16_t type) { switch (type) { case BBS_FLOPPY: return "Floppy"; case BBS_HARDDISK: return "HDD"; case BBS_CDROM: return "CDROM"; case BBS_PCMCIA: return "PCMCIA"; case BBS_USB: return "USB"; case BBS_EMBED_NETWORK: return "Network"; default: return "Unknown"; } } /* * Add a BBS entry for a block device * * priority: 0 = highest (boot device), 1+ = lower priority */ static void add_bbs_entry(struct low_stub *low_stub, const struct boot_device_info *info, int priority) { BBS_TABLE *entry; char *desc; size_t idx; if (low_stub->bbs_entry_count >= MAX_BBS_ENTRIES) { printf("bootdev: BBS table full, skipping device\n"); return; } idx = low_stub->bbs_entry_count; entry = &low_stub->bbs_entries[idx]; desc = low_stub->bbs_desc_strings[idx]; memset(entry, 0, sizeof(*entry)); /* Set boot priority - 0 is highest, higher numbers = lower priority */ entry->BootPriority = priority; /* PCI location */ entry->Bus = info->bus; entry->Device = info->device; entry->Function = info->function; /* Device type */ entry->DeviceType = info->device_type; /* PCI class codes - use actual values from device */ entry->Class = info->pci_class; entry->SubClass = info->pci_subclass; /* Status flags - mark as enabled and media present */ entry->StatusFlags.Enabled = 1; entry->StatusFlags.MediaPresent = 2; /* Media present and bootable */ /* Description string - stored in low memory */ if (priority == 0) { snprintf(desc, BBS_DESC_STRING_SIZE, "Boot %s %02x:%02x.%x", device_type_str(info->device_type), info->bus, info->device, info->function); } else { snprintf(desc, BBS_DESC_STRING_SIZE, "%s %02x:%02x.%x", device_type_str(info->device_type), info->bus, info->device, info->function); } /* Set description string pointer (segment:offset for real mode) */ uintptr_t desc_addr = (uintptr_t)desc; entry->DescStringSegment = EFI_SEGMENT(desc_addr); entry->DescStringOffset = EFI_OFFSET(desc_addr); printf("bootdev: BBS[%zu] %s pri=%d\n", idx, desc, entry->BootPriority); low_stub->bbs_entry_count++; } /* * Enumerate block I/O devices and build BBS entries */ static int enumerate_block_devices(struct low_stub *low_stub, const struct boot_device_info *boot_info) { EFI_STATUS status; EFI_GUID block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; EFI_HANDLE *handles = NULL; UINTN handle_count = 0; int next_priority = 1; /* Priority 0 reserved for boot device */ /* Find all block I/O devices */ status = gBS->LocateHandleBuffer(ByProtocol, &block_io_guid, NULL, &handle_count, &handles); if (EFI_ERROR(status)) { printf("bootdev: Failed to locate block devices: %d\n", (int)status); return -1; } printf("bootdev: Found %lu block devices\n", (unsigned long)handle_count); for (UINTN i = 0; i < handle_count; i++) { EFI_BLOCK_IO_PROTOCOL *block_io; struct boot_device_info dev_info; status = gBS->HandleProtocol(handles[i], &block_io_guid, (void **)&block_io); if (EFI_ERROR(status)) { continue; } /* Skip logical partitions, only want raw devices */ if (block_io->Media->LogicalPartition) { continue; } /* Get PCI location for this device */ if (!get_pci_location(handles[i], &dev_info)) { continue; } bool is_boot_device = boot_info->valid && devices_match(&dev_info, boot_info); int priority = is_boot_device ? 0 : next_priority++; add_bbs_entry(low_stub, &dev_info, priority); } gBS->FreePool(handles); return 0; } /* * Main entry point: build BBS table for SeaBIOS */ int build_bbs_table(struct csmwrap_priv *priv, EFI_HANDLE image_handle) { EFI_STATUS status; EFI_GUID loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL; struct boot_device_info boot_info = {0}; struct low_stub *low_stub = priv->low_stub; if (!low_stub) { printf("bootdev: low_stub not initialized\n"); return -1; } printf("bootdev: Building BBS table...\n"); /* Get loaded image protocol to find boot device */ status = gBS->HandleProtocol(image_handle, &loaded_image_guid, (void **)&loaded_image); if (EFI_ERROR(status) || !loaded_image) { printf("bootdev: Failed to get loaded image: %d\n", (int)status); /* Continue without boot device info - will enumerate all devices */ } else if (loaded_image->DeviceHandle) { /* Get boot device information */ printf("bootdev: Detecting boot device...\n"); if (get_pci_location(loaded_image->DeviceHandle, &boot_info)) { printf("bootdev: Boot device: PCI %02x:%02x.%x type=%s\n", boot_info.bus, boot_info.device, boot_info.function, device_type_str(boot_info.device_type)); } } /* Reset BBS table */ low_stub->bbs_entry_count = 0; memset(low_stub->bbs_entries, 0, sizeof(low_stub->bbs_entries)); memset(low_stub->bbs_desc_strings, 0, sizeof(low_stub->bbs_desc_strings)); /* Enumerate all block devices and build BBS entries */ if (enumerate_block_devices(low_stub, &boot_info) < 0) { printf("bootdev: Failed to enumerate block devices\n"); /* Not fatal - SeaBIOS can still enumerate drives itself */ } /* Set up boot_table to point to our BBS table */ if (low_stub->bbs_entry_count > 0) { low_stub->boot_table.NumberBbsEntries = low_stub->bbs_entry_count; low_stub->boot_table.BbsTable = (uintptr_t)low_stub->bbs_entries; printf("bootdev: BBS table built with %zu entries\n", low_stub->bbs_entry_count); } else { printf("bootdev: No BBS entries created\n"); } return 0; } ================================================ FILE: src/bootdev.h ================================================ #ifndef _BOOTDEV_H #define _BOOTDEV_H #include /* Forward declaration */ struct csmwrap_priv; /* * Boot device detection and BBS table building * * This module detects the boot device (the drive CSMWrap was loaded from) * and builds a BBS (BIOS Boot Specification) table for SeaBIOS with the * boot device prioritized first. */ /* Boot device information extracted from device path */ struct boot_device_info { bool valid; uint8_t bus; uint8_t device; uint8_t function; uint8_t pci_class; /* PCI class code */ uint8_t pci_subclass; /* PCI subclass code */ uint16_t device_type; /* BBS_HARDDISK, BBS_CDROM, etc. */ bool is_usb; uint16_t sata_port; /* SATA port number if applicable */ }; /* * Detect boot device and build BBS table * * This function: * 1. Parses the device path of the boot device to get PCI location * 2. Enumerates all block I/O devices * 3. Builds a BBS table with the boot device at highest priority * * @param priv CSMWrap private data structure (must have low_stub initialized) * @param image_handle EFI image handle (used to get loaded image info) * @return 0 on success, -1 on failure */ int build_bbs_table(struct csmwrap_priv *priv, EFI_HANDLE image_handle); #endif /* _BOOTDEV_H */ ================================================ FILE: src/config.c ================================================ #include #include #include #include #include #include #include struct csmwrap_config gConfig = { .serial_debug = false, .serial_port = 0x3f8, .serial_baud = 115200, .vgabios_path = {0}, .iommu_disable = true, .verbose = false, .vga_specified = false, .vga_bus = 0, .vga_device = 0, .vga_function = 0, .system_thread_specified = false, .system_thread_apic_id = 0, .cpu_filter_mode = CPU_FILTER_NONE, .cpu_filter_list = NULL, .cpu_filter_count = 0, }; bool config_cpu_in_filter(uint32_t apic_id) { if (gConfig.cpu_filter_mode == CPU_FILTER_NONE) return true; bool found = false; for (size_t i = 0; i < gConfig.cpu_filter_count; i++) { if (gConfig.cpu_filter_list[i] == apic_id) { found = true; break; } } if (gConfig.cpu_filter_mode == CPU_FILTER_ALLOWLIST) return found; /* CPU_FILTER_BLOCKLIST */ return !found; } static bool char_eq_nocase(char a, char b) { if (a >= 'A' && a <= 'Z') a += 'a' - 'A'; if (b >= 'A' && b <= 'Z') b += 'a' - 'A'; return a == b; } static bool streq_nocase(const char *a, const char *b) { while (*a && *b) { if (!char_eq_nocase(*a, *b)) return false; a++; b++; } return *a == *b; } static bool parse_bool(const char *val, bool *out) { if (streq_nocase(val, "true") || streq_nocase(val, "yes") || streq_nocase(val, "1")) { *out = true; return true; } if (streq_nocase(val, "false") || streq_nocase(val, "no") || streq_nocase(val, "0")) { *out = false; return true; } return false; } static bool parse_uint32(const char *val, uint32_t *out) { uint32_t result = 0; bool hex = false; if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) { hex = true; val += 2; } if (*val == '\0') return false; while (*val) { char c = *val; uint32_t digit; if (c >= '0' && c <= '9') { digit = c - '0'; } else if (hex && c >= 'a' && c <= 'f') { digit = 10 + c - 'a'; } else if (hex && c >= 'A' && c <= 'F') { digit = 10 + c - 'A'; } else { return false; } result = result * (hex ? 16 : 10) + digit; val++; } *out = result; return true; } static bool parse_hex_byte(const char *s, size_t len, uint32_t *out) { if (len == 0) return false; uint32_t result = 0; for (size_t i = 0; i < len; i++) { char c = s[i]; uint32_t digit; if (c >= '0' && c <= '9') digit = c - '0'; else if (c >= 'a' && c <= 'f') digit = 10 + c - 'a'; else if (c >= 'A' && c <= 'F') digit = 10 + c - 'A'; else return false; result = result * 16 + digit; } *out = result; return true; } /* * Parse a single token (already null-terminated) of the form "N" or "N-M" * into either a single value or an inclusive range. Both N and M are * decimal or 0x-prefixed hex. Whitespace around the '-' is allowed. * * Returns false on malformed input or if N > M. */ static bool parse_apic_id_token(char *tok, uint32_t *lo, uint32_t *hi) { char *dash = NULL; /* Skip a leading 0x prefix when scanning for '-' so we don't mistake * the hex digit sequence for a range delimiter (no negatives allowed). */ char *scan = tok; if (scan[0] == '0' && (scan[1] == 'x' || scan[1] == 'X')) scan += 2; for (char *q = scan; *q; q++) { if (*q == '-') { dash = q; break; } } if (!dash) { uint32_t v; if (!parse_uint32(tok, &v)) return false; *lo = *hi = v; return true; } /* Split into "lo" and "hi" halves, trimming whitespace around the dash. */ char *lo_end = dash; while (lo_end > tok && (lo_end[-1] == ' ' || lo_end[-1] == '\t')) lo_end--; char *hi_start = dash + 1; while (*hi_start == ' ' || *hi_start == '\t') hi_start++; if (lo_end == tok || *hi_start == '\0') return false; *lo_end = '\0'; uint32_t lo_v, hi_v; if (!parse_uint32(tok, &lo_v) || !parse_uint32(hi_start, &hi_v)) return false; if (lo_v > hi_v) return false; *lo = lo_v; *hi = hi_v; return true; } /* * Parse a comma-separated list of APIC IDs. * * Each entry is either a single ID (decimal or 0x-prefixed hex) or an * inclusive range "N-M". Whitespace around commas and dashes is ignored. * * If out is non-NULL, expanded IDs are written to out[0 .. *out_count - 1] * and parsing fails if more than out_capacity entries would be produced. * If out is NULL, the call counts entries without writing anything; this * lets callers size an allocation up front. * * Returns false on malformed input. */ static bool parse_apic_id_list(const char *val, uint32_t *out, size_t out_capacity, size_t *out_count) { size_t count = 0; const char *p = val; while (*p) { while (*p == ' ' || *p == '\t') p++; if (*p == '\0' || *p == ',') { if (*p == ',') p++; continue; } const char *start = p; while (*p && *p != ',') p++; const char *end = p; while (end > start && (end[-1] == ' ' || end[-1] == '\t')) end--; char buf[64]; size_t len = (size_t)(end - start); if (len == 0 || len >= sizeof(buf)) return false; for (size_t i = 0; i < len; i++) buf[i] = start[i]; buf[len] = '\0'; uint32_t lo, hi; if (!parse_apic_id_token(buf, &lo, &hi)) return false; for (uint32_t v = lo; ; v++) { if (out != NULL) { if (count >= out_capacity) return false; out[count] = v; } /* Guard against size_t overflow: a single uint32_t range can * span 2^32 entries, which wraps size_t on 32-bit builds. */ if (count == SIZE_MAX) return false; count++; if (v == hi) break; } if (*p == ',') p++; } *out_count = count; return true; } /* * Parse a PCI address in BB:DD.F format (all hex). */ static bool parse_pci_address(const char *val, uint8_t *bus, uint8_t *device, uint8_t *function) { /* Find ':' separator between bus and device */ const char *colon = NULL; for (const char *p = val; *p; p++) { if (*p == ':') { colon = p; break; } } if (!colon) return false; /* Find '.' separator between device and function */ const char *dot = NULL; for (const char *p = colon + 1; *p; p++) { if (*p == '.') { dot = p; break; } } if (!dot) return false; uint32_t b, d, f; if (!parse_hex_byte(val, (size_t)(colon - val), &b) || b > 0xFF) return false; if (!parse_hex_byte(colon + 1, (size_t)(dot - colon - 1), &d) || d > 0x1F) return false; size_t flen = 0; while (dot[1 + flen]) flen++; if (!parse_hex_byte(dot + 1, flen, &f) || f > 0x7) return false; *bus = (uint8_t)b; *device = (uint8_t)d; *function = (uint8_t)f; return true; } static const char *skip_whitespace(const char *s) { while (*s == ' ' || *s == '\t') s++; return s; } static size_t trim_trailing(const char *start, size_t len) { while (len > 0 && (start[len - 1] == ' ' || start[len - 1] == '\t' || start[len - 1] == '\r' || start[len - 1] == '\n')) len--; return len; } /* * Parse a single key=value line and apply it to gConfig. * key and val are null-terminated, trimmed strings. */ static void config_apply(const char *key, const char *val) { if (streq_nocase(key, "serial")) { bool v; if (parse_bool(val, &v)) { gConfig.serial_debug = v; printf(" serial = %s\n", v ? "true" : "false"); } else { printf(" warning: invalid value for 'serial': %s\n", val); } } else if (streq_nocase(key, "serial_port")) { uint32_t v; if (parse_uint32(val, &v) && v <= 0xFFFF) { gConfig.serial_port = (uint16_t)v; printf(" serial_port = 0x%x\n", gConfig.serial_port); } else { printf(" warning: invalid value for 'serial_port': %s\n", val); } } else if (streq_nocase(key, "serial_baud")) { uint32_t v; if (parse_uint32(val, &v) && v > 0) { gConfig.serial_baud = v; printf(" serial_baud = %u\n", gConfig.serial_baud); } else { printf(" warning: invalid value for 'serial_baud': %s\n", val); } } else if (streq_nocase(key, "vgabios")) { /* Convert ASCII path to CHAR16 */ size_t i; for (i = 0; val[i] && i < CONFIG_VGABIOS_PATH_MAX - 1; i++) gConfig.vgabios_path[i] = (CHAR16)(unsigned char)val[i]; gConfig.vgabios_path[i] = 0; printf(" vgabios = %s\n", val); } else if (streq_nocase(key, "iommu_disable")) { bool v; if (parse_bool(val, &v)) { gConfig.iommu_disable = v; printf(" iommu_disable = %s\n", v ? "true" : "false"); } else { printf(" warning: invalid value for 'iommu_disable': %s\n", val); } } else if (streq_nocase(key, "verbose")) { bool v; if (parse_bool(val, &v)) { gConfig.verbose = v; printf(" verbose = %s\n", v ? "true" : "false"); } else { printf(" warning: invalid value for 'verbose': %s\n", val); } } else if (streq_nocase(key, "vga")) { uint8_t b, d, f; if (parse_pci_address(val, &b, &d, &f)) { gConfig.vga_specified = true; gConfig.vga_bus = b; gConfig.vga_device = d; gConfig.vga_function = f; printf(" vga = %02x:%02x.%x\n", b, d, f); } else { printf(" warning: invalid PCI address for 'vga': %s (expected BB:DD.F)\n", val); } } else if (streq_nocase(key, "system_thread")) { uint32_t v; if (parse_uint32(val, &v)) { gConfig.system_thread_specified = true; gConfig.system_thread_apic_id = v; printf(" system_thread = APIC ID %u\n", v); } else { printf(" warning: invalid value for 'system_thread': %s\n", val); } } else if (streq_nocase(key, "cpu_allowlist") || streq_nocase(key, "cpu_blocklist")) { enum csmwrap_cpu_filter_mode mode = streq_nocase(key, "cpu_allowlist") ? CPU_FILTER_ALLOWLIST : CPU_FILTER_BLOCKLIST; if (gConfig.cpu_filter_mode != CPU_FILTER_NONE && gConfig.cpu_filter_mode != mode) { printf(" warning: '%s' ignored - cpu_allowlist and cpu_blocklist " "are mutually exclusive\n", key); } else { /* First pass: validate syntax and compute the expanded count. */ size_t count = 0; if (!parse_apic_id_list(val, NULL, 0, &count)) { printf(" warning: invalid value for '%s': %s\n", key, val); } else if (count > SIZE_MAX / sizeof(uint32_t)) { /* Allocation size would wrap size_t. */ printf(" warning: '%s' has too many entries (%zu)\n", key, count); } else { uint32_t *list = NULL; if (count > 0) { EFI_STATUS st = gBS->AllocatePool( EfiLoaderData, count * sizeof(uint32_t), (void **)&list); if (EFI_ERROR(st)) { printf(" warning: out of memory for '%s' (%zu IDs)\n", key, count); goto cpu_filter_done; } /* Second pass: actually fill the buffer. */ size_t actual = 0; if (!parse_apic_id_list(val, list, count, &actual) || actual != count) { gBS->FreePool(list); printf(" warning: parse mismatch for '%s'\n", key); goto cpu_filter_done; } } /* Replace any previously-set list. */ if (gConfig.cpu_filter_list) { gBS->FreePool(gConfig.cpu_filter_list); gConfig.cpu_filter_list = NULL; } gConfig.cpu_filter_mode = mode; gConfig.cpu_filter_list = list; gConfig.cpu_filter_count = count; if (count == 0) { printf(" %s = (empty)%s\n", key, mode == CPU_FILTER_ALLOWLIST ? " - only the BSP will be visible to the OS" : " - no CPUs hidden"); } else { printf(" %s = %zu APIC ID(s):", key, count); /* Cap the printed list so a giant range doesn't spam. */ size_t shown = count < 16 ? count : 16; for (size_t i = 0; i < shown; i++) printf(" %u", list[i]); if (shown < count) printf(" ... (+%zu more)", count - shown); printf("\n"); } } cpu_filter_done: ; } } else { printf(" warning: unknown config key '%s'\n", key); } } /* * Parse an INI-style buffer (flat key=value, no sections). */ static void config_parse(char *buf, size_t len) { char *line = buf; char *end = buf + len; while (line < end) { /* Find end of line */ char *eol = line; while (eol < end && *eol != '\n') eol++; /* Null-terminate the line */ if (eol < end) *eol = '\0'; const char *p = skip_whitespace(line); /* Skip empty lines and comments */ if (*p == '\0' || *p == ';' || *p == '#') { line = eol + 1; continue; } /* Find '=' separator */ const char *eq = p; while (*eq && *eq != '=') eq++; if (*eq != '=') { printf(" warning: malformed line (no '='): %s\n", p); line = eol + 1; continue; } /* Extract key: from p to eq, trimmed */ size_t key_len = trim_trailing(p, (size_t)(eq - p)); if (key_len == 0) { line = eol + 1; continue; } /* Null-terminate key in place */ char *key_start = (char *)p; key_start[key_len] = '\0'; /* Extract value: after '=', trimmed */ const char *val_start = skip_whitespace(eq + 1); size_t val_len = trim_trailing(val_start, eol - val_start); /* Null-terminate value in place */ char *val_mut = (char *)val_start; val_mut[val_len] = '\0'; config_apply(key_start, val_mut); line = eol + 1; } } /* * Build the config file path by finding the directory of the running * EFI executable from its device path and appending "csmwrap.ini". */ static bool config_build_path(EFI_DEVICE_PATH_PROTOCOL *file_path, CHAR16 *out, size_t out_chars) { if (!file_path) return false; /* Reconstruct the file path string from FILEPATH_DEVICE_PATH nodes */ size_t pos = 0; out[0] = 0; EFI_DEVICE_PATH_PROTOCOL *node; for (node = file_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { if (DevicePathType(node) == MEDIA_DEVICE_PATH && DevicePathSubType(node) == MEDIA_FILEPATH_DP) { FILEPATH_DEVICE_PATH *fp = (FILEPATH_DEVICE_PATH *)node; CHAR16 *src = fp->PathName; while (*src && pos < out_chars - 1) { out[pos++] = *src++; } } } out[pos] = 0; if (pos == 0) return false; /* Find the last backslash to strip the filename */ size_t last_sep = 0; bool found_sep = false; for (size_t i = 0; i < pos; i++) { if (out[i] == L'\\' || out[i] == L'/') { last_sep = i; found_sep = true; } } size_t dir_end; if (found_sep) { dir_end = last_sep + 1; /* keep the trailing backslash */ } else { /* No separator - file is at root, prepend backslash */ dir_end = 0; if (pos + 1 < out_chars) { out[0] = L'\\'; dir_end = 1; } } /* Append "csmwrap.ini" */ static const CHAR16 ini_name[] = L"csmwrap.ini"; size_t name_len = sizeof(ini_name) / sizeof(CHAR16) - 1; if (dir_end + name_len >= out_chars) return false; for (size_t i = 0; i <= name_len; i++) out[dir_end + i] = ini_name[i]; return true; } void config_load(EFI_FILE_PROTOCOL *root_dir, EFI_DEVICE_PATH_PROTOCOL *file_path) { if (!root_dir || !file_path) return; CHAR16 path[512]; if (!config_build_path(file_path, path, ARRAY_SIZE(path))) { printf("Config: could not determine executable directory\n"); return; } EFI_FILE_PROTOCOL *file = NULL; EFI_STATUS status = root_dir->Open(root_dir, &file, path, EFI_FILE_MODE_READ, 0); if (status != EFI_SUCCESS) { /* Not an error - config file is optional */ return; } /* Get file size via EFI_FILE_INFO */ EFI_GUID fi_guid = EFI_FILE_INFO_ID; UINTN info_size = 0; file->GetInfo(file, &fi_guid, &info_size, NULL); void *info_buf = NULL; if (gBS->AllocatePool(EfiLoaderData, info_size, &info_buf) != EFI_SUCCESS) { file->Close(file); return; } UINTN file_size = 0; if (file->GetInfo(file, &fi_guid, &info_size, info_buf) == EFI_SUCCESS) { EFI_FILE_INFO *fi = info_buf; file_size = (UINTN)fi->FileSize; } gBS->FreePool(info_buf); if (file_size == 0 || file_size > 64 * 1024) { printf("Config: file empty or too large (%lu bytes)\n", (unsigned long)file_size); file->Close(file); return; } /* Read file contents */ char *buf = NULL; if (gBS->AllocatePool(EfiLoaderData, file_size + 1, (void **)&buf) != EFI_SUCCESS) { file->Close(file); return; } UINTN read_size = file_size; if (file->Read(file, &read_size, buf) != EFI_SUCCESS) { gBS->FreePool(buf); file->Close(file); return; } buf[read_size] = '\0'; file->Close(file); printf("Config: loaded csmwrap.ini (%lu bytes)\n", (unsigned long)read_size); config_parse(buf, read_size); gBS->FreePool(buf); } ================================================ FILE: src/config.h ================================================ #ifndef CONFIG_H #define CONFIG_H #include #include #include #include #define CONFIG_VGABIOS_PATH_MAX 256 enum csmwrap_cpu_filter_mode { CPU_FILTER_NONE = 0, CPU_FILTER_ALLOWLIST, CPU_FILTER_BLOCKLIST, }; struct csmwrap_config { bool serial_debug; uint16_t serial_port; uint32_t serial_baud; CHAR16 vgabios_path[CONFIG_VGABIOS_PATH_MAX]; bool iommu_disable; bool verbose; bool vga_specified; uint8_t vga_bus; uint8_t vga_device; uint8_t vga_function; bool system_thread_specified; uint32_t system_thread_apic_id; /* * cpu_filter_list points to an EFI-pool-allocated array of length * cpu_filter_count, or is NULL when cpu_filter_count == 0. An empty * list with mode ALLOWLIST means "no APs visible to the OS"; an * empty list with mode BLOCKLIST means "no APs hidden from the OS". */ enum csmwrap_cpu_filter_mode cpu_filter_mode; uint32_t *cpu_filter_list; size_t cpu_filter_count; }; extern struct csmwrap_config gConfig; /* * Returns true if the CPU with the given APIC ID is allowed by the * user-configured allow/block list. Does NOT consider BSP-must-keep or * system-thread-must-hide rules - callers handle those separately. * * With CPU_FILTER_NONE this always returns true. */ bool config_cpu_in_filter(uint32_t apic_id); /* * Load configuration from csmwrap.ini next to the running EFI executable. * root_dir: filesystem root opened via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * file_path: loaded image's FilePath device path (used to find our directory) * * If the file is missing or unreadable, defaults are silently retained. */ void config_load(EFI_FILE_PROTOCOL *root_dir, EFI_DEVICE_PATH_PROTOCOL *file_path); #endif ================================================ FILE: src/coreboot.c ================================================ #include #include "csmwrap.h" static UINT16 CbCheckSum16 ( IN UINT16 *Buffer, IN UINTN Length ) { UINT32 Sum; UINT32 TmpValue; UINTN Idx; UINT8 *TmpPtr; Sum = 0; TmpPtr = (UINT8 *)Buffer; for (Idx = 0; Idx < Length; Idx++) { TmpValue = TmpPtr[Idx]; if (Idx % 2 == 1) { TmpValue <<= 8; } Sum += TmpValue; // Wrap if (Sum >= 0x10000) { Sum = (Sum + (Sum >> 16)) & 0xFFFF; } } return (UINT16)((~Sum) & 0xFFFF); } int build_coreboot_table(struct csmwrap_priv *priv) { void *p = (void *)CB_TABLE_START; void *tables; uint32_t table_entries = 0; struct cb_header *header = (struct cb_header *)p; memset(header, 0, sizeof(struct cb_header)); header->signature = CB_HEADER_SIGNATURE; header->header_bytes = sizeof(struct cb_header); p += header->header_bytes; tables = p; /* cb_framebuffer */ if (priv->video_type != CSMWRAP_VIDEO_OPROM) { struct cb_framebuffer *framebuffer = (struct cb_framebuffer *)p; memcpy(framebuffer, &priv->cb_fb, sizeof(struct cb_framebuffer)); framebuffer->tag = CB_TAG_FRAMEBUFFER; framebuffer->size = sizeof(struct cb_framebuffer); p += framebuffer->size; table_entries++; } /* Last header stuff */ header->table_entries = table_entries; header->table_bytes = (uint32_t)((uintptr_t)p - (uintptr_t)tables); header->table_checksum = CbCheckSum16((UINT16*)tables, header->table_bytes); header->header_checksum = CbCheckSum16((UINT16*)header, header->header_bytes); return 0; } ================================================ FILE: src/csmwrap.c ================================================ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Generated by: xxd -i Csm16.bin >> Csm16.h #include #ifndef BUILD_VERSION #define BUILD_VERSION "Unknown" #endif const char *banner = "\033[38;2;0;102;128m _,,,,,,,,,,_\n" " _,;l!l'''''''''''''l;l;,_\n" " ,;l!''....................`ql;,_\n" " ,;l'`............................`ql;_\n" " ,;l'..........\033[38;2;141;211;95m_____\033[38;2;0;102;128m...................`ql,\n" " lp`.........\033[38;2;141;211;95m,;#######;,\033[38;2;0;102;128m..................'ql\n" " ,l'......\033[38;2;141;211;95m_,;####\033[38;2;228;230;109mooooooo\033[38;2;141;211;95m##;_\033[38;2;0;102;128m..................ql,\n" " ,l'....\033[38;2;141;211;95m,#######################+,\033[38;2;0;102;128m..............ql,\n" ",l'...\033[38;2;141;211;95m,##############################,\033[38;2;0;102;128m...........ql,\n" "lp....\033[38;2;199;221;133m############\033[38;2;141;211;95m######################,\033[38;2;0;102;128m.........ql \n" "lp....\033[38;2;199;221;133m###############\033[38;2;141;211;95m######################,\033[38;2;0;102;128m......ql\n" "lp....\033[38;2;199;221;133m`################\033[38;2;141;211;95m#####################\\\033[38;2;0;102;128m.....ql \n" "lp.....\033[38;2;199;221;133m`################\033[38;2;141;211;95m#####################\\\033[38;2;0;102;128m....ql\n" "`l,......\033[38;2;199;221;133m`###############\033[38;2;141;211;95m#####################\033[38;2;0;102;128m...,l'\n" " `l........\033[38;2;199;221;133m`\"#########\033[38;2;141;211;95m########################\033[38;2;0;102;128m..,l'\n" " `l,.........\033[38;2;199;221;133m`\"\"#####\033[38;2;141;211;95m######################%\033[38;2;0;102;128m..,l'\n" " `l,.........\033[38;2;141;211;95m,,,,,;####################%\"\033[38;2;0;102;128m...,l' \n" " `l;,...\033[38;2;141;211;95m\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'\033[38;2;0;102;128m.....,;l' \n" " `l;,_.............................._,;l' \n" " `l;,_......................._,;l'' \n" " `'l;p,_............_,,;lll'`\n" " `'''::::::::::'''\033[0m\n" "CSMWrap Version " BUILD_VERSION "\n" "https://github.com/CSMWrap/CSMWrap\n" "By: Jiaxun Yang \n" "And: Mintsuki \n"; EFI_SYSTEM_TABLE *gST; EFI_BOOT_SERVICES *gBS; EFI_RUNTIME_SERVICES *gRT; EFI_TIME gTimeAtBoot; bool gBootServicesExited = false; struct csmwrap_priv priv = { .csm_bin = Csm16_bin, }; /* * UEFI memory allocation wrappers for Flanterm. * These use EFI Boot Services pool allocation. */ static void *flanterm_uefi_malloc(size_t size) { void *ptr = NULL; if (gBS->AllocatePool(EfiLoaderData, size, &ptr) != EFI_SUCCESS) { return NULL; } return ptr; } static void flanterm_uefi_free(void *ptr, size_t size) { (void)size; /* UEFI FreePool doesn't need size */ if (ptr != NULL) { gBS->FreePool(ptr); } } static void *find_table(uint32_t signature, uint8_t *csm_bin_base, size_t size) { /* Compatibility16 header: signature[4], checksum[1], length[1], ... */ for (uint8_t *Ptr = csm_bin_base; Ptr + 6 <= csm_bin_base + size; Ptr += 0x10) { if (*(uint32_t *)Ptr != signature) continue; uint8_t table_len = Ptr[5]; if (table_len < 6 || (size_t)(Ptr - csm_bin_base) + table_len > size) continue; uint8_t sum = 0; for (uint8_t i = 0; i < table_len; i++) sum += Ptr[i]; if (sum == 0) return Ptr; } return NULL; } /* * SMBIOS entry point structures */ #define SMBIOS_21_SIGNATURE 0x5f4d535f /* "_SM_" */ #define SMBIOS_21_ENTRY_POINT_LENGTH 0x1F /* Standard length */ #pragma pack(1) struct smbios_21_entry_point { uint32_t signature; /* "_SM_" */ uint8_t checksum; /* Checksum of bytes 0x00-0x0F */ uint8_t length; /* Entry point length (usually 0x1F) */ uint8_t smbios_major_version; uint8_t smbios_minor_version; uint16_t max_structure_size; uint8_t entry_point_revision; uint8_t formatted_area[5]; char intermediate_anchor_string[5]; /* "_DMI_" */ uint8_t intermediate_checksum; /* Checksum of bytes 0x10-0x1E */ uint16_t structure_table_length; /* Total length of structure table */ uint32_t structure_table_address; /* Physical address of structure table */ uint16_t number_of_structures; uint8_t smbios_bcd_revision; }; struct smbios_30_entry_point { char signature[5]; /* "_SM3_" */ uint8_t checksum; uint8_t length; uint8_t smbios_major_version; uint8_t smbios_minor_version; uint8_t smbios_docrev; uint8_t entry_point_revision; uint8_t reserved; uint32_t structure_table_max_size; uint64_t structure_table_address; /* 64-bit! */ }; /* SMBIOS structure header - at the start of every structure */ struct smbios_structure_header { uint8_t type; uint8_t length; /* Length of formatted area only, not including strings */ uint16_t handle; }; #pragma pack() static uint8_t smbios_checksum(const void *data, size_t len) { const uint8_t *p = data; uint8_t sum = 0; for (size_t i = 0; i < len; i++) sum += p[i]; return sum; } /* * Statistics gathered from walking the SMBIOS structure table. * Using uint32_t for sizes to avoid overflow during calculation, * even though SMBIOS 2.x limits these to 16-bit values. */ struct smbios_table_stats { uint32_t number_of_structures; uint32_t max_structure_size; uint32_t table_length; }; /* * Walk the SMBIOS structure table and gather statistics. * The structure table format is the same for SMBIOS 2.x and 3.0. * * Each structure consists of: * - Formatted area (header.length bytes, starting with the header) * - Unformatted area (null-terminated strings, ending with double-null) * * Returns true on success, false if the table appears corrupted. */ static bool smbios_walk_table(const void *table, uint32_t max_size, struct smbios_table_stats *stats) { const uint8_t *ptr = table; const uint8_t *end = ptr + max_size; stats->number_of_structures = 0; stats->max_structure_size = 0; stats->table_length = 0; while (ptr + sizeof(struct smbios_structure_header) <= end) { const struct smbios_structure_header *hdr = (const struct smbios_structure_header *)ptr; /* Sanity check: length must be at least header size */ if (hdr->length < sizeof(struct smbios_structure_header)) { printf(" Warning: Invalid structure length %u at offset %u\n", hdr->length, (uint32_t)(ptr - (const uint8_t *)table)); return false; } /* Check formatted area doesn't exceed bounds */ if (ptr + hdr->length > end) { printf(" Warning: Structure exceeds table bounds\n"); return false; } /* Find the end of the unformatted area (strings) */ const uint8_t *strings_start = ptr + hdr->length; const uint8_t *strings_ptr = strings_start; /* Look for double-null terminator */ bool found_terminator = false; while (strings_ptr + 1 < end) { if (strings_ptr[0] == 0 && strings_ptr[1] == 0) { strings_ptr += 2; /* Include both nulls */ found_terminator = true; break; } strings_ptr++; } if (!found_terminator) { printf(" Warning: Missing double-null terminator\n"); return false; } /* Calculate this structure's total size */ uint32_t struct_size = (uint32_t)(strings_ptr - ptr); if (struct_size > stats->max_structure_size) { stats->max_structure_size = struct_size; } stats->number_of_structures++; /* Type 127 marks end of table */ if (hdr->type == 127) { stats->table_length = (uint32_t)(strings_ptr - (const uint8_t *)table); return true; } ptr = strings_ptr; } /* Reached end without finding type 127 - use what we have */ stats->table_length = (uint32_t)(ptr - (const uint8_t *)table); return true; } /* * Allocated buffer for synthesized/relocated SMBIOS data. */ static void *smbios_buffer = NULL; /* * Synthesize an SMBIOS 2.x entry point from SMBIOS 3.0 data. * The structure table data format is identical; only the entry point differs. * * Allocates memory for entry point + structure table below 4GB. * Returns the new SMBIOS 2.x entry point, or NULL on failure. */ static struct smbios_21_entry_point *synthesize_smbios_21_from_30( struct smbios_30_entry_point *ep30, uint64_t st_addr, uint32_t st_max_size) { /* Walk the structure table to get accurate statistics */ struct smbios_table_stats stats; if (!smbios_walk_table((void *)(uintptr_t)st_addr, st_max_size, &stats)) { printf(" Failed to parse SMBIOS structure table\n"); return NULL; } printf(" Table stats: %u structures, max size %u, actual length %u\n", stats.number_of_structures, stats.max_structure_size, stats.table_length); /* Check for SMBIOS 2.x limitations (16-bit fields) */ if (stats.table_length > 0xFFFF) { printf(" Warning: Table length %u exceeds SMBIOS 2.x limit (65535)\n", stats.table_length); /* Truncate - some data will be missing but better than nothing */ stats.table_length = 0xFFFF; } if (stats.max_structure_size > 0xFFFF) { printf(" Warning: Max structure size exceeds SMBIOS 2.x limit\n"); stats.max_structure_size = 0xFFFF; } if (stats.number_of_structures > 0xFFFF) { printf(" Warning: Structure count exceeds SMBIOS 2.x limit\n"); stats.number_of_structures = 0xFFFF; } /* Allocate buffer for entry point + structure table below 4GB */ size_t total_size = SMBIOS_21_ENTRY_POINT_LENGTH + stats.table_length; EFI_PHYSICAL_ADDRESS max_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiRuntimeServicesData, (total_size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE, &max_addr ); if (status != EFI_SUCCESS) { printf(" Failed to allocate memory for SMBIOS synthesis\n"); return NULL; } smbios_buffer = (void *)(uintptr_t)max_addr; printf(" Synthesizing SMBIOS 2.x at %p\n", smbios_buffer); /* Build the SMBIOS 2.x entry point */ struct smbios_21_entry_point *ep21 = smbios_buffer; memset(ep21, 0, SMBIOS_21_ENTRY_POINT_LENGTH); ep21->signature = SMBIOS_21_SIGNATURE; ep21->length = SMBIOS_21_ENTRY_POINT_LENGTH; ep21->smbios_major_version = ep30->smbios_major_version; ep21->smbios_minor_version = ep30->smbios_minor_version; ep21->max_structure_size = (uint16_t)stats.max_structure_size; ep21->entry_point_revision = 0; memcpy(ep21->intermediate_anchor_string, "_DMI_", 5); ep21->structure_table_length = (uint16_t)stats.table_length; ep21->number_of_structures = stats.number_of_structures; /* BCD revision: major in high nibble, minor in low nibble */ ep21->smbios_bcd_revision = ((ep30->smbios_major_version & 0xF) << 4) | (ep30->smbios_minor_version & 0xF); /* Copy structure table after entry point */ void *st_dest = (uint8_t *)smbios_buffer + SMBIOS_21_ENTRY_POINT_LENGTH; memcpy(st_dest, (void *)(uintptr_t)st_addr, stats.table_length); ep21->structure_table_address = (uint32_t)(uintptr_t)st_dest; /* Calculate checksums */ ep21->checksum = 0; ep21->intermediate_checksum = 0; ep21->intermediate_checksum = -smbios_checksum((uint8_t *)ep21 + 0x10, SMBIOS_21_ENTRY_POINT_LENGTH - 0x10); ep21->checksum = -smbios_checksum(ep21, SMBIOS_21_ENTRY_POINT_LENGTH); printf(" Synthesis complete: SMBIOS %u.%u, %u structures, table at %x\n", ep21->smbios_major_version, ep21->smbios_minor_version, ep21->number_of_structures, ep21->structure_table_address); return ep21; } #ifdef __x86_64__ /* * Relocate SMBIOS 2.x entry point and structure table to below 4GB. * Only needed on 64-bit systems where SMBIOS data may be above 4GB. * Returns the new entry point address, or NULL on failure. */ static struct smbios_21_entry_point *relocate_smbios_21( struct smbios_21_entry_point *ep, uint64_t st_addr, uint32_t st_size) { size_t ep_size = ep->length; size_t total_size = ep_size + st_size; /* Allocate below 4GB */ EFI_PHYSICAL_ADDRESS max_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiRuntimeServicesData, (total_size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE, &max_addr ); if (status != EFI_SUCCESS) { printf(" Failed to allocate memory for SMBIOS relocation\n"); return NULL; } smbios_buffer = (void *)(uintptr_t)max_addr; printf(" Relocating SMBIOS to %p\n", smbios_buffer); /* Copy entry point */ struct smbios_21_entry_point *new_ep = smbios_buffer; memcpy(new_ep, ep, ep_size); /* Copy structure table right after entry point */ void *new_st = (uint8_t *)smbios_buffer + ep_size; memcpy(new_st, (void *)(uintptr_t)st_addr, st_size); /* Update structure table address in the new entry point */ new_ep->structure_table_address = (uint32_t)(uintptr_t)new_st; /* Recalculate checksums */ new_ep->checksum = 0; new_ep->intermediate_checksum = 0; new_ep->intermediate_checksum = -smbios_checksum((uint8_t *)new_ep + 0x10, ep_size - 0x10); new_ep->checksum = -smbios_checksum(new_ep, ep_size); printf(" Relocation complete, new structure table at %x\n", new_ep->structure_table_address); return new_ep; } #endif /* __x86_64__ */ int set_smbios_table() { EFI_GUID smbiosGuid = SMBIOS_TABLE_GUID; EFI_GUID smbios3Guid = SMBIOS3_TABLE_GUID; struct smbios_21_entry_point *result_ep = NULL; /* First, try to find SMBIOS 2.x table (preferred for legacy compatibility) */ for (size_t i = 0; i < gST->NumberOfTableEntries; i++) { EFI_CONFIGURATION_TABLE *table = gST->ConfigurationTable + i; if (!efi_guidcmp(table->VendorGuid, smbiosGuid)) { struct smbios_21_entry_point *ep = table->VendorTable; printf("Found SMBIOS 2.x entry point at %p\n", (void *)ep); /* Validate signature */ if (ep->signature != SMBIOS_21_SIGNATURE) { printf(" Invalid signature, skipping\n"); continue; } /* Validate checksums */ if (smbios_checksum(ep, 0x10) != 0) { printf(" Invalid entry point checksum, skipping\n"); continue; } if (memcmp(ep->intermediate_anchor_string, "_DMI_", 5) != 0) { printf(" Invalid DMI anchor, skipping\n"); continue; } if (smbios_checksum((uint8_t *)ep + 0x10, ep->length - 0x10) != 0) { printf(" Invalid intermediate checksum, skipping\n"); continue; } printf(" Version: %u.%u, structure table at %x, length %u\n", ep->smbios_major_version, ep->smbios_minor_version, ep->structure_table_address, ep->structure_table_length); #ifdef __x86_64__ /* Check if entry point or structure table is above 4GB */ uint64_t ep_addr = (uint64_t)(uintptr_t)ep; uint64_t st_addr = ep->structure_table_address; if (ep_addr >= 0x100000000ULL || st_addr >= 0x100000000ULL) { printf(" Entry point or structure table above 4GB, relocation needed\n"); result_ep = relocate_smbios_21(ep, st_addr, ep->structure_table_length); break; } #endif result_ep = ep; break; } } /* * If SMBIOS 2.x not found/usable, try SMBIOS 3.0. * We synthesize an SMBIOS 2.x entry point from the 3.0 data since * SeaBIOS and legacy operating systems only understand 2.x format. */ if (!result_ep) { for (size_t i = 0; i < gST->NumberOfTableEntries; i++) { EFI_CONFIGURATION_TABLE *table = gST->ConfigurationTable + i; if (!efi_guidcmp(table->VendorGuid, smbios3Guid)) { struct smbios_30_entry_point *ep = table->VendorTable; printf("Found SMBIOS 3.0 entry point at %p\n", (void *)ep); /* Validate signature */ if (memcmp(ep->signature, "_SM3_", 5) != 0) { printf(" Invalid signature, skipping\n"); continue; } /* Validate checksum */ if (smbios_checksum(ep, ep->length) != 0) { printf(" Invalid checksum, skipping\n"); continue; } printf(" Version: %u.%u, structure table at %lx, max size %u\n", ep->smbios_major_version, ep->smbios_minor_version, (unsigned long)ep->structure_table_address, ep->structure_table_max_size); /* Synthesize SMBIOS 2.x from 3.0 */ result_ep = synthesize_smbios_21_from_30( ep, ep->structure_table_address, ep->structure_table_max_size); break; } } } if (!result_ep) { printf("No usable SMBIOS table found\n"); return -1; } priv.low_stub->boot_table.SmbiosTable = (uintptr_t)result_ep; priv.low_stub->boot_table.SmbiosTableLength = result_ep->structure_table_length; return 0; } void __attribute__((noreturn)) panic(const char *fmt, ...) { gConfig.verbose = true; printf("\n*** PANIC: "); va_list l; va_start(l, fmt); vprintf(fmt, l); va_end(l); printf("*** System halted.\n"); for (;;) { asm volatile("hlt"); } } EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { EFI_PHYSICAL_ADDRESS HiPmm; uintptr_t csm_bin_base; EFI_STATUS Status; EFI_IA32_REGISTER_SET Regs; gST = SystemTable; gBS = SystemTable->BootServices; gRT = SystemTable->RuntimeServices; calibrate_tsc(); csmwrap_video_early_init(&priv); /* Initialise Flanterm (output gated on verbose; panics always show) */ if (priv.cb_fb.physical_address != 0) { flanterm_ctx = flanterm_fb_init( flanterm_uefi_malloc, flanterm_uefi_free, (void *)(uintptr_t)priv.cb_fb.physical_address, priv.cb_fb.x_resolution, priv.cb_fb.y_resolution, priv.cb_fb.bytes_per_line, priv.cb_fb.red_mask_size, priv.cb_fb.red_mask_pos, priv.cb_fb.green_mask_size, priv.cb_fb.green_mask_pos, priv.cb_fb.blue_mask_size, priv.cb_fb.blue_mask_pos, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, FLANTERM_FB_ROTATE_0 ); } gBS->SetWatchdogTimer(0, 0, 0, NULL); /* Banner is always shown on screen */ gConfig.verbose = true; printf("%s", banner); gConfig.verbose = false; for (EFI_PHYSICAL_ADDRESS i = 0; i < 0x100000; i += EFI_PAGE_SIZE) { EFI_PHYSICAL_ADDRESS j = i; if (gBS->AllocatePages(AllocateAddress, EfiLoaderData, 1, &j) != EFI_SUCCESS) { if (i < 0xa0000) { printf("warning: Early AllocatePages() failed for address 0x%llx\n", (unsigned long long)i); } } } if (gRT->GetTime(&gTimeAtBoot, NULL) != EFI_SUCCESS) { panic("Failed to query current time\n"); } EFI_GUID loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL; if (gBS->HandleProtocol(ImageHandle, &loaded_image_guid, (void **)&loaded_image) != EFI_SUCCESS) { loaded_image = NULL; } EFI_GUID sfs_protocol_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *sfs_protocol = NULL; if (loaded_image == NULL || gBS->HandleProtocol(loaded_image->DeviceHandle, &sfs_protocol_guid, (void **)&sfs_protocol) != EFI_SUCCESS) { sfs_protocol = NULL; } EFI_FILE_PROTOCOL *sfs_dir = NULL; if (sfs_protocol == NULL || sfs_protocol->OpenVolume(sfs_protocol, &sfs_dir) != EFI_SUCCESS) { sfs_dir = NULL; } /* Load configuration from csmwrap.ini next to our executable */ if (sfs_dir != NULL && loaded_image != NULL) { config_load(sfs_dir, loaded_image->FilePath); } /* Load custom VGABIOS from config path if specified */ EFI_FILE_PROTOCOL *vgabios_file_handle = NULL; if (sfs_dir != NULL && gConfig.vgabios_path[0] != 0) { if (sfs_dir->Open(sfs_dir, &vgabios_file_handle, gConfig.vgabios_path, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) { UINTN max_size = 256 * 1024; if (gBS->AllocatePool(EfiLoaderData, max_size, &vbios_loc) != EFI_SUCCESS) { vbios_loc = NULL; } else { if (vgabios_file_handle->Read(vgabios_file_handle, &max_size, vbios_loc) == EFI_SUCCESS) { printf("Loaded custom VBIOS from config. Using it as our VBIOS!\n"); vbios_size = max_size; } else { gBS->FreePool(vbios_loc); vbios_loc = NULL; } } vgabios_file_handle->Close(vgabios_file_handle); } else { printf("warning: could not open configured vgabios path\n"); } } if (sfs_dir != NULL) { sfs_dir->Close(sfs_dir); } if (unlock_bios_region()) { panic("Unable to unlock BIOS region\n"); } printf("Unlock!\n"); apply_intel_platform_workarounds(); csm_bin_base = (uintptr_t)BIOSROM_END - sizeof(Csm16_bin); priv.csm_bin_base = csm_bin_base; printf("csm_bin_base: 0x%lx\n", csm_bin_base); if (csm_bin_base < VGABIOS_END) { panic("Illegal csm_bin size\n"); } priv.csm_efi_table = find_table(EFI_COMPATIBILITY16_TABLE_SIGNATURE, Csm16_bin, sizeof(Csm16_bin)); if (priv.csm_efi_table == NULL) { panic("EFI_COMPATIBILITY16_TABLE not found\n"); } /* Initialize ACPI first (needed for MADT parsing in bios_proxy_init) */ if (!acpi_init(&priv)) { panic("ACPI initialization failed\n"); } /* Calculate RSDP copy location for MADT patching */ void *rsdp_copy = priv.csm_bin + (priv.csm_efi_table->AcpiRsdPtrPointer - priv.csm_bin_base); /* Initialize BIOS proxy (find mailbox and helper entry in CSM binary) */ if (bios_proxy_init(Csm16_bin, sizeof(Csm16_bin), rsdp_copy) != 0) { panic("BIOS proxy initialization failed\n"); } bool pci_initialized = pci_early_initialize(); if (!pci_initialized) printf("pci_early_initialize failed, PCI BAR relocation will be skipped\n"); Status = csmwrap_video_init(&priv); /* Enumerate non-VGA PCI option ROMs while boot services are available */ struct pci_oprom_list oprom_list; oprom_enumerate(&priv, &oprom_list); HiPmm = 0xffffffff; if (gBS->AllocatePages(AllocateMaxAddress, EfiRuntimeServicesData, HIPMM_SIZE / EFI_PAGE_SIZE, &HiPmm) != EFI_SUCCESS) { panic("Unable to alloc HiPmm\n"); } priv.low_stub = (struct low_stub *)LOW_STUB_BASE; memset((void*)LOW_STUB_BASE, 0, CONVEN_END - LOW_STUB_BASE); set_smbios_table(); priv.low_stub->boot_table.AcpiTable = priv.csm_efi_table->AcpiRsdPtrPointer; uintptr_t pmm_base = LegacyBiosInitializeThunkAndTable(LOW_STUB_BASE, sizeof(struct low_stub)); printf("Init Thunk pmm: %lx\n", (uintptr_t)pmm_base); priv.low_stub->init_table.BiosLessThan1MB = 0; // SeaBIOS does not actually use this field. priv.low_stub->init_table.ThunkStart = (uint32_t)(uintptr_t)priv.low_stub; priv.low_stub->init_table.ThunkSizeInBytes = sizeof(struct low_stub); priv.low_stub->init_table.LowPmmMemory = (uint32_t)pmm_base; priv.low_stub->init_table.LowPmmMemorySizeInBytes = (uint32_t)CONVEN_END - (uint32_t)pmm_base; priv.low_stub->init_table.HiPmmMemorySizeInBytes = HIPMM_SIZE; priv.low_stub->init_table.HiPmmMemory = HiPmm; priv.low_stub->vga_oprom_table.OpromSegment = EFI_SEGMENT(VGABIOS_START); priv.low_stub->vga_oprom_table.PciBus = priv.vga_pci_bus; priv.low_stub->vga_oprom_table.PciDeviceFunction = priv.vga_pci_devfn; /* Build BBS table with boot device prioritized */ build_bbs_table(&priv, ImageHandle); /* Build MP table from ACPI MADT (excludes helper core) */ mptable_init(&priv); /* Build $PIR table from ACPI _PRT for legacy PCI BIOS callers */ pir_init(&priv); printf("CALL16 %x:%x\n", priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset); /* WARNING: No EFI Video afterwards */ csmwrap_video_prepare_exitbs(&priv); /* WARNING: No EFI runtime service afterwards */ UINTN efi_mmap_size = 0, efi_desc_size = 0, efi_mmap_key = 0; UINT32 efi_desc_ver = 0; EFI_MEMORY_DESCRIPTOR *efi_mmap = NULL; UINTN efi_mmap_alloc = 0; for (size_t retries = 0; ; retries++) { if (retries == 128) { panic("Failed to exit boot services\n"); } efi_mmap_size = efi_mmap_alloc; Status = gBS->GetMemoryMap(&efi_mmap_size, efi_mmap, &efi_mmap_key, &efi_desc_size, &efi_desc_ver); if (Status == EFI_BUFFER_TOO_SMALL) { /* Map grew (or first call) - reallocate with slack for the * descriptors that AllocatePool itself may add. */ if (efi_mmap != NULL) { gBS->FreePool(efi_mmap); } efi_mmap_alloc = efi_mmap_size + 4096; if (gBS->AllocatePool(EfiLoaderData, efi_mmap_alloc, (void **)&efi_mmap) != EFI_SUCCESS) { panic("AllocatePool() for EFI memory map failed\n"); } continue; } if (Status != EFI_SUCCESS) { panic("GetMemoryMap() failed\n"); } Status = gBS->ExitBootServices(ImageHandle, efi_mmap_key); if (Status == EFI_SUCCESS) { break; } /* Key invalidated by a memory-map change - retry. */ } /* Boot services protocols (including serial I/O) are no longer usable */ gBootServicesExited = true; /* Disable external interrupts */ asm volatile ("cli"); /* Disable IOMMUs before PCI relocation and CSM init */ if (gConfig.iommu_disable) iommu_disable(); /* Prepare APIC for legacy BIOS operation (disable or configure for ExtINT) */ apic_prepare_for_legacy(); pci_late_initialize(); build_coreboot_table(&priv); build_e820_map(&priv, efi_mmap, efi_mmap_size, efi_desc_size); uintptr_t e820_low = (uintptr_t)&priv.low_stub->e820_map; priv.csm_efi_table->E820Pointer = e820_low; priv.csm_efi_table->E820Length = sizeof(EFI_E820_ENTRY64) * priv.low_stub->e820_entries; /* Hand SeaBIOS the exact extra root bus numbers we discovered via * uACPI. Setting the pointer (even with count==0) signals authoritative * info; if discovery failed we leave the fields zero and SeaBIOS uses * its pre-extension default. */ if (pci_initialized) { size_t extra_root_count = pci_get_extra_root_buses( priv.low_stub->extra_pci_roots, EXTRA_PCI_ROOTS_MAX); priv.low_stub->extra_pci_roots_count = (uint8_t)extra_root_count; priv.csm_efi_table->ExtraPciRootListPointer = (uint32_t)(uintptr_t)&priv.low_stub->extra_pci_roots[0]; priv.csm_efi_table->ExtraPciRootListCount = (uint8_t)extra_root_count; printf("Reporting %zu extra PCI root bus(es) to SeaBIOS:", extra_root_count); for (size_t i = 0; i < extra_root_count; i++) printf(" %u", priv.low_stub->extra_pci_roots[i]); printf("\n"); } /* Disable 8259 PIC */ outb(0x21, 0xff); outb(0xa1, 0xff); outb(0x43, 0x36); /* Program PIT to default */ outb(0x40, 0x00); outb(0x40, 0x00); /* Copy ROM to location, as late as possible */ memcpy((void*)csm_bin_base, Csm16_bin, sizeof(Csm16_bin)); if (vbios_loc != NULL) { uintptr_t max_vbios_size = csm_bin_base - VGABIOS_START; if (vbios_size > max_vbios_size) { panic("VBIOS too large (%u bytes, max %u)\n", (unsigned)vbios_size, (unsigned)max_vbios_size); } memcpy((void*)VGABIOS_START, vbios_loc, vbios_size); } /* * Start the BIOS proxy helper core now that CSM is in its final location. * The helper core will handle BIOS calls when the main core is in V86 mode. */ if (bios_proxy_start_helper(csm_bin_base) != 0) { panic("Failed to start BIOS proxy helper core\n"); } /* Disable flanterm after last potential panic point - SeaBIOS will take over video */ flanterm_ctx = NULL; memset(&Regs, 0, sizeof(EFI_IA32_REGISTER_SET)); Regs.X.AX = Legacy16InitializeYourself; Regs.X.ES = EFI_SEGMENT(&priv.low_stub->init_table); Regs.X.BX = EFI_OFFSET(&priv.low_stub->init_table); LegacyBiosFarCall86(priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); if (priv.vga_pci_io != NULL) { pci_enable_for_oprom(priv.vga_pci_bus, priv.vga_pci_devfn); } memset(&Regs, 0, sizeof(EFI_IA32_REGISTER_SET)); Regs.X.AX = Legacy16DispatchOprom; Regs.X.ES = EFI_SEGMENT(&priv.low_stub->vga_oprom_table); Regs.X.BX = EFI_OFFSET(&priv.low_stub->vga_oprom_table); LegacyBiosFarCall86(priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); /* Dispatch non-VGA option ROMs (storage, network, etc.) */ oprom_dispatch_all(&priv, &oprom_list); memset(&Regs, 0, sizeof(EFI_IA32_REGISTER_SET)); Regs.X.AX = Legacy16UpdateBbs; Regs.X.ES = EFI_SEGMENT(&priv.low_stub->boot_table); Regs.X.BX = EFI_OFFSET(&priv.low_stub->boot_table); LegacyBiosFarCall86(priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); memset(&Regs, 0, sizeof(EFI_IA32_REGISTER_SET)); Regs.X.AX = Legacy16PrepareToBoot; Regs.X.ES = EFI_SEGMENT(&priv.low_stub->boot_table); Regs.X.BX = EFI_OFFSET(&priv.low_stub->boot_table); LegacyBiosFarCall86(priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); memset(&Regs, 0, sizeof(EFI_IA32_REGISTER_SET)); Regs.X.AX = Legacy16Boot; // No arguments? LegacyBiosFarCall86(priv.csm_efi_table->Compatibility16CallSegment, priv.csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); return 0; } ================================================ FILE: src/csmwrap.h ================================================ #ifndef _CSM_WRAP_H #define _CSM_WRAP_H #include #include #include #include #include #include #include #include #include extern EFI_SYSTEM_TABLE *gST; extern EFI_BOOT_SERVICES *gBS; extern EFI_RUNTIME_SERVICES *gRT; extern EFI_TIME gTimeAtBoot; extern bool gBootServicesExited; enum csmwrap_video_type { CSMWRAP_VIDEO_NONE, CSMWRAP_VIDEO_OPROM, CSMWRAP_VIDEO_SEAVGABIOS, }; struct csmwrap_priv { uint8_t *csm_bin; EFI_COMPATIBILITY16_TABLE *csm_efi_table; uintptr_t csm_bin_base; struct low_stub *low_stub; /* VGA stuff */ enum csmwrap_video_type video_type; EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; EFI_HANDLE gop_handle; EFI_PCI_IO_PROTOCOL *vga_pci_io; uint8_t vga_pci_bus; uint8_t vga_pci_devfn; uint16_t vga_vendor_id; uint16_t vga_device_id; struct cb_framebuffer cb_fb; }; extern struct csmwrap_priv priv; extern int unlock_bios_region(); extern int build_coreboot_table(struct csmwrap_priv *priv); bool acpi_init(struct csmwrap_priv *priv); bool acpi_namespace_init(void); int build_e820_map(struct csmwrap_priv *priv, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN memory_map_size, UINTN descriptor_size); int apply_intel_platform_workarounds(void); void __attribute__((noreturn)) panic(const char *fmt, ...); static inline int efi_guidcmp (EFI_GUID left, EFI_GUID right) { return memcmp(&left, &right, sizeof (EFI_GUID)); } #define E820_MAX_ENTRIES 128 #define MAX_BBS_ENTRIES 32 #define BBS_DESC_STRING_SIZE 32 #define EXTRA_PCI_ROOTS_MAX 255 #pragma pack(1) struct low_stub { LOW_MEMORY_THUNK thunk; EFI_TO_COMPATIBILITY16_INIT_TABLE init_table; EFI_TO_COMPATIBILITY16_BOOT_TABLE boot_table; EFI_DISPATCH_OPROM_TABLE vga_oprom_table; EFI_DISPATCH_OPROM_TABLE oprom_table; /* Reused for each non-VGA oprom dispatch */ /* E820 memory map */ int e820_entries; EFI_E820_ENTRY64 e820_map[E820_MAX_ENTRIES]; /* BBS table for boot device priority */ size_t bbs_entry_count; BBS_TABLE bbs_entries[MAX_BBS_ENTRIES]; char bbs_desc_strings[MAX_BBS_ENTRIES][BBS_DESC_STRING_SIZE]; /* Extra (non-zero) PCI root bus numbers, exposed to SeaBIOS so it can * skip its brute-force scan past MaxPCIBus. */ uint8_t extra_pci_roots[EXTRA_PCI_ROOTS_MAX]; uint8_t extra_pci_roots_count; }; #pragma pack() /* Memory map information */ /* In low memory */ #define CB_TABLE_START 0x00000500 #define CONVEN_START 0x00007E00 /* We may have some stack here */ #define LOW_STUB_BASE 0x00020000 /* * Conventional memory ends at 640KB (0xA0000) - EBDA size. * The 1KB initial EBDA matches SeaBIOS's EBDA_SIZE_START on entry; SeaBIOS * may grow the EBDA downward during option ROM dispatch and will update its * own e820 accordingly, so this constant only describes the starting layout. * The PMM (Post Memory Manager) area is between low_stub and CONVEN_END. */ #define CONVEN_END 0x0009FC00 #define EBDA_BASE CONVEN_END #define VGABIOS_START 0x000C0000 #define VGABIOS_END 0x000C8000 #define BIOSROM_START VGABIOS_END #define BIOSROM_END 0x00100000 /* End of low 1MiB */ #define HIPMM_SIZE 0x400000 /* Allocated on runtime, can be anywhere in 32bit */ #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #endif #ifdef ALIGN # undef ALIGN #endif #define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) #define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) #define ALIGN_UP(x, a) ALIGN((x), (a)) #define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) #define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) #ifdef ACCESS_PAGE0_CODE # undef ACCESS_PAGE0_CODE #endif #define ACCESS_PAGE0_CODE(statements) \ do { \ statements; \ \ } while (FALSE) #endif ================================================ FILE: src/e820.c ================================================ #include #include #include "csmwrap.h" #include "io.h" /* This is not in E820.h */ #define EfiAcpiAddressRangeHole (-1ULL) static const char * e820_type_name(uint32_t type) { switch (type) { case EfiAcpiAddressRangeMemory: return "RAM"; case EfiAcpiAddressRangeReserved: return "RESERVED"; case EfiAcpiAddressRangeACPI: return "ACPI"; case EfiAcpiAddressRangeNVS: return "NVS"; default: return "UNKNOWN"; } } // Remove an entry from the e820_map. static void remove_e820(struct csmwrap_priv *priv, int i) { EFI_E820_ENTRY64 *e820_map = priv->low_stub->e820_map; int *e820_count = &priv->low_stub->e820_entries; if (i < 0 || i >= *e820_count) { printf("e820_map remove index out of range\n"); return; } (*e820_count)--; memmove(&e820_map[i], &e820_map[i+1], sizeof(EFI_E820_ENTRY64) * (*e820_count - i)); } // Insert an entry in the e820_map at the given position. static void insert_e820(struct csmwrap_priv *priv, int i, uint64_t start, uint64_t size, uint64_t type) { EFI_E820_ENTRY64 *e820_map = priv->low_stub->e820_map; int *e820_count = &priv->low_stub->e820_entries; if (*e820_count >= E820_MAX_ENTRIES) { printf("e820_map overflow\n"); return; } memmove(&e820_map[i + 1], &e820_map[i], sizeof(EFI_E820_ENTRY64) * (*e820_count - i)); (*e820_count)++; EFI_E820_ENTRY64 *e = &e820_map[i]; e->BaseAddr = start; e->Length = size; e->Type = type; } // Show the current e820_map. static void dump_map(struct csmwrap_priv *priv) { EFI_E820_ENTRY64 *e820_map = priv->low_stub->e820_map; int e820_count = priv->low_stub->e820_entries; printf("csmwrap e820 map has %d items:\n", e820_count); int i; for (i = 0; i < e820_count; i++) { EFI_E820_ENTRY64 *e = &e820_map[i]; uint64_t e_end = e->BaseAddr + e->Length; printf(" %d: %016llx - %016llx = %d %s\n", i, e->BaseAddr, e_end, e->Type, e820_type_name(e->Type)); } } static const char * efi_memory_type_name(uint32_t type) { switch (type) { case EfiReservedMemoryType: return "Reserved"; case EfiLoaderCode: return "LoaderCode"; case EfiLoaderData: return "LoaderData"; case EfiBootServicesCode: return "BSCode"; case EfiBootServicesData: return "BSData"; case EfiRuntimeServicesCode: return "RTCode"; case EfiRuntimeServicesData: return "RTData"; case EfiConventionalMemory: return "Conventional"; case EfiUnusableMemory: return "Unusable"; case EfiACPIReclaimMemory: return "ACPIReclaim"; case EfiACPIMemoryNVS: return "ACPINVS"; case EfiMemoryMappedIO: return "MMIO"; case EfiMemoryMappedIOPortSpace: return "MMIOPort"; case EfiPalCode: return "PalCode"; case EfiPersistentMemory: return "Persistent"; case EfiUnacceptedMemoryType: return "Unaccepted"; default: return "UNKNOWN"; } } // Show the raw UEFI memory map that build_e820_map() consumes. static void dump_efi_memory_map(EFI_MEMORY_DESCRIPTOR *memory_map, UINTN memory_map_size, UINTN descriptor_size) { EFI_MEMORY_DESCRIPTOR *end = (EFI_MEMORY_DESCRIPTOR *) ((uint8_t *)memory_map + memory_map_size); int count = descriptor_size ? (int)(memory_map_size / descriptor_size) : 0; printf("EFI memory map has %d entries (descriptor_size=%u):\n", count, (unsigned)descriptor_size); int i = 0; for (EFI_MEMORY_DESCRIPTOR *d = memory_map; d < end; d = NextMemoryDescriptor(d, descriptor_size), i++) { uint64_t bytes = d->NumberOfPages * EFI_PAGE_SIZE; uint64_t end_addr = d->PhysicalStart + bytes; printf(" %3d: %016llx - %016llx (%6llu pages) %2u %-13s attr=%016llx%s\n", i, d->PhysicalStart, end_addr, (unsigned long long)d->NumberOfPages, d->Type, efi_memory_type_name(d->Type), (unsigned long long)d->Attribute, (d->Attribute & EFI_MEMORY_RUNTIME) ? " RT" : ""); } } void e820_add(struct csmwrap_priv *priv, uint64_t start, uint64_t size, uint64_t type) { EFI_E820_ENTRY64 *e820_map = priv->low_stub->e820_map; int *e820_count = &priv->low_stub->e820_entries; if (!size) return; // Find position of new item (splitting existing item if needed). uint64_t end = start + size; int i; for (i = 0; i < *e820_count; i++) { EFI_E820_ENTRY64 *e = &e820_map[i]; uint64_t e_end = e->BaseAddr + e->Length; if (start > e_end) continue; // Found position - check if an existing item needs to be split. if (start > e->BaseAddr) { if (type == e->Type) { // Same type - merge them. size += start - e->BaseAddr; start = e->BaseAddr; } else { // Split existing item. e->Length = start - e->BaseAddr; i++; if (e_end > end) insert_e820(priv, i, end, e_end - end, e->Type); } } break; } // Remove/adjust existing items that are overlapping. while (i < *e820_count) { EFI_E820_ENTRY64 *e = &e820_map[i]; if (end < e->BaseAddr) // No overlap - done. break; uint64_t e_end = e->BaseAddr + e->Length; if (end >= e_end) { // Existing item completely overlapped - remove it. remove_e820(priv, i); continue; } // Not completely overlapped - adjust its start. e->BaseAddr = end; e->Length = e_end - end; if (type == e->Type) { // Same type - merge them. size += e->Length; remove_e820(priv, i); } break; } // Insert new item. if (type != EfiAcpiAddressRangeHole) insert_e820(priv, i, start, size, type); } // Remove any definitions in a memory range (make a memory hole). void e820_remove(struct csmwrap_priv *priv, uint64_t start, uint64_t size) { e820_add(priv, start, size, EfiAcpiAddressRangeHole); } /* * Convert UEFI memory types to E820 types * See https://uefi.org/sites/default/files/resources/ACPI_4_Errata_A.pdf Table 14-6 */ static uint32_t convert_memory_type(EFI_MEMORY_TYPE type) { switch (type) { case EfiConventionalMemory: case EfiLoaderCode: case EfiLoaderData: case EfiBootServicesCode: case EfiBootServicesData: return EfiAcpiAddressRangeMemory; case EfiACPIReclaimMemory: return EfiAcpiAddressRangeACPI; case EfiACPIMemoryNVS: return EfiAcpiAddressRangeNVS; case EfiUnusableMemory: case EfiReservedMemoryType: case EfiRuntimeServicesCode: case EfiRuntimeServicesData: case EfiMemoryMappedIO: case EfiMemoryMappedIOPortSpace: case EfiPalCode: default: return EfiAcpiAddressRangeReserved; } } static inline void cmos_write(uint8_t reg, uint8_t val) { outb(0x70, 0x80 | reg); outb(0x80, 0); outb(0x71, val); } /* * Write CMOS memory size registers to match the E820 map. * * UEFI firmware does not initialize legacy CMOS memory registers, leaving them * with garbage values. Some legacy software (notably Windows 95 setup) reads * CMOS directly to detect extended memory size, bypassing INT 15h and XMS. * * CMOS layout: * 0x15/0x16: Base memory in KB (should be 640) * 0x17/0x18: Total extended memory in KB, saturated to 65535 * 0x30/0x31: Total extended memory in KB, saturated to 65535 (mirror of 0x17/0x18) * 0x34/0x35: Extended memory above 16MB, in 64KB blocks (max 65535) * 0x5B/0x5C/0x5D: Extended memory above 4GB, in 64KB blocks (24-bit, max 0xFFFFFF) */ static void e820_update_cmos(struct csmwrap_priv *priv) { EFI_E820_ENTRY64 *e820_map = priv->low_stub->e820_map; int e820_count = priv->low_stub->e820_entries; /* Find end of contiguous RAM starting from 1MB */ uint64_t ram_end = 0x100000; int progress = 1; while (progress) { progress = 0; for (int i = 0; i < e820_count; i++) { EFI_E820_ENTRY64 *e = &e820_map[i]; uint64_t e_end = e->BaseAddr + e->Length; if (e->Type != EfiAcpiAddressRangeMemory && e->Type != EfiAcpiAddressRangeACPI) continue; if (e_end > 0xFFFFFFFFULL) continue; if (e->BaseAddr <= ram_end && e_end > ram_end) { ram_end = e_end; progress = 1; } } } uint64_t ext_kb = (ram_end > 0x100000) ? (ram_end - 0x100000) / 1024 : 0; uint64_t above_16m_64k = (ram_end > 0x1000000) ? (ram_end - 0x1000000) / 65536 : 0; /* Find end of contiguous RAM starting from 4GB */ uint64_t high_ram_end = 0x100000000ULL; progress = 1; while (progress) { progress = 0; for (int i = 0; i < e820_count; i++) { EFI_E820_ENTRY64 *e = &e820_map[i]; uint64_t e_end = e->BaseAddr + e->Length; if (e->Type != EfiAcpiAddressRangeMemory && e->Type != EfiAcpiAddressRangeACPI) continue; if (e->BaseAddr <= high_ram_end && e_end > high_ram_end) { high_ram_end = e_end; progress = 1; } } } uint64_t above_4g_64k = (high_ram_end > 0x100000000ULL) ? (high_ram_end - 0x100000000ULL) / 65536 : 0; /* Cap to register widths */ uint16_t cmos_17_18 = (ext_kb > 65535) ? 65535 : (uint16_t)ext_kb; uint16_t cmos_30_31 = (ext_kb > 65535) ? 65535 : (uint16_t)ext_kb; uint16_t cmos_34_35 = (above_16m_64k > 65535) ? 65535 : (uint16_t)above_16m_64k; uint32_t cmos_5b_5d = (above_4g_64k > 0xFFFFFF) ? 0xFFFFFF : (uint32_t)above_4g_64k; printf("CMOS: base=640 ext=%u KB >16M=%u x64KB >4G=%u x64KB (ram_end=0x%llx high_end=0x%llx)\n", cmos_30_31, cmos_34_35, cmos_5b_5d, ram_end, high_ram_end); /* Base memory: 640 KB */ cmos_write(0x15, 640 & 0xFF); cmos_write(0x16, 640 >> 8); /* Extended memory 1-16MB range in KB */ cmos_write(0x17, cmos_17_18 & 0xFF); cmos_write(0x18, cmos_17_18 >> 8); /* Extended memory 1-64MB range in KB */ cmos_write(0x30, cmos_30_31 & 0xFF); cmos_write(0x31, cmos_30_31 >> 8); /* Extended memory above 16MB in 64KB blocks */ cmos_write(0x34, cmos_34_35 & 0xFF); cmos_write(0x35, cmos_34_35 >> 8); /* Extended memory above 4GB in 64KB blocks (24-bit) */ cmos_write(0x5B, cmos_5b_5d & 0xFF); cmos_write(0x5C, (cmos_5b_5d >> 8) & 0xFF); cmos_write(0x5D, (cmos_5b_5d >> 16) & 0xFF); /* Bit 7 of port 0x70 is the chipset NMI mask; clear it so we don't * hand off to legacy BIOS with NMI delivery gated. */ outb(0x70, 0x0D); inb(0x71); /* complete the CMOS access cycle */ } /* * Build E820 memory map based on UEFI GetMemoryMap * Return the number of entries in the E820 map */ int build_e820_map(struct csmwrap_priv *priv, EFI_MEMORY_DESCRIPTOR *memory_map, UINTN memory_map_size, UINTN descriptor_size) { EFI_MEMORY_DESCRIPTOR *memory_map_end; EFI_MEMORY_DESCRIPTOR *memory_map_ptr; memory_map_end = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)memory_map + memory_map_size); dump_efi_memory_map(memory_map, memory_map_size, descriptor_size); /* Process each memory descriptor and convert to E820 format */ for (memory_map_ptr = memory_map; memory_map_ptr < memory_map_end; memory_map_ptr = NextMemoryDescriptor(memory_map_ptr, descriptor_size)) { uint64_t start = memory_map_ptr->PhysicalStart; uint64_t end = start + (memory_map_ptr->NumberOfPages * EFI_PAGE_SIZE); uint32_t type = convert_memory_type(memory_map_ptr->Type); /* Skip zero-length regions */ if (start == end) continue; e820_add(priv, start, end - start, type); } /* Remove whole 1MB, we are going to fix it later */ e820_remove(priv, 0, 0x100000); /* * Reproduce SeaBIOS's initial low-memory layout: 639KB usable + 1KB EBDA. * SeaBIOS recomputes its own e820 from endlow/ebda_seg during init and * may grow the EBDA further (option ROMs allocating BBS/ATA/MPT space), * so this map is a starting snapshot, not the final OS-visible map. * Reporting only 512KB here previously confused HIMEM.SYS / EMM386. */ e820_add(priv, 0, 0x9FC00, EfiAcpiAddressRangeMemory); e820_add(priv, 0x9FC00, 0x400, EfiAcpiAddressRangeReserved); /* Reserve Expansion BIOS (video RAM, option ROMs, system ROM) */ e820_add(priv, 0xa0000, 0x100000 - 0xa0000, EfiAcpiAddressRangeReserved); dump_map(priv); e820_update_cmos(priv); return 0; } ================================================ FILE: src/edk2/Acpi.h ================================================ /** @file This file contains the latest ACPI definitions that are consumed by drivers that do not care about ACPI versions. Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
Copyright (c) 2019 - 2021, ARM Ltd. All rights reserved.
Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_H_ #define _ACPI_H_ #include "Acpi65.h" #endif ================================================ FILE: src/edk2/Acpi10.h ================================================ /** @file ACPI 1.0b definitions from the ACPI Specification, revision 1.0b Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2020, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_1_0_H_ #define _ACPI_1_0_H_ #include "Edk2Compat.h" #include "AcpiAml.h" /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure. /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_COMMON_HEADER; #pragma pack(1) /// /// The common ACPI description table header. This structure prefaces most ACPI tables. /// typedef struct { UINT32 Signature; UINT32 Length; UINT8 Revision; UINT8 Checksum; UINT8 OemId[6]; UINT64 OemTableId; UINT32 OemRevision; UINT32 CreatorId; UINT32 CreatorRevision; } EFI_ACPI_DESCRIPTION_HEADER; #pragma pack() // // Define for Descriptor // #define ACPI_SMALL_ITEM_FLAG 0x00 #define ACPI_LARGE_ITEM_FLAG 0x01 // // Small Item Descriptor Name // #define ACPI_SMALL_IRQ_DESCRIPTOR_NAME 0x04 #define ACPI_SMALL_DMA_DESCRIPTOR_NAME 0x05 #define ACPI_SMALL_START_DEPENDENT_DESCRIPTOR_NAME 0x06 #define ACPI_SMALL_END_DEPENDENT_DESCRIPTOR_NAME 0x07 #define ACPI_SMALL_IO_PORT_DESCRIPTOR_NAME 0x08 #define ACPI_SMALL_FIXED_IO_PORT_DESCRIPTOR_NAME 0x09 #define ACPI_SMALL_VENDOR_DEFINED_DESCRIPTOR_NAME 0x0E #define ACPI_SMALL_END_TAG_DESCRIPTOR_NAME 0x0F // // Large Item Descriptor Name // #define ACPI_LARGE_24_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x01 #define ACPI_LARGE_VENDOR_DEFINED_DESCRIPTOR_NAME 0x04 #define ACPI_LARGE_32_BIT_MEMORY_RANGE_DESCRIPTOR_NAME 0x05 #define ACPI_LARGE_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR_NAME 0x06 #define ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x07 #define ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x08 #define ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME 0x09 #define ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME 0x0A // // Small Item Descriptor Value // #define ACPI_IRQ_NOFLAG_DESCRIPTOR 0x22 #define ACPI_IRQ_DESCRIPTOR 0x23 #define ACPI_DMA_DESCRIPTOR 0x2A #define ACPI_START_DEPENDENT_DESCRIPTOR 0x30 #define ACPI_START_DEPENDENT_EX_DESCRIPTOR 0x31 #define ACPI_END_DEPENDENT_DESCRIPTOR 0x38 #define ACPI_IO_PORT_DESCRIPTOR 0x47 #define ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR 0x4B #define ACPI_END_TAG_DESCRIPTOR 0x79 // // Large Item Descriptor Value // #define ACPI_24_BIT_MEMORY_RANGE_DESCRIPTOR 0x81 #define ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR 0x85 #define ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR 0x86 #define ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR 0x87 #define ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR 0x88 #define ACPI_EXTENDED_INTERRUPT_DESCRIPTOR 0x89 #define ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR 0x8A #define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A // // Resource Type // #define ACPI_ADDRESS_SPACE_TYPE_MEM 0x00 #define ACPI_ADDRESS_SPACE_TYPE_IO 0x01 #define ACPI_ADDRESS_SPACE_TYPE_BUS 0x02 /// /// Power Management Timer frequency is fixed at 3.579545MHz. /// #define ACPI_TIMER_FREQUENCY 3579545 // // Ensure proper structure formats // #pragma pack(1) /// /// The common definition of QWORD, DWORD, and WORD /// Address Space Descriptors. /// typedef PACKED struct { UINT8 Desc; UINT16 Len; UINT8 ResType; UINT8 GenFlag; UINT8 SpecificFlag; UINT64 AddrSpaceGranularity; UINT64 AddrRangeMin; UINT64 AddrRangeMax; UINT64 AddrTranslationOffset; UINT64 AddrLen; } EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR; typedef PACKED union { UINT8 Byte; PACKED struct { UINT8 Length : 3; UINT8 Name : 4; UINT8 Type : 1; } Bits; } ACPI_SMALL_RESOURCE_HEADER; typedef PACKED struct { PACKED union { UINT8 Byte; PACKED struct { UINT8 Name : 7; UINT8 Type : 1; } Bits; } Header; UINT16 Length; } ACPI_LARGE_RESOURCE_HEADER; /// /// IRQ Descriptor. /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT16 Mask; } EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR; /// /// IRQ Descriptor. /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT16 Mask; UINT8 Information; } EFI_ACPI_IRQ_DESCRIPTOR; /// /// DMA Descriptor. /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT8 ChannelMask; UINT8 Information; } EFI_ACPI_DMA_DESCRIPTOR; /// /// I/O Port Descriptor /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT8 Information; UINT16 BaseAddressMin; UINT16 BaseAddressMax; UINT8 Alignment; UINT8 Length; } EFI_ACPI_IO_PORT_DESCRIPTOR; /// /// Fixed Location I/O Port Descriptor. /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT16 BaseAddress; UINT8 Length; } EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR; /// /// 24-Bit Memory Range Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 Information; UINT16 BaseAddressMin; UINT16 BaseAddressMax; UINT16 Alignment; UINT16 Length; } EFI_ACPI_24_BIT_MEMORY_RANGE_DESCRIPTOR; /// /// 32-Bit Memory Range Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 Information; UINT32 BaseAddressMin; UINT32 BaseAddressMax; UINT32 Alignment; UINT32 Length; } EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR; /// /// Fixed 32-Bit Fixed Memory Range Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 Information; UINT32 BaseAddress; UINT32 Length; } EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR; /// /// QWORD Address Space Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 ResType; UINT8 GenFlag; UINT8 SpecificFlag; UINT64 AddrSpaceGranularity; UINT64 AddrRangeMin; UINT64 AddrRangeMax; UINT64 AddrTranslationOffset; UINT64 AddrLen; } EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR; /// /// DWORD Address Space Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 ResType; UINT8 GenFlag; UINT8 SpecificFlag; UINT32 AddrSpaceGranularity; UINT32 AddrRangeMin; UINT32 AddrRangeMax; UINT32 AddrTranslationOffset; UINT32 AddrLen; } EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR; /// /// WORD Address Space Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 ResType; UINT8 GenFlag; UINT8 SpecificFlag; UINT16 AddrSpaceGranularity; UINT16 AddrRangeMin; UINT16 AddrRangeMax; UINT16 AddrTranslationOffset; UINT16 AddrLen; } EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR; /// /// Extended Interrupt Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 InterruptVectorFlags; UINT8 InterruptTableLength; UINT32 InterruptNumber[1]; } EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR; #pragma pack() /// /// The End tag identifies an end of resource data. /// typedef struct { UINT8 Desc; UINT8 Checksum; } EFI_ACPI_END_TAG_DESCRIPTOR; // // General use definitions // #define EFI_ACPI_RESERVED_BYTE 0x00 #define EFI_ACPI_RESERVED_WORD 0x0000 #define EFI_ACPI_RESERVED_DWORD 0x00000000 #define EFI_ACPI_RESERVED_QWORD 0x0000000000000000 // // Resource Type Specific Flags // Ref ACPI specification 6.4.3.5.5 // // Bit [0] : Write Status, _RW // #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_WRITE (1 << 0) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_ONLY (0 << 0) // // Bit [2:1] : Memory Attributes, _MEM // #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE (0 << 1) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE (1 << 1) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_WRITE_COMBINING (2 << 1) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE (3 << 1) // // Bit [4:3] : Memory Attributes, _MTP // #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_MEMORY (0 << 3) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_RESERVED (1 << 3) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_ACPI (2 << 3) #define EFI_APCI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_NVS (3 << 3) // // Bit [5] : Memory to I/O Translation, _TTP // #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_TRANSLATION (1 << 5) #define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_STATIC (0 << 5) // // IRQ Information // Ref ACPI specification 6.4.2.1 // #define EFI_ACPI_IRQ_SHARABLE_MASK 0x10 #define EFI_ACPI_IRQ_SHARABLE 0x10 #define EFI_ACPI_IRQ_POLARITY_MASK 0x08 #define EFI_ACPI_IRQ_HIGH_TRUE 0x00 #define EFI_ACPI_IRQ_LOW_FALSE 0x08 #define EFI_ACPI_IRQ_MODE 0x01 #define EFI_ACPI_IRQ_LEVEL_TRIGGERED 0x00 #define EFI_ACPI_IRQ_EDGE_TRIGGERED 0x01 // // DMA Information // Ref ACPI specification 6.4.2.2 // #define EFI_ACPI_DMA_SPEED_TYPE_MASK 0x60 #define EFI_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 #define EFI_ACPI_DMA_SPEED_TYPE_A 0x20 #define EFI_ACPI_DMA_SPEED_TYPE_B 0x40 #define EFI_ACPI_DMA_SPEED_TYPE_F 0x60 #define EFI_ACPI_DMA_BUS_MASTER_MASK 0x04 #define EFI_ACPI_DMA_BUS_MASTER 0x04 #define EFI_ACPI_DMA_TRANSFER_TYPE_MASK 0x03 #define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x00 #define EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x01 #define EFI_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x02 // // IO Information // Ref ACPI specification 6.4.2.5 // #define EFI_ACPI_IO_DECODE_MASK 0x01 #define EFI_ACPI_IO_DECODE_16_BIT 0x01 #define EFI_ACPI_IO_DECODE_10_BIT 0x00 // // Memory Information // Ref ACPI specification 6.4.3.4 // #define EFI_ACPI_MEMORY_WRITE_STATUS_MASK 0x01 #define EFI_ACPI_MEMORY_WRITABLE 0x01 #define EFI_ACPI_MEMORY_NON_WRITABLE 0x00 // // Interrupt Vector Flags definitions for Extended Interrupt Descriptor // Ref ACPI specification 6.4.3.6 // #define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK BIT0 #define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK BIT1 #define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK BIT2 #define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK BIT3 #define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK BIT4 // // Ensure proper structure formats // #pragma pack(1) // // ACPI 1.0b table structures // /// /// Root System Description Pointer Structure. /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Reserved; UINT32 RsdtAddress; } EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 1.0b specification). /// #define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT). /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 IntModel; UINT8 Reserved1; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 Reserved2; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 Reserved3; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT8 Reserved4; UINT8 Reserved5; UINT8 Reserved6; UINT32 Flags; } EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 1.0b specification). /// #define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x01 #define EFI_ACPI_1_0_INT_MODE_DUAL_PIC 0 #define EFI_ACPI_1_0_INT_MODE_MULTIPLE_APIC 1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_1_0_WBINVD BIT0 #define EFI_ACPI_1_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_1_0_PROC_C1 BIT2 #define EFI_ACPI_1_0_P_LVL2_UP BIT3 #define EFI_ACPI_1_0_PWR_BUTTON BIT4 #define EFI_ACPI_1_0_SLP_BUTTON BIT5 #define EFI_ACPI_1_0_FIX_RTC BIT6 #define EFI_ACPI_1_0_RTC_S4 BIT7 #define EFI_ACPI_1_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_1_0_DCK_CAP BIT9 /// /// Firmware ACPI Control Structure. /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT8 Reserved[40]; } EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// Firmware Control Structure Feature Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_1_0_S4BIOS_F BIT0 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform-specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 1.0b specification). /// #define EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_1_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x05 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_1_0_IO_APIC 0x01 #define EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_1_0_LOCAL_APIC_NMI 0x04 // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition. /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_1_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure. /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 SystemVectorBase; } EFI_ACPI_1_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure. /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterruptVector; UINT16 Flags; } EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Non-Maskable Interrupt Source Structure. /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterruptVector; } EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure. /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicInti; } EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_1_0_SMART_BATTERY_DESCRIPTION_TABLE; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer. /// #define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table. /// #define EFI_ACPI_1_0_APIC_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "DSDT" Differentiated System Description Table. /// #define EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "FACS" Firmware ACPI Control Structure. /// #define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FACP" Fixed ACPI Description Table. /// #define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "PSDT" Persistent System Description Table. /// #define EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RSDT" Root System Description Table. /// #define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table. /// #define EFI_ACPI_1_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SSDT" Secondary System Description Table. /// #define EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi20.h ================================================ /** @file ACPI 2.0 definitions from the ACPI Specification, revision 2.0 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_2_0_H_ #define _ACPI_2_0_H_ #include "Acpi10.h" // // Define for Descriptor // #define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME 0x02 #define ACPI_GENERIC_REGISTER_DESCRIPTOR 0x82 // // Ensure proper structure formats // #pragma pack(1) /// /// Generic Register Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AddressSize; UINT64 RegisterAddress; } EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR; #pragma pack() // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 2.0 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 Reserved; UINT64 Address; } EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_2_0_SYSTEM_MEMORY 0 #define EFI_ACPI_2_0_SYSTEM_IO 1 #define EFI_ACPI_2_0_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_2_0_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_2_0_SMBUS 4 #define EFI_ACPI_2_0_FUNCTIONAL_FIXED_HARDWARE 0x7F // // ACPI 2.0 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_2_0_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT8 Reserved2[3]; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; } EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x03 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_2_0_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_2_0_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_2_0_PM_PROFILE_MOBILE 2 #define EFI_ACPI_2_0_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_2_0_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_2_0_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_2_0_PM_PROFILE_APPLIANCE_PC 6 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_2_0_LEGACY_DEVICES BIT0 #define EFI_ACPI_2_0_8042 BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_2_0_WBINVD BIT0 #define EFI_ACPI_2_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_2_0_PROC_C1 BIT2 #define EFI_ACPI_2_0_P_LVL2_UP BIT3 #define EFI_ACPI_2_0_PWR_BUTTON BIT4 #define EFI_ACPI_2_0_SLP_BUTTON BIT5 #define EFI_ACPI_2_0_FIX_RTC BIT6 #define EFI_ACPI_2_0_RTC_S4 BIT7 #define EFI_ACPI_2_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_2_0_DCK_CAP BIT9 #define EFI_ACPI_2_0_RESET_REG_SUP BIT10 #define EFI_ACPI_2_0_SEALED_CASE BIT11 #define EFI_ACPI_2_0_HEADLESS BIT12 #define EFI_ACPI_2_0_CPU_SW_SLP BIT13 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved[31]; } EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_2_0_S4BIOS_F BIT0 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_2_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x09 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_2_0_IO_APIC 0x01 #define EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_2_0_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_2_0_IO_SAPIC 0x06 #define EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC 0x07 #define EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES 0x08 // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_2_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_2_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_2_0_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; } EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 Reserved; } EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 2.0 spec.) /// #define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "SPIC" Multiple SAPIC Description Table /// /// BUGBUG: Don't know where this came from except SR870BN4 uses it. /// #define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495053 /// #define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_2_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "DBGP" MS Bebug Port Spec /// #define EFI_ACPI_2_0_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_2_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_2_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_2_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SRAT" Static Resource Affinity Table /// #define EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_2_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_2_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi30.h ================================================ /** @file ACPI 3.0 definitions from the ACPI Specification Revision 3.0b October 10, 2006 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_3_0_H_ #define _ACPI_3_0_H_ #include "Acpi20.h" /// /// _CSD Revision for ACPI 3.0 /// #define EFI_ACPI_3_0_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 3.0 /// #define EFI_ACPI_3_0_AML_CSD_NUM_ENTRIES 6 // // Define for Descriptor // #define ACPI_LARGE_EXTENDED_ADDRESS_SPACE_DESCRIPTOR_NAME 0x0B #define ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR 0x8B /// /// C-state Coordination Types /// See s8.4.2.2 _CSD (C-State Dependency) /// #define ACPI_AML_COORD_TYPE_SW_ALL 0xFC #define ACPI_AML_COORD_TYPE_SW_ANY 0xFD #define ACPI_AML_COORD_TYPE_HW_ALL 0xFE /// /// _PSD Revision for ACPI 3.0 // See s8.4.4.5 _PSD (P-State Dependency) /// #define EFI_ACPI_3_0_AML_PSD_REVISION 0 // // Ensure proper structure formats // #pragma pack(1) /// /// Extended Address Space Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 ResType; UINT8 GenFlag; UINT8 SpecificFlag; UINT8 RevisionId; UINT8 Reserved; UINT64 AddrSpaceGranularity; UINT64 AddrRangeMin; UINT64 AddrRangeMax; UINT64 AddrTranslationOffset; UINT64 AddrLen; UINT64 TypeSpecificAttribute; } EFI_ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR; #pragma pack() // // Memory Type Specific Flags // #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_UC 0x0000000000000001 #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WC 0x0000000000000002 #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WT 0x0000000000000004 #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WB 0x0000000000000008 #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_UCE 0x0000000000000010 #define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_NV 0x0000000000008000 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 3.0 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_3_0_SYSTEM_MEMORY 0 #define EFI_ACPI_3_0_SYSTEM_IO 1 #define EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_3_0_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_3_0_SMBUS 4 #define EFI_ACPI_3_0_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_3_0_UNDEFINED 0 #define EFI_ACPI_3_0_BYTE 1 #define EFI_ACPI_3_0_WORD 2 #define EFI_ACPI_3_0_DWORD 3 #define EFI_ACPI_3_0_QWORD 4 // // ACPI 3.0 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 3.0b spec.) /// #define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 3.0b) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_3_0_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT8 Reserved2[3]; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; } EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x04 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_3_0_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_3_0_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_3_0_PM_PROFILE_MOBILE 2 #define EFI_ACPI_3_0_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_3_0_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_3_0_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_3_0_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_3_0_PM_PROFILE_PERFORMANCE_SERVER 7 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_3_0_LEGACY_DEVICES BIT0 #define EFI_ACPI_3_0_8042 BIT1 #define EFI_ACPI_3_0_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_3_0_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_3_0_PCIE_ASPM_CONTROLS BIT4 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_3_0_WBINVD BIT0 #define EFI_ACPI_3_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_3_0_PROC_C1 BIT2 #define EFI_ACPI_3_0_P_LVL2_UP BIT3 #define EFI_ACPI_3_0_PWR_BUTTON BIT4 #define EFI_ACPI_3_0_SLP_BUTTON BIT5 #define EFI_ACPI_3_0_FIX_RTC BIT6 #define EFI_ACPI_3_0_RTC_S4 BIT7 #define EFI_ACPI_3_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_3_0_DCK_CAP BIT9 #define EFI_ACPI_3_0_RESET_REG_SUP BIT10 #define EFI_ACPI_3_0_SEALED_CASE BIT11 #define EFI_ACPI_3_0_HEADLESS BIT12 #define EFI_ACPI_3_0_CPU_SW_SLP BIT13 #define EFI_ACPI_3_0_PCI_EXP_WAK BIT14 #define EFI_ACPI_3_0_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_3_0_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_3_0_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_3_0_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved[31]; } EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_3_0_S4BIOS_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_3_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x09 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_3_0_IO_APIC 0x01 #define EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_3_0_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_3_0_IO_SAPIC 0x06 #define EFI_ACPI_3_0_LOCAL_SAPIC 0x07 #define EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES 0x08 // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_3_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_3_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_3_0_POLARITY (3 << 0) #define EFI_ACPI_3_0_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_3_0_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_3_0_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x02 // // SRAT structure types. // All other values between 0x02 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_3_0_MEMORY_AFFINITY 0x01 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT8 Reserved[4]; } EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_3_0_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_3_0_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_3_0_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_3_0_MEMORY_NONVOLATILE (1 << 2) /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 3.0 spec.) /// #define EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_3_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_3_0_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WSPT" Windows Specific Properties Table /// #define EFI_ACPI_3_0_WINDOWS_SPECIFIC_PROPERTIES_TABLE_SIGNATURE SIGNATURE_32('W', 'S', 'P', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi40.h ================================================ /** @file ACPI 4.0 definitions from the ACPI Specification Revision 4.0a April 5, 2010 Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_4_0_H_ #define _ACPI_4_0_H_ #include "Acpi30.h" /// /// _CSD Revision for ACPI 4.0 /// #define EFI_ACPI_4_0_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 4.0 /// #define EFI_ACPI_4_0_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 4.0 /// #define EFI_ACPI_4_0_AML_PSD_REVISION 0 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 4.0 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_4_0_SYSTEM_MEMORY 0 #define EFI_ACPI_4_0_SYSTEM_IO 1 #define EFI_ACPI_4_0_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_4_0_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_4_0_SMBUS 4 #define EFI_ACPI_4_0_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_4_0_UNDEFINED 0 #define EFI_ACPI_4_0_BYTE 1 #define EFI_ACPI_4_0_WORD 2 #define EFI_ACPI_4_0_DWORD 3 #define EFI_ACPI_4_0_QWORD 4 // // ACPI 4.0 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 4.0b spec.) /// #define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 4.0a) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_4_0_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT8 Reserved2[3]; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; } EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x04 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_4_0_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_4_0_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_4_0_PM_PROFILE_MOBILE 2 #define EFI_ACPI_4_0_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_4_0_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_4_0_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_4_0_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_4_0_PM_PROFILE_PERFORMANCE_SERVER 7 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_4_0_LEGACY_DEVICES BIT0 #define EFI_ACPI_4_0_8042 BIT1 #define EFI_ACPI_4_0_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_4_0_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_4_0_PCIE_ASPM_CONTROLS BIT4 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_4_0_WBINVD BIT0 #define EFI_ACPI_4_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_4_0_PROC_C1 BIT2 #define EFI_ACPI_4_0_P_LVL2_UP BIT3 #define EFI_ACPI_4_0_PWR_BUTTON BIT4 #define EFI_ACPI_4_0_SLP_BUTTON BIT5 #define EFI_ACPI_4_0_FIX_RTC BIT6 #define EFI_ACPI_4_0_RTC_S4 BIT7 #define EFI_ACPI_4_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_4_0_DCK_CAP BIT9 #define EFI_ACPI_4_0_RESET_REG_SUP BIT10 #define EFI_ACPI_4_0_SEALED_CASE BIT11 #define EFI_ACPI_4_0_HEADLESS BIT12 #define EFI_ACPI_4_0_CPU_SW_SLP BIT13 #define EFI_ACPI_4_0_PCI_EXP_WAK BIT14 #define EFI_ACPI_4_0_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_4_0_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_4_0_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_4_0_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_4_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_4_0_S4BIOS_F BIT0 #define EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_4_0_OSPM_64BIT_WAKE__F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_4_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_4_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0B an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_4_0_IO_APIC 0x01 #define EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_4_0_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_4_0_IO_SAPIC 0x06 #define EFI_ACPI_4_0_LOCAL_SAPIC 0x07 #define EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_4_0_LOCAL_X2APIC_NMI 0x0A // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_4_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_4_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_4_0_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_4_0_POLARITY (3 << 0) #define EFI_ACPI_4_0_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_4_0_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_4_0_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_4_0_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x03 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_4_0_MEMORY_AFFINITY 0x01 #define EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_4_0_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_4_0_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_4_0_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_4_0_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_4_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_4_0_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_4_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_4_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_4_0_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_4_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_4_0_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_4_0_ERROR_SEVERITY_CORRECTABLE 0x00 #define EFI_ACPI_4_0_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_4_0_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_4_0_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_4_0_ERROR_SEVERITY_NONE 0x03 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; } EFI_ACPI_4_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0201 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_4_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_4_0_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_4_0_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_4_0_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_4_0_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_4_0_GENERIC_HARDWARE_ERROR 0x09 // // Error Source structure flags. // #define EFI_ACPI_4_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_4_0_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_4_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_4_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_4_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_4_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_4_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_4_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_4_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_4_0_GENERIC_ERROR_STATUS_STRUCTURE; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_4_0_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_4_0_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_4_0_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_4_0_ERST_END_OPERATION 0x03 #define EFI_ACPI_4_0_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_4_0_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_4_0_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_4_0_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_4_0_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_4_0_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_4_0_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_4_0_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F /// /// ERST Action Command Status /// #define EFI_ACPI_4_0_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_4_0_EINJ_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_4_0_EINJ_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_4_0_EINJ_STATUS_FAILED 0x03 #define EFI_ACPI_4_0_EINJ_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_4_0_EINJ_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_4_0_ERST_READ_REGISTER 0x00 #define EFI_ACPI_4_0_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_4_0_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_4_0_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_4_0_ERST_NOOP 0x04 #define EFI_ACPI_4_0_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_4_0_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_4_0_ERST_STORE_VAR1 0x07 #define EFI_ACPI_4_0_ERST_ADD 0x08 #define EFI_ACPI_4_0_ERST_SUBTRACT 0x09 #define EFI_ACPI_4_0_ERST_ADD_VALUE 0x0A #define EFI_ACPI_4_0_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_4_0_ERST_STALL 0x0C #define EFI_ACPI_4_0_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_4_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_4_0_ERST_GOTO 0x0F #define EFI_ACPI_4_0_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_4_0_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_4_0_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_4_0_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_4_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_4_0_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 4.0 spec.) /// #define EFI_ACPI_4_0_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_4_0_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_4_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_4_0_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_4_0_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_4_0_EINJ_END_OPERATION 0x04 #define EFI_ACPI_4_0_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_4_0_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_4_0_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_4_0_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_4_0_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_4_0_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_4_0_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_4_0_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_4_0_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_4_0_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_4_0_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_4_0_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_4_0_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_4_0_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_4_0_EINJ_TRIGGER_ACTION_TABLE; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_4_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_4_0_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_4_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_4_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_4_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_4_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_4_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_4_0_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_4_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_4_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_4_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_4_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_4_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_4_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_4_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_4_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_4_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Enlightenment Table /// #define EFI_ACPI_4_0_WINDOWS_ACPI_ENLIGHTENMENT_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_4_0_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_4_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi50.h ================================================ /** @file ACPI 5.0 definitions from the ACPI Specification Revision 5.0a November 13, 2013. Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
Copyright (c) 2011 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2020, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_5_0_H_ #define _ACPI_5_0_H_ #include "Acpi40.h" /// /// _CSD Revision for ACPI 5.0 /// #define EFI_ACPI_5_0_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 5.0 /// #define EFI_ACPI_5_0_AML_CSD_NUM_ENTRIES 6 // // Define for Descriptor // #define ACPI_SMALL_FIXED_DMA_DESCRIPTOR_NAME 0x0A #define ACPI_LARGE_GPIO_CONNECTION_DESCRIPTOR_NAME 0x0C #define ACPI_LARGE_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR_NAME 0x0E #define ACPI_FIXED_DMA_DESCRIPTOR 0x55 #define ACPI_GPIO_CONNECTION_DESCRIPTOR 0x8C #define ACPI_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR 0x8E /// /// _PSD Revision for ACPI 5.0 /// #define EFI_ACPI_5_0_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 5.0 /// #define EFI_ACPI_5_0_AML_CPC_REVISION 1 #pragma pack(1) /// /// Generic DMA Descriptor. /// typedef PACKED struct { ACPI_SMALL_RESOURCE_HEADER Header; UINT16 DmaRequestLine; UINT16 DmaChannel; UINT8 DmaTransferWidth; } EFI_ACPI_FIXED_DMA_DESCRIPTOR; /// /// GPIO Connection Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT8 ConnectionType; UINT16 GeneralFlags; UINT16 InterruptFlags; UINT8 PinConfiguration; UINT16 OutputDriveStrength; UINT16 DebounceTimeout; UINT16 PinTableOffset; UINT8 ResourceSourceIndex; UINT16 ResourceSourceNameOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_GPIO_CONNECTION_DESCRIPTOR; #define EFI_ACPI_GPIO_CONNECTION_TYPE_INTERRUPT 0x0 #define EFI_ACPI_GPIO_CONNECTION_TYPE_IO 0x1 /// /// Serial Bus Resource Descriptor (Generic) /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT8 ResourceSourceIndex; UINT8 SerialBusType; UINT8 GeneralFlags; UINT16 TypeSpecificFlags; UINT8 TypeSpecificRevisionId; UINT16 TypeDataLength; // Type specific data } EFI_ACPI_SERIAL_BUS_RESOURCE_DESCRIPTOR; #define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_I2C 0x1 #define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_SPI 0x2 #define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_UART 0x3 /// /// Serial Bus Resource Descriptor (I2C) /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT8 ResourceSourceIndex; UINT8 SerialBusType; UINT8 GeneralFlags; UINT16 TypeSpecificFlags; UINT8 TypeSpecificRevisionId; UINT16 TypeDataLength; UINT32 ConnectionSpeed; UINT16 SlaveAddress; } EFI_ACPI_SERIAL_BUS_RESOURCE_I2C_DESCRIPTOR; /// /// Serial Bus Resource Descriptor (SPI) /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT8 ResourceSourceIndex; UINT8 SerialBusType; UINT8 GeneralFlags; UINT16 TypeSpecificFlags; UINT8 TypeSpecificRevisionId; UINT16 TypeDataLength; UINT32 ConnectionSpeed; UINT8 DataBitLength; UINT8 Phase; UINT8 Polarity; UINT16 DeviceSelection; } EFI_ACPI_SERIAL_BUS_RESOURCE_SPI_DESCRIPTOR; /// /// Serial Bus Resource Descriptor (UART) /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT8 ResourceSourceIndex; UINT8 SerialBusType; UINT8 GeneralFlags; UINT16 TypeSpecificFlags; UINT8 TypeSpecificRevisionId; UINT16 TypeDataLength; UINT32 DefaultBaudRate; UINT16 RxFIFO; UINT16 TxFIFO; UINT8 Parity; UINT8 SerialLinesEnabled; } EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR; #pragma pack() // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 5.0 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_5_0_SYSTEM_MEMORY 0 #define EFI_ACPI_5_0_SYSTEM_IO 1 #define EFI_ACPI_5_0_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_5_0_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_5_0_SMBUS 4 #define EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_5_0_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_5_0_UNDEFINED 0 #define EFI_ACPI_5_0_BYTE 1 #define EFI_ACPI_5_0_WORD 2 #define EFI_ACPI_5_0_DWORD 3 #define EFI_ACPI_5_0_QWORD 4 // // ACPI 5.0 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 5.0) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_5_0_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT8 Reserved2[3]; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; } EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x05 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_5_0_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_5_0_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_5_0_PM_PROFILE_MOBILE 2 #define EFI_ACPI_5_0_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_5_0_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_5_0_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_5_0_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_5_0_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_5_0_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_0_LEGACY_DEVICES BIT0 #define EFI_ACPI_5_0_8042 BIT1 #define EFI_ACPI_5_0_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_5_0_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_5_0_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_5_0_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_0_WBINVD BIT0 #define EFI_ACPI_5_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_5_0_PROC_C1 BIT2 #define EFI_ACPI_5_0_P_LVL2_UP BIT3 #define EFI_ACPI_5_0_PWR_BUTTON BIT4 #define EFI_ACPI_5_0_SLP_BUTTON BIT5 #define EFI_ACPI_5_0_FIX_RTC BIT6 #define EFI_ACPI_5_0_RTC_S4 BIT7 #define EFI_ACPI_5_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_5_0_DCK_CAP BIT9 #define EFI_ACPI_5_0_RESET_REG_SUP BIT10 #define EFI_ACPI_5_0_SEALED_CASE BIT11 #define EFI_ACPI_5_0_HEADLESS BIT12 #define EFI_ACPI_5_0_CPU_SW_SLP BIT13 #define EFI_ACPI_5_0_PCI_EXP_WAK BIT14 #define EFI_ACPI_5_0_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_5_0_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_5_0_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_5_0_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_5_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_5_0_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_5_0_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_0_S4BIOS_F BIT0 #define EFI_ACPI_5_0_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_0_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_5_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_5_0_IO_APIC 0x01 #define EFI_ACPI_5_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_5_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_5_0_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_5_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_5_0_IO_SAPIC 0x06 #define EFI_ACPI_5_0_LOCAL_SAPIC 0x07 #define EFI_ACPI_5_0_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_5_0_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_5_0_GIC 0x0B #define EFI_ACPI_5_0_GICD 0x0C // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_5_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_5_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_5_0_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_0_POLARITY (3 << 0) #define EFI_ACPI_5_0_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_5_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_5_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_5_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_5_0_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_5_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_5_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_0_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_5_0_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicId; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; } EFI_ACPI_5_0_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_0_GIC_ENABLED BIT0 #define EFI_ACPI_5_0_PERFORMANCE_INTERRUPT_MODEL BIT1 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT32 Reserved2; } EFI_ACPI_5_0_GIC_DISTRIBUTOR_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_5_0_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x03 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_5_0_MEMORY_AFFINITY 0x01 #define EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_5_0_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_5_0_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_5_0_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_5_0_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_5_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_5_0_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_5_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_5_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_5_0_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_5_0_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_5_0_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_5_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED 0x01 #define EFI_ACPI_5_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE 0x02 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_5_0_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_5_0_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_5_0_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_5_0_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_5_0_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_5_0_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_5_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_5_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_5_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_5_0_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_5_0_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_5_0_BGRT_STATUS_DISPLAYED 0x01 #define EFI_ACPI_5_0_BGRT_STATUS_INVALID EFI_ACPI_5_0_BGRT_STATUS_NOT_DISPLAYED #define EFI_ACPI_5_0_BGRT_STATUS_VALID EFI_ACPI_5_0_BGRT_STATUS_DISPLAYED /// /// BGRT Image Type /// #define EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior to when the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_5_0_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 PhysicalAddress; UINT32 GlobalFlags; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; } EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x01 /// /// Global Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_MEMORY_MAPPED_BLOCK_PRESENT BIT0 #define EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_INTERRUPT_MODE BIT1 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_5_0_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_5_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_5_0_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_5_0_ERROR_SEVERITY_CORRECTABLE 0x00 #define EFI_ACPI_5_0_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_5_0_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_5_0_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_5_0_ERROR_SEVERITY_NONE 0x03 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; } EFI_ACPI_5_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0201 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_5_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_5_0_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_5_0_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_5_0_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_5_0_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_5_0_GENERIC_HARDWARE_ERROR 0x09 // // Error Source structure flags. // #define EFI_ACPI_5_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_5_0_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_5_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_5_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_5_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_5_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_5_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_5_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_5_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_5_0_GENERIC_ERROR_STATUS_STRUCTURE; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_5_0_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_5_0_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_5_0_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_5_0_ERST_END_OPERATION 0x03 #define EFI_ACPI_5_0_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_5_0_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_5_0_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_5_0_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_5_0_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_5_0_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_5_0_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_5_0_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F /// /// ERST Action Command Status /// #define EFI_ACPI_5_0_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_5_0_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_5_0_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_5_0_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_5_0_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_5_0_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_5_0_ERST_READ_REGISTER 0x00 #define EFI_ACPI_5_0_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_5_0_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_5_0_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_5_0_ERST_NOOP 0x04 #define EFI_ACPI_5_0_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_5_0_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_5_0_ERST_STORE_VAR1 0x07 #define EFI_ACPI_5_0_ERST_ADD 0x08 #define EFI_ACPI_5_0_ERST_SUBTRACT 0x09 #define EFI_ACPI_5_0_ERST_ADD_VALUE 0x0A #define EFI_ACPI_5_0_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_5_0_ERST_STALL 0x0C #define EFI_ACPI_5_0_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_5_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_5_0_ERST_GOTO 0x0F #define EFI_ACPI_5_0_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_5_0_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_5_0_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_5_0_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_5_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_5_0_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_5_0_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_5_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_5_0_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_5_0_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_5_0_EINJ_END_OPERATION 0x04 #define EFI_ACPI_5_0_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_5_0_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_5_0_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_5_0_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_5_0_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_5_0_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_5_0_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_5_0_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_5_0_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_5_0_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_5_0_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_5_0_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_5_0_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_5_0_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_5_0_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 5.0 spec.) /// #define EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01 /// /// PCCT Global Flags /// #define EFI_ACPI_5_0_PCCT_FLAGS_SCI_DOORBELL BIT0 // // PCCT Subspace type // #define EFI_ACPI_5_0_PCCT_SUBSPACE_TYPE_GENERIC 0x00 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_5_0_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 GenerateSci : 1; } EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 SciDoorbell : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_5_0_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_5_0_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_5_0_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_5_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_5_0_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_5_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_5_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_5_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_5_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_5_0_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_5_0_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_5_0_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_5_0_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_5_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_5_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_5_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_5_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_5_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_5_0_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_5_0_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_5_0_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_5_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_5_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_5_0_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_5_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') #define EFI_ACPI_5_0_WINDOWS_ACPI_ENLIGHTENMENT_TABLE_SIGNATURE EFI_ACPI_5_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_5_0_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_5_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_5_0_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi51.h ================================================ /** @file ACPI 5.1 definitions from the ACPI Specification Revision 5.1 Errata B January, 2016. Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
Copyright (c) 2020, ARM Ltd. All rights reserved.
Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_5_1_H_ #define _ACPI_5_1_H_ #include "Acpi50.h" /// /// _CSD Revision for ACPI 5.1 /// #define EFI_ACPI_5_1_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 5.1 /// #define EFI_ACPI_5_1_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 5.1 /// #define EFI_ACPI_5_1_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 5.1 /// #define EFI_ACPI_5_1_AML_CPC_REVISION 2 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 5.1 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_5_1_SYSTEM_MEMORY 0 #define EFI_ACPI_5_1_SYSTEM_IO 1 #define EFI_ACPI_5_1_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_5_1_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_5_1_SMBUS 4 #define EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_5_1_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_5_1_UNDEFINED 0 #define EFI_ACPI_5_1_BYTE 1 #define EFI_ACPI_5_1_WORD 2 #define EFI_ACPI_5_1_DWORD 3 #define EFI_ACPI_5_1_QWORD 4 // // ACPI 5.1 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 5.1) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_5_1_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; } EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x05 #define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x01 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_5_1_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_5_1_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_5_1_PM_PROFILE_MOBILE 2 #define EFI_ACPI_5_1_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_5_1_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_5_1_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_5_1_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_5_1_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_5_1_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_1_LEGACY_DEVICES BIT0 #define EFI_ACPI_5_1_8042 BIT1 #define EFI_ACPI_5_1_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_5_1_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_5_1_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_5_1_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_1_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_5_1_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_1_WBINVD BIT0 #define EFI_ACPI_5_1_WBINVD_FLUSH BIT1 #define EFI_ACPI_5_1_PROC_C1 BIT2 #define EFI_ACPI_5_1_P_LVL2_UP BIT3 #define EFI_ACPI_5_1_PWR_BUTTON BIT4 #define EFI_ACPI_5_1_SLP_BUTTON BIT5 #define EFI_ACPI_5_1_FIX_RTC BIT6 #define EFI_ACPI_5_1_RTC_S4 BIT7 #define EFI_ACPI_5_1_TMR_VAL_EXT BIT8 #define EFI_ACPI_5_1_DCK_CAP BIT9 #define EFI_ACPI_5_1_RESET_REG_SUP BIT10 #define EFI_ACPI_5_1_SEALED_CASE BIT11 #define EFI_ACPI_5_1_HEADLESS BIT12 #define EFI_ACPI_5_1_CPU_SW_SLP BIT13 #define EFI_ACPI_5_1_PCI_EXP_WAK BIT14 #define EFI_ACPI_5_1_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_5_1_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_5_1_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_5_1_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_5_1_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_5_1_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_5_1_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_1_S4BIOS_F BIT0 #define EFI_ACPI_5_1_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_1_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_5_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_5_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_1_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_5_1_IO_APIC 0x01 #define EFI_ACPI_5_1_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_5_1_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_5_1_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_5_1_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_5_1_IO_SAPIC 0x06 #define EFI_ACPI_5_1_LOCAL_SAPIC 0x07 #define EFI_ACPI_5_1_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_5_1_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_5_1_GIC 0x0B #define EFI_ACPI_5_1_GICD 0x0C #define EFI_ACPI_5_1_GIC_MSI_FRAME 0x0D #define EFI_ACPI_5_1_GICR 0x0E // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_5_1_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_5_1_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_5_1_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_5_1_POLARITY (3 << 0) #define EFI_ACPI_5_1_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_5_1_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_5_1_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_5_1_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_5_1_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_5_1_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_5_1_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_5_1_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_5_1_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; } EFI_ACPI_5_1_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GIC_ENABLED BIT0 #define EFI_ACPI_5_1_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_5_1_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_5_1_GIC_V1 0x01 #define EFI_ACPI_5_1_GIC_V2 0x02 #define EFI_ACPI_5_1_GIC_V3 0x03 #define EFI_ACPI_5_1_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_5_1_GICR_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_5_1_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x04 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_5_1_MEMORY_AFFINITY 0x01 #define EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_5_1_GICC_AFFINITY 0x03 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_5_1_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_5_1_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_5_1_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_5_1_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_5_1_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GICC_ENABLED (1 << 0) /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_5_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_5_1_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_5_1_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_5_1_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_5_1_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_5_1_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_5_1_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_5_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED 0x01 #define EFI_ACPI_5_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE 0x02 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_5_1_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_5_1_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_5_1_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_5_1_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_5_1_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_5_1_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_5_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_5_1_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_5_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_5_1_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_5_1_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_5_1_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_5_1_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_5_1_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_5_1_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_5_1_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_5_1_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_5_1_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_5_1_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior to when the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_5_1_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_5_1_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_5_1_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_5_1_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_5_1_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_5_1_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_5_1_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; } EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_5_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_5_1_GTDT_GT_BLOCK 0 #define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// SBSA Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE; /// /// SBSA Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_5_1_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_5_1_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_5_1_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_5_1_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_5_1_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_5_1_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_5_1_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_5_1_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; } EFI_ACPI_5_1_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0201 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_5_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_5_1_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_5_1_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_5_1_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_5_1_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_5_1_GENERIC_HARDWARE_ERROR 0x09 // // Error Source structure flags. // #define EFI_ACPI_5_1_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_5_1_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_5_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_5_1_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_5_1_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_5_1_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_5_1_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_5_1_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_5_1_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_5_1_GENERIC_ERROR_STATUS_STRUCTURE; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_5_1_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_5_1_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_5_1_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_5_1_ERST_END_OPERATION 0x03 #define EFI_ACPI_5_1_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_5_1_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_5_1_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_5_1_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_5_1_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_5_1_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_5_1_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_5_1_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F /// /// ERST Action Command Status /// #define EFI_ACPI_5_1_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_5_1_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_5_1_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_5_1_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_5_1_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_5_1_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_5_1_ERST_READ_REGISTER 0x00 #define EFI_ACPI_5_1_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_5_1_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_5_1_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_5_1_ERST_NOOP 0x04 #define EFI_ACPI_5_1_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_5_1_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_5_1_ERST_STORE_VAR1 0x07 #define EFI_ACPI_5_1_ERST_ADD 0x08 #define EFI_ACPI_5_1_ERST_SUBTRACT 0x09 #define EFI_ACPI_5_1_ERST_ADD_VALUE 0x0A #define EFI_ACPI_5_1_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_5_1_ERST_STALL 0x0C #define EFI_ACPI_5_1_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_5_1_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_5_1_ERST_GOTO 0x0F #define EFI_ACPI_5_1_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_5_1_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_5_1_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_5_1_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_5_1_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_5_1_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_5_1_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_5_1_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_5_1_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_5_1_EINJ_END_OPERATION 0x04 #define EFI_ACPI_5_1_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_5_1_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_5_1_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_5_1_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_5_1_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_5_1_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_5_1_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_5_1_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_5_1_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_5_1_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_5_1_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_5_1_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_5_1_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_5_1_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_5_1_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 5.1 spec.) /// #define EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01 /// /// PCCT Global Flags /// #define EFI_ACPI_5_1_PCCT_FLAGS_SCI_DOORBELL BIT0 // // PCCT Subspace type // #define EFI_ACPI_5_1_PCCT_SUBSPACE_TYPE_GENERIC 0x00 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_5_1_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_5_1_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 GenerateSci : 1; } EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 SciDoorbell : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_5_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_5_1_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_5_1_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_5_1_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_5_1_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_5_1_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_5_1_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_5_1_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_5_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_5_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_5_1_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_5_1_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_5_1_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_5_1_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_5_1_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_5_1_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_5_1_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_5_1_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_5_1_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_5_1_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_5_1_IO_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_5_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_5_1_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_5_1_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_5_1_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_5_1_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_5_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_5_1_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_5_1_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_5_1_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_5_1_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_5_1_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_5_1_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_5_1_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_5_1_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi60.h ================================================ /** @file ACPI 6.0 definitions from the ACPI Specification Revision 6.0 Errata A January, 2016. Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
Copyright (c) 2020, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_0_H_ #define _ACPI_6_0_H_ #include "Acpi51.h" /// /// _CSD Revision for ACPI 6.0 /// #define EFI_ACPI_6_0_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.0 /// #define EFI_ACPI_6_0_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 6.0 /// #define EFI_ACPI_6_0_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.0 /// #define EFI_ACPI_6_0_AML_CPC_REVISION 2 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 6.0 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_0_SYSTEM_MEMORY 0 #define EFI_ACPI_6_0_SYSTEM_IO 1 #define EFI_ACPI_6_0_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_6_0_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_6_0_SMBUS 4 #define EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_0_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_0_UNDEFINED 0 #define EFI_ACPI_6_0_BYTE 1 #define EFI_ACPI_6_0_WORD 2 #define EFI_ACPI_6_0_DWORD 3 #define EFI_ACPI_6_0_QWORD 4 // // ACPI 6.0 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.0) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_0_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x00 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_0_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_0_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_0_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_0_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_0_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_0_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_0_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_0_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_0_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_0_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_0_8042 BIT1 #define EFI_ACPI_6_0_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_0_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_0_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_0_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_0_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_0_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_0_WBINVD BIT0 #define EFI_ACPI_6_0_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_0_PROC_C1 BIT2 #define EFI_ACPI_6_0_P_LVL2_UP BIT3 #define EFI_ACPI_6_0_PWR_BUTTON BIT4 #define EFI_ACPI_6_0_SLP_BUTTON BIT5 #define EFI_ACPI_6_0_FIX_RTC BIT6 #define EFI_ACPI_6_0_RTC_S4 BIT7 #define EFI_ACPI_6_0_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_0_DCK_CAP BIT9 #define EFI_ACPI_6_0_RESET_REG_SUP BIT10 #define EFI_ACPI_6_0_SEALED_CASE BIT11 #define EFI_ACPI_6_0_HEADLESS BIT12 #define EFI_ACPI_6_0_CPU_SW_SLP BIT13 #define EFI_ACPI_6_0_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_0_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_0_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_0_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_0_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_0_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_0_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_0_S4BIOS_F BIT0 #define EFI_ACPI_6_0_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_0_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.0 Errata A spec.) /// #define EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x04 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_0_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_0_IO_APIC 0x01 #define EFI_ACPI_6_0_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_0_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_0_IO_SAPIC 0x06 #define EFI_ACPI_6_0_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_0_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_0_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_0_GIC 0x0B #define EFI_ACPI_6_0_GICD 0x0C #define EFI_ACPI_6_0_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_0_GICR 0x0E #define EFI_ACPI_6_0_GIC_ITS 0x0F // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_0_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_0_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_0_POLARITY (3 << 0) #define EFI_ACPI_6_0_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_0_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_0_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_0_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_0_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2[3]; } EFI_ACPI_6_0_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GIC_ENABLED BIT0 #define EFI_ACPI_6_0_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_0_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_0_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_0_GIC_V1 0x01 #define EFI_ACPI_6_0_GIC_V2 0x02 #define EFI_ACPI_6_0_GIC_V3 0x03 #define EFI_ACPI_6_0_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_0_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_0_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_0_GIC_ITS_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_0_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x04 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_0_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_0_GICC_AFFINITY 0x03 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_0_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_0_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_0_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_0_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_0_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GICC_ENABLED (1 << 0) /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_0_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_0_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_0_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_0_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED 0x01 #define EFI_ACPI_6_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE 0x02 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_0_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_0_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_0_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_0_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_0_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_0_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_6_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_6_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_0_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_0_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_0_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_0_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior to when the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_0_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_0_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_0_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_0_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; } EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_0_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_0_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_0_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_0_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// SBSA Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE; /// /// SBSA Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.0 spec.) // #define EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_TO_SYSTEM_ADDRESS_RANGE_MAP_STRUCTURE_TYPE 1 #define EFI_ACPI_6_0_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_0_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_0_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_0_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_0_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_0_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_0_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_0_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_0_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; } EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_0_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_0_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 MemoryDevicePhysicalID; UINT16 MemoryDeviceRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 MemoryDeviceRegionSize; UINT64 RegionOffset; UINT64 MemoryDevicePhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 MemoryDeviceStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_TO_SYSTEM_ADDRESS_RANGE_MAP_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_0_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_0_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 Reserved_18[6]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_0_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_0_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_0_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_0_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_0_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_0_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_0_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_0_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_0_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_0_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; } EFI_ACPI_6_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0201 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_0_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_0_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_0_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_0_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR 0x09 // // Error Source structure flags. // #define EFI_ACPI_6_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_0_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_0_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_0_GENERIC_ERROR_STATUS_STRUCTURE; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_0_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_0_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_0_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_0_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_0_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_0_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_0_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_0_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_0_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_0_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_0_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_0_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F /// /// ERST Action Command Status /// #define EFI_ACPI_6_0_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_0_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_0_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_0_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_0_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_0_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_0_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_0_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_0_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_0_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_0_ERST_NOOP 0x04 #define EFI_ACPI_6_0_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_0_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_0_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_0_ERST_ADD 0x08 #define EFI_ACPI_6_0_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_0_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_0_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_0_ERST_STALL 0x0C #define EFI_ACPI_6_0_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_0_ERST_GOTO 0x0F #define EFI_ACPI_6_0_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_0_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_0_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_0_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_0_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_0_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_0_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_0_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_0_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_0_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_0_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_0_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_0_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_0_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_0_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_0_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_0_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_0_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_0_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.0 spec.) /// #define EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01 /// /// PCCT Global Flags /// #define EFI_ACPI_6_0_PCCT_FLAGS_SCI_DOORBELL BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_0_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_0_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_0_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_0_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_0_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 GenerateSci : 1; } EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 SciDoorbell : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_0_PCCT_SUBSPACE_DOORBELL_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_0_PCCT_SUBSPACE_DOORBELL_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 DoorbellInterrupt; UINT8 DoorbellInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_0_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 DoorbellInterrupt; UINT8 DoorbellInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellAckRegister; UINT64 DoorbellAckPreserve; UINT64 DoorbellAckWrite; } EFI_ACPI_6_0_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_0_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_0_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_0_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_0_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_0_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_0_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_0_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_0_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_0_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_0_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_0_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_0_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_0_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_6_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_0_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_0_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_0_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_0_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_0_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi61.h ================================================ /** @file ACPI 6.1 definitions from the ACPI Specification Revision 6.1 January, 2016. Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (c) 2020, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_1_H_ #define _ACPI_6_1_H_ #include "Acpi60.h" /// /// _CSD Revision for ACPI 6.1 /// #define EFI_ACPI_6_1_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.1 /// #define EFI_ACPI_6_1_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 6.1 /// #define EFI_ACPI_6_1_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.1 /// #define EFI_ACPI_6_1_AML_CPC_REVISION 2 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 6.1 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_1_SYSTEM_MEMORY 0 #define EFI_ACPI_6_1_SYSTEM_IO 1 #define EFI_ACPI_6_1_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_6_1_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_6_1_SMBUS 4 #define EFI_ACPI_6_1_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_1_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_1_UNDEFINED 0 #define EFI_ACPI_6_1_BYTE 1 #define EFI_ACPI_6_1_WORD 2 #define EFI_ACPI_6_1_DWORD 3 #define EFI_ACPI_6_1_QWORD 4 // // ACPI 6.1 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.1) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_1_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x01 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_1_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_1_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_1_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_1_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_1_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_1_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_1_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_1_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_1_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_1_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_1_8042 BIT1 #define EFI_ACPI_6_1_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_1_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_1_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_1_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_1_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_1_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_1_WBINVD BIT0 #define EFI_ACPI_6_1_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_1_PROC_C1 BIT2 #define EFI_ACPI_6_1_P_LVL2_UP BIT3 #define EFI_ACPI_6_1_PWR_BUTTON BIT4 #define EFI_ACPI_6_1_SLP_BUTTON BIT5 #define EFI_ACPI_6_1_FIX_RTC BIT6 #define EFI_ACPI_6_1_RTC_S4 BIT7 #define EFI_ACPI_6_1_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_1_DCK_CAP BIT9 #define EFI_ACPI_6_1_RESET_REG_SUP BIT10 #define EFI_ACPI_6_1_SEALED_CASE BIT11 #define EFI_ACPI_6_1_HEADLESS BIT12 #define EFI_ACPI_6_1_CPU_SW_SLP BIT13 #define EFI_ACPI_6_1_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_1_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_1_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_1_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_1_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_1_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_1_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_1_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_1_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_1_S4BIOS_F BIT0 #define EFI_ACPI_6_1_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_1_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x04 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_1_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_1_IO_APIC 0x01 #define EFI_ACPI_6_1_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_1_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_1_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_1_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_1_IO_SAPIC 0x06 #define EFI_ACPI_6_1_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_1_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_1_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_1_GIC 0x0B #define EFI_ACPI_6_1_GICD 0x0C #define EFI_ACPI_6_1_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_1_GICR 0x0E #define EFI_ACPI_6_1_GIC_ITS 0x0F // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_1_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_1_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_1_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_1_POLARITY (3 << 0) #define EFI_ACPI_6_1_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_1_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_1_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_1_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_1_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_1_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_1_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_1_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_1_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2[3]; } EFI_ACPI_6_1_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GIC_ENABLED BIT0 #define EFI_ACPI_6_1_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_1_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_1_GIC_V1 0x01 #define EFI_ACPI_6_1_GIC_V2 0x02 #define EFI_ACPI_6_1_GIC_V3 0x03 #define EFI_ACPI_6_1_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_1_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_1_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_1_GIC_ITS_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_1_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_1_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x04 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_1_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_1_GICC_AFFINITY 0x03 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_1_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_1_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_1_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_1_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_1_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_1_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GICC_ENABLED (1 << 0) /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_1_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_1_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_1_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_1_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_1_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_1_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED 0x01 #define EFI_ACPI_6_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE 0x02 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_1_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_1_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_1_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_1_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_1_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_1_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_1_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_1_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_1_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_1_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_6_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_6_1_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_6_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_6_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_6_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_1_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_1_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_1_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_1_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_1_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_1_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_1_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_1_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_1_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_1_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_1_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_1_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_1_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_1_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior to when the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_1_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_1_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_1_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_1_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_1_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_1_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_1_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_1_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; } EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_1_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// SBSA Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE; /// /// SBSA Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.1 spec.) // #define EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_1_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE 1 #define EFI_ACPI_6_1_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_1_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_1_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_1_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_1_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_1_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_1_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_1_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_1_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_1_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_1_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_1_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_1_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; } EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_1_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 #define EFI_ACPI_6_1_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_NOT_MAP_NVDIMM_TO_SPA BIT6 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_1_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NVDIMMPhysicalID; UINT16 NVDIMMRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 NVDIMMRegionSize; UINT64 RegionOffset; UINT64 NVDIMMPhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 NVDIMMStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_1_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_1_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_1_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_1_NFIT_NVDIMM_CONTROL_REGION_VALID_FIELDS_MANUFACTURING BIT0 #define EFI_ACPI_6_1_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 ValidFields; UINT8 ManufacturingLocation; UINT16 ManufacturingDate; UINT8 Reserved_22[2]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_1_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_1_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_1_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_1_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_1_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_1_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_1_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_1_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_1_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_1_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_1_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_1_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_1_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; UINT8 Timestamp[8]; } EFI_ACPI_6_1_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0300 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_1_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_1_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_1_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_1_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_1_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_1_GENERIC_HARDWARE_ERROR 0x09 #define EFI_ACPI_6_1_GENERIC_HARDWARE_ERROR_VERSION_2 0x0A // // Error Source structure flags. // #define EFI_ACPI_6_1_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_1_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEA 0x08 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEI 0x09 #define EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_GSIV 0x0A /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_1_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_1_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_1_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_1_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_1_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Hardware Error Source Version 2 Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE ReadAckRegister; UINT64 ReadAckPreserve; UINT64 ReadAckWrite; } EFI_ACPI_6_1_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_1_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_1_GENERIC_ERROR_STATUS_STRUCTURE; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_1_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_1_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_1_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_1_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_1_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_1_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_1_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_1_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_1_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_1_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_1_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_1_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_1_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F #define EFI_ACPI_6_1_ERST_GET_EXECUTE_OPERATION_TIMINGS 0x10 /// /// ERST Action Command Status /// #define EFI_ACPI_6_1_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_1_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_1_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_1_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_1_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_1_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_1_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_1_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_1_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_1_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_1_ERST_NOOP 0x04 #define EFI_ACPI_6_1_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_1_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_1_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_1_ERST_ADD 0x08 #define EFI_ACPI_6_1_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_1_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_1_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_1_ERST_STALL 0x0C #define EFI_ACPI_6_1_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_1_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_1_ERST_GOTO 0x0F #define EFI_ACPI_6_1_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_1_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_1_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_1_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_1_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_1_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_1_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_1_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_1_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_1_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_1_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_1_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_1_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_1_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_1_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_1_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_1_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_1_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_1_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_1_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_1_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_1_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_1_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_1_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_1_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_1_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_1_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_1_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_1_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_1_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_1_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.1 spec.) /// #define EFI_ACPI_6_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01 /// /// PCCT Global Flags /// #define EFI_ACPI_6_1_PCCT_FLAGS_SCI_DOORBELL BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_1_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_1_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_1_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_1_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_1_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 GenerateSci : 1; } EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 SciDoorbell : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_1_PCCT_SUBSPACE_DOORBELL_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_1_PCCT_SUBSPACE_DOORBELL_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 DoorbellInterrupt; UINT8 DoorbellInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_1_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 DoorbellInterrupt; UINT8 DoorbellInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellAckRegister; UINT64 DoorbellAckPreserve; UINT64 DoorbellAckWrite; } EFI_ACPI_6_1_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_1_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_1_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_1_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_1_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_1_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_1_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_1_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_1_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_1_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_1_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_1_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_1_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_1_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_1_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_1_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_1_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_1_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_1_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_1_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_1_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_1_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_1_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_1_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_1_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_1_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_1_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_1_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_1_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_1_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_1_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_1_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_1_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_1_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_1_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_1_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_1_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_1_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_1_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_1_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi62.h ================================================ /** @file ACPI 6.2 definitions from the ACPI Specification Revision 6.2 May, 2017. Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2020, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_2_H_ #define _ACPI_6_2_H_ #include "Acpi61.h" /// /// _CSD Revision for ACPI 6.2 /// #define EFI_ACPI_6_2_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.2 /// #define EFI_ACPI_6_2_AML_CSD_NUM_ENTRIES 6 // // Large Item Descriptor Name // #define ACPI_LARGE_PIN_FUNCTION_DESCRIPTOR_NAME 0x0D #define ACPI_LARGE_PIN_CONFIGURATION_DESCRIPTOR_NAME 0x0F #define ACPI_LARGE_PIN_GROUP_DESCRIPTOR_NAME 0x10 #define ACPI_LARGE_PIN_GROUP_FUNCTION_DESCRIPTOR_NAME 0x11 #define ACPI_LARGE_PIN_GROUP_CONFIGURATION_DESCRIPTOR_NAME 0x12 // // Large Item Descriptor Value // #define ACPI_PIN_FUNCTION_DESCRIPTOR 0x8D #define ACPI_PIN_CONFIGURATION_DESCRIPTOR 0x8F #define ACPI_PIN_GROUP_DESCRIPTOR 0x90 #define ACPI_PIN_GROUP_FUNCTION_DESCRIPTOR 0x91 #define ACPI_PIN_GROUP_CONFIGURATION_DESCRIPTOR 0x92 /// /// _PSD Revision for ACPI 6.2 /// #define EFI_ACPI_6_2_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.2 /// #define EFI_ACPI_6_2_AML_CPC_REVISION 3 #pragma pack(1) /// /// Pin Function Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT16 Flags; UINT8 PinPullConfiguration; UINT16 FunctionNumber; UINT16 PinTableOffset; UINT8 ResourceSourceIndex; UINT16 ResourceSourceNameOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_PIN_FUNCTION_DESCRIPTOR; /// /// Pin Configuration Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT16 Flags; UINT8 PinConfigurationType; UINT32 PinConfigurationValue; UINT16 PinTableOffset; UINT8 ResourceSourceIndex; UINT16 ResourceSourceNameOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_PIN_CONFIGURATION_DESCRIPTOR; /// /// Pin Group Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT16 Flags; UINT16 PinTableOffset; UINT16 ResourceLabelOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_PIN_GROUP_DESCRIPTOR; /// /// Pin Group Function Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT16 Flags; UINT16 FunctionNumber; UINT8 ResourceSourceIndex; UINT16 ResourceSourceNameOffset; UINT16 ResourceSourceLabelOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_PIN_GROUP_FUNCTION_DESCRIPTOR; /// /// Pin Group Configuration Descriptor /// typedef PACKED struct { ACPI_LARGE_RESOURCE_HEADER Header; UINT8 RevisionId; UINT16 Flags; UINT8 PinConfigurationType; UINT32 PinConfigurationValue; UINT8 ResourceSourceIndex; UINT16 ResourceSourceNameOffset; UINT16 ResourceSourceLabelOffset; UINT16 VendorDataOffset; UINT16 VendorDataLength; } EFI_ACPI_PIN_GROUP_CONFIGURATION_DESCRIPTOR; #pragma pack() // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 6.2 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_2_SYSTEM_MEMORY 0 #define EFI_ACPI_6_2_SYSTEM_IO 1 #define EFI_ACPI_6_2_PCI_CONFIGURATION_SPACE 2 #define EFI_ACPI_6_2_EMBEDDED_CONTROLLER 3 #define EFI_ACPI_6_2_SMBUS 4 #define EFI_ACPI_6_2_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_2_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_2_UNDEFINED 0 #define EFI_ACPI_6_2_BYTE 1 #define EFI_ACPI_6_2_WORD 2 #define EFI_ACPI_6_2_DWORD 3 #define EFI_ACPI_6_2_QWORD 4 // // ACPI 6.2 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.2) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_2_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x02 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_2_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_2_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_2_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_2_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_2_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_2_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_2_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_2_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_2_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_2_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_2_8042 BIT1 #define EFI_ACPI_6_2_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_2_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_2_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_2_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_2_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_2_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_2_WBINVD BIT0 #define EFI_ACPI_6_2_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_2_PROC_C1 BIT2 #define EFI_ACPI_6_2_P_LVL2_UP BIT3 #define EFI_ACPI_6_2_PWR_BUTTON BIT4 #define EFI_ACPI_6_2_SLP_BUTTON BIT5 #define EFI_ACPI_6_2_FIX_RTC BIT6 #define EFI_ACPI_6_2_RTC_S4 BIT7 #define EFI_ACPI_6_2_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_2_DCK_CAP BIT9 #define EFI_ACPI_6_2_RESET_REG_SUP BIT10 #define EFI_ACPI_6_2_SEALED_CASE BIT11 #define EFI_ACPI_6_2_HEADLESS BIT12 #define EFI_ACPI_6_2_CPU_SW_SLP BIT13 #define EFI_ACPI_6_2_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_2_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_2_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_2_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_2_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_2_S4BIOS_F BIT0 #define EFI_ACPI_6_2_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_2_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x04 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_2_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_2_IO_APIC 0x01 #define EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_2_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_2_IO_SAPIC 0x06 #define EFI_ACPI_6_2_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_2_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_2_GIC 0x0B #define EFI_ACPI_6_2_GICD 0x0C #define EFI_ACPI_6_2_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_2_GICR 0x0E #define EFI_ACPI_6_2_GIC_ITS 0x0F // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_LOCAL_APIC_ENABLED BIT0 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_2_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_2_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_2_POLARITY (3 << 0) #define EFI_ACPI_6_2_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_2_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_2_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2[3]; } EFI_ACPI_6_2_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GIC_ENABLED BIT0 #define EFI_ACPI_6_2_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_2_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_2_GIC_V1 0x01 #define EFI_ACPI_6_2_GIC_V2 0x02 #define EFI_ACPI_6_2_GIC_V3 0x03 #define EFI_ACPI_6_2_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_2_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_2_GIC_ITS_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_2_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_2_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x05 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_2_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_2_GICC_AFFINITY 0x03 #define EFI_ACPI_6_2_GIC_ITS_AFFINITY 0x04 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_2_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_2_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_2_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_2_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GICC_ENABLED (1 << 0) /// /// GIC Interrupt Translation Service (ITS) Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT8 Reserved[2]; UINT32 ItsId; } EFI_ACPI_6_2_GIC_ITS_AFFINITY_STRUCTURE; /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_2_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_2_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_2_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_2_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_2_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_2_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_2_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_2_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED BIT0 #define EFI_ACPI_6_2_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED_AND_EXPOSED_TO_SOFTWARE BIT1 #define EFI_ACPI_6_2_RASF_PLATFORM_RAS_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT2 #define EFI_ACPI_6_2_RASF_PLATFORM_RAS_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT3 #define EFI_ACPI_6_2_RASF_PLATFORM_RAS_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT4 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_2_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_2_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_2_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_2_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_2_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_2_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_2_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_2_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_2_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_2_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_2_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_6_2_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_2_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_2_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_2_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_6_2_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_6_2_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_6_2_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_6_2_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_2_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_2_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_2_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_2_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_2_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_2_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_2_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_2_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_2_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_2_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_2_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_2_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior to when the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_2_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_2_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_2_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_2_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_2_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_2_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_2_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_2_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; } EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_2_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_2_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_2_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_2_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// SBSA Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE; /// /// SBSA Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_2_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.2 spec.) // #define EFI_ACPI_6_2_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_2_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_2_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE 1 #define EFI_ACPI_6_2_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_2_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_2_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_2_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_2_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 #define EFI_ACPI_6_2_NFIT_PLATFORM_CAPABILITIES_STRUCTURE_TYPE 7 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_2_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_2_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_2_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_2_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_2_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_2_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_2_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_2_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_2_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_2_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_2_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; } EFI_ACPI_6_2_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_2_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 #define EFI_ACPI_6_2_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_NOT_MAP_NVDIMM_TO_SPA BIT6 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_2_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NVDIMMPhysicalID; UINT16 NVDIMMRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 NVDIMMRegionSize; UINT64 RegionOffset; UINT64 NVDIMMPhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 NVDIMMStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_2_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_2_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_2_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_2_NFIT_NVDIMM_CONTROL_REGION_VALID_FIELDS_MANUFACTURING BIT0 #define EFI_ACPI_6_2_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 ValidFields; UINT8 ManufacturingLocation; UINT16 ManufacturingDate; UINT8 Reserved_22[2]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_2_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_2_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_2_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_2_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; // // Definition for Platform Capabilities Structure // typedef struct { UINT16 Type; UINT16 Length; UINT8 HighestValidCapability; UINT8 Reserved_5[3]; UINT32 Capabilities; UINT8 Reserved_12[4]; } EFI_ACPI_6_2_NFIT_PLATFORM_CAPABILITIES_STRUCTURE; #define EFI_ACPI_6_2_NFIT_PLATFORM_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT0 #define EFI_ACPI_6_2_NFIT_PLATFORM_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT1 #define EFI_ACPI_6_2_NFIT_PLATFORM_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT2 /// /// Secure DEVices Table (SDEV) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_2_SECURE_DEVICES_TABLE_HEADER; /// /// SDEV Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_SECURE_DEVICES_TABLE_REVISION 0x01 /// /// Secure Device types /// #define EFI_ACPI_6_2_SDEV_TYPE_PCIE_ENDPOINT_DEVICE 0x01 #define EFI_ACPI_6_2_SDEV_TYPE_ACPI_NAMESPACE_DEVICE 0x00 /// /// Secure Device flags /// #define EFI_ACPI_6_2_SDEV_FLAG_ALLOW_HANDOFF BIT0 /// /// SDEV Structure Header /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; } EFI_ACPI_6_2_SDEV_STRUCTURE_HEADER; /// /// PCIe Endpoint Device based Secure Device Structure /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; UINT16 PciSegmentNumber; UINT16 StartBusNumber; UINT16 PciPathOffset; UINT16 PciPathLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_2_SDEV_STRUCTURE_PCIE_ENDPOINT_DEVICE; /// /// ACPI_NAMESPACE_DEVICE based Secure Device Structure /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; UINT16 DeviceIdentifierOffset; UINT16 DeviceIdentifierLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_2_SDEV_STRUCTURE_ACPI_NAMESPACE_DEVICE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_2_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_2_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_2_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_2_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_2_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_2_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_2_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_2_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_2_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; UINT8 Timestamp[8]; } EFI_ACPI_6_2_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0300 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_2_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_2_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_2_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_2_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_2_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_2_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_2_GENERIC_HARDWARE_ERROR 0x09 #define EFI_ACPI_6_2_GENERIC_HARDWARE_ERROR_VERSION_2 0x0A #define EFI_ACPI_6_2_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK 0x0B // // Error Source structure flags. // #define EFI_ACPI_6_2_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_2_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) #define EFI_ACPI_6_2_ERROR_SOURCE_FLAG_GHES_ASSIST (1 << 2) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_2_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEA 0x08 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEI 0x09 #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_GSIV 0x0A #define EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION 0x0B /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_2_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_2_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_2_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_2_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_2_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_2_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Hardware Error Source Version 2 Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ReadAckRegister; UINT64 ReadAckPreserve; UINT64 ReadAckWrite; } EFI_ACPI_6_2_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_2_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_2_GENERIC_ERROR_STATUS_STRUCTURE; /// /// IA-32 Architecture Deferred Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_2_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE; /// /// HMAT - Heterogeneous Memory Attribute Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[4]; } EFI_ACPI_6_2_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER; /// /// HMAT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION 0x01 /// /// HMAT types /// #define EFI_ACPI_6_2_HMAT_TYPE_MEMORY_SUBSYSTEM_ADDRESS_RANGE 0x00 #define EFI_ACPI_6_2_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO 0x01 #define EFI_ACPI_6_2_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO 0x02 /// /// HMAT Structure Header /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; } EFI_ACPI_6_2_HMAT_STRUCTURE_HEADER; /// /// Memory Subsystem Address Range Structure flags /// typedef struct { UINT16 ProcessorProximityDomainValid : 1; UINT16 MemoryProximityDomainValid : 1; UINT16 ReservationHint : 1; UINT16 Reserved : 13; } EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SUBSYSTEM_ADDRESS_RANGE_FLAGS; /// /// Memory Subsystem Address Range Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SUBSYSTEM_ADDRESS_RANGE_FLAGS Flags; UINT8 Reserved1[2]; UINT32 ProcessorProximityDomain; UINT32 MemoryProximityDomain; UINT8 Reserved2[4]; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; } EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SUBSYSTEM_ADDRESS_RANGE; /// /// System Locality Latency and Bandwidth Information Structure flags /// typedef struct { UINT8 MemoryHierarchy : 5; UINT8 Reserved : 3; } EFI_ACPI_6_2_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS; /// /// System Locality Latency and Bandwidth Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_2_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS Flags; UINT8 DataType; UINT8 Reserved1[2]; UINT32 NumberOfInitiatorProximityDomains; UINT32 NumberOfTargetProximityDomains; UINT8 Reserved2[4]; UINT64 EntryBaseUnit; } EFI_ACPI_6_2_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO; /// /// Memory Side Cache Information Structure cache attributes /// typedef struct { UINT32 TotalCacheLevels : 4; UINT32 CacheLevel : 4; UINT32 CacheAssociativity : 4; UINT32 WritePolicy : 4; UINT32 CacheLineSize : 16; } EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES; /// /// Memory Side Cache Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; UINT32 MemoryProximityDomain; UINT8 Reserved1[4]; UINT64 MemorySideCacheSize; EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES CacheAttributes; UINT8 Reserved2[2]; UINT16 NumberOfSmbiosHandles; } EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_2_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_2_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_2_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_2_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_2_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_2_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_2_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_2_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_2_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_2_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_2_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_2_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_2_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_2_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_2_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_2_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F #define EFI_ACPI_6_2_ERST_GET_EXECUTE_OPERATION_TIMINGS 0x10 /// /// ERST Action Command Status /// #define EFI_ACPI_6_2_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_2_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_2_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_2_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_2_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_2_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_2_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_2_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_2_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_2_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_2_ERST_NOOP 0x04 #define EFI_ACPI_6_2_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_2_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_2_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_2_ERST_ADD 0x08 #define EFI_ACPI_6_2_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_2_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_2_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_2_ERST_STALL 0x0C #define EFI_ACPI_6_2_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_2_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_2_ERST_GOTO 0x0F #define EFI_ACPI_6_2_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_2_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_2_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_2_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_2_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_2_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_2_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_2_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_2_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_2_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_2_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_2_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_2_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_2_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_2_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_2_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_2_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_2_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_2_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_2_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_2_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_2_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_2_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_2_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_2_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_2_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_2_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_2_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_2_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_2_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_2_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_2_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_2_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_2_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_2_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_2_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_2_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_2_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_2_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_2_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_2_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x02 /// /// PCCT Global Flags /// #define EFI_ACPI_6_2_PCCT_FLAGS_PLATFORM_INTERRUPT BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_2_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_2_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_2_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 #define EFI_ACPI_6_2_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC 0x03 #define EFI_ACPI_6_2_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC 0x04 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_2_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_2_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 NotifyOnCompletion : 1; } EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 PlatformInterrupt : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_2_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_2_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_2_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckWrite; } EFI_ACPI_6_2_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; /// /// Type 3 Extended PCC Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT32 AddressLength; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT32 MinimumRequestTurnaroundTime; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckSet; UINT8 Reserved1[8]; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE CommandCompleteUpdateRegister; UINT64 CommandCompleteUpdatePreserve; UINT64 CommandCompleteUpdateSet; EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; } EFI_ACPI_6_2_PCCT_SUBSPACE_3_EXTENDED_PCC; /// /// Type 4 Extended PCC Subspace Structure /// typedef EFI_ACPI_6_2_PCCT_SUBSPACE_3_EXTENDED_PCC EFI_ACPI_6_2_PCCT_SUBSPACE_4_EXTENDED_PCC; #define EFI_ACPI_6_2_PCCT_MASTER_SLAVE_COMMUNICATIONS_CHANNEL_FLAGS_NOTIFY_ON_COMPLETION BIT0 typedef struct { UINT32 Signature; UINT32 Flags; UINT32 Length; UINT32 Command; } EFI_ACPI_6_2_PCCT_EXTENDED_PCC_SHARED_MEMORY_REGION_HEADER; /// /// Platform Debug Trigger Table (PDTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 TriggerCount; UINT8 Reserved[3]; UINT32 TriggerIdentifierArrayOffset; } EFI_ACPI_6_2_PLATFORM_DEBUG_TRIGGER_TABLE_HEADER; /// /// PDTT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_PLATFORM_DEBUG_TRIGGER_TABLE_REVISION 0x00 /// /// PDTT Platform Communication Channel Identifier Structure /// typedef struct { UINT16 SubChannelIdentifer : 8; UINT16 Runtime : 1; UINT16 WaitForCompletion : 1; UINT16 Reserved : 6; } EFI_ACPI_6_2_PDTT_PCC_IDENTIFIER; /// /// PCC Commands Codes used by Platform Debug Trigger Table /// #define EFI_ACPI_6_2_PDTT_PCC_COMMAND_DOORBELL_ONLY 0x00 #define EFI_ACPI_6_2_PDTT_PCC_COMMAND_VENDOR_SPECIFIC 0x01 /// /// PPTT Platform Communication Channel /// typedef EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER EFI_ACPI_6_2_PDTT_PCC; /// /// Processor Properties Topology Table (PPTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER; /// /// PPTT Revision (as defined in ACPI 6.2 spec.) /// #define EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION 0x01 /// /// PPTT types /// #define EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR 0x00 #define EFI_ACPI_6_2_PPTT_TYPE_CACHE 0x01 #define EFI_ACPI_6_2_PPTT_TYPE_ID 0x02 /// /// PPTT Structure Header /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; } EFI_ACPI_6_2_PPTT_STRUCTURE_HEADER; /// /// For PPTT struct processor flags /// #define EFI_ACPI_6_2_PPTT_PROCESSOR_ID_INVALID 0x0 #define EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID 0x1 /// /// Processor hierarchy node structure flags /// typedef struct { UINT32 PhysicalPackage : 1; UINT32 AcpiProcessorIdValid : 1; UINT32 Reserved : 30; } EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR_FLAGS; /// /// Processor hierarchy node structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR_FLAGS Flags; UINT32 Parent; UINT32 AcpiProcessorId; UINT32 NumberOfPrivateResources; } EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR; /// /// Cache Type Structure flags /// typedef struct { UINT32 SizePropertyValid : 1; UINT32 NumberOfSetsValid : 1; UINT32 AssociativityValid : 1; UINT32 AllocationTypeValid : 1; UINT32 CacheTypeValid : 1; UINT32 WritePolicyValid : 1; UINT32 LineSizeValid : 1; UINT32 Reserved : 25; } EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_FLAGS; /// /// For cache attributes /// #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_READ 0x0 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_WRITE 0x1 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE 0x2 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_CACHE_TYPE_DATA 0x0 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION 0x1 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED 0x2 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK 0x0 #define EFI_ACPI_6_2_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_THROUGH 0x1 /// /// Cache Type Structure cache attributes /// typedef struct { UINT8 AllocationType : 2; UINT8 CacheType : 2; UINT8 WritePolicy : 1; UINT8 Reserved : 3; } EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES; /// /// Cache Type Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_FLAGS Flags; UINT32 NextLevelOfCache; UINT32 Size; UINT32 NumberOfSets; UINT8 Associativity; EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES Attributes; UINT16 LineSize; } EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE; /// /// ID structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 VendorId; UINT64 Level1Id; UINT64 Level2Id; UINT16 MajorRev; UINT16 MinorRev; UINT16 SpinRev; } EFI_ACPI_6_2_PPTT_STRUCTURE_ID; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_2_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_2_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_2_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_2_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_2_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_2_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_2_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "HMAT" Heterogeneous Memory Attribute Table /// #define EFI_ACPI_6_2_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('H', 'M', 'A', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_2_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_2_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PDTT" Platform Debug Trigger Table /// #define EFI_ACPI_6_2_PLATFORM_DEBUG_TRIGGER_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'D', 'T', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_2_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PPTT" Processor Properties Topology Table /// #define EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'P', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_2_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_2_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_2_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SDEV" Secure DEVices Table /// #define EFI_ACPI_6_2_SECURE_DEVICES_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'V') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_2_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_2_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_2_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_2_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DPPT" DMA Protection Policy Table /// #define EFI_ACPI_6_2_DMA_PROTECTION_POLICY_TABLE_SIGNATURE SIGNATURE_32('D', 'P', 'P', 'T') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_2_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_2_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_2_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_2_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_2_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_2_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_2_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SDEI" Software Delegated Exceptions Interface Table /// #define EFI_ACPI_6_2_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'I') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_2_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Console Redirection Table /// #define EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_2_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_2_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_2_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_2_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_2_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_2_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_2_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_2_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_2_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "WSMT" Windows SMM Security Mitigation Table /// #define EFI_ACPI_6_2_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE SIGNATURE_32('W', 'S', 'M', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_2_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi63.h ================================================ /** @file ACPI 6.3 definitions from the ACPI Specification Revision 6.3 Jan, 2019. Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2019 - 2020, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_3_H_ #define _ACPI_6_3_H_ #include "Acpi62.h" /// /// _CSD Revision for ACPI 6.3 /// #define EFI_ACPI_6_3_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.3 /// #define EFI_ACPI_6_3_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 6.3 /// #define EFI_ACPI_6_3_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.3 /// #define EFI_ACPI_6_3_AML_CPC_REVISION 3 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 6.3 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_3_SYSTEM_MEMORY 0x00 #define EFI_ACPI_6_3_SYSTEM_IO 0x01 #define EFI_ACPI_6_3_PCI_CONFIGURATION_SPACE 0x02 #define EFI_ACPI_6_3_EMBEDDED_CONTROLLER 0x03 #define EFI_ACPI_6_3_SMBUS 0x04 #define EFI_ACPI_6_3_SYSTEM_CMOS 0x05 #define EFI_ACPI_6_3_PCI_BAR_TARGET 0x06 #define EFI_ACPI_6_3_IPMI 0x07 #define EFI_ACPI_6_3_GENERAL_PURPOSE_IO 0x08 #define EFI_ACPI_6_3_GENERIC_SERIAL_BUS 0x09 #define EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_3_UNDEFINED 0 #define EFI_ACPI_6_3_BYTE 1 #define EFI_ACPI_6_3_WORD 2 #define EFI_ACPI_6_3_DWORD 3 #define EFI_ACPI_6_3_QWORD 4 // // ACPI 6.3 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.3) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_3_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x03 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_3_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_3_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_3_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_3_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_3_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_3_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_3_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_3_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_3_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_3_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_3_8042 BIT1 #define EFI_ACPI_6_3_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_3_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_3_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_3_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_3_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_3_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_3_WBINVD BIT0 #define EFI_ACPI_6_3_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_3_PROC_C1 BIT2 #define EFI_ACPI_6_3_P_LVL2_UP BIT3 #define EFI_ACPI_6_3_PWR_BUTTON BIT4 #define EFI_ACPI_6_3_SLP_BUTTON BIT5 #define EFI_ACPI_6_3_FIX_RTC BIT6 #define EFI_ACPI_6_3_RTC_S4 BIT7 #define EFI_ACPI_6_3_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_3_DCK_CAP BIT9 #define EFI_ACPI_6_3_RESET_REG_SUP BIT10 #define EFI_ACPI_6_3_SEALED_CASE BIT11 #define EFI_ACPI_6_3_HEADLESS BIT12 #define EFI_ACPI_6_3_CPU_SW_SLP BIT13 #define EFI_ACPI_6_3_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_3_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_3_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_3_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_3_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_3_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_3_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_3_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_3_S4BIOS_F BIT0 #define EFI_ACPI_6_3_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_3_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x05 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_3_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x0D and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_3_IO_APIC 0x01 #define EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_3_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_3_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_3_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_3_IO_SAPIC 0x06 #define EFI_ACPI_6_3_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_3_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_3_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_3_GIC 0x0B #define EFI_ACPI_6_3_GICD 0x0C #define EFI_ACPI_6_3_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_3_GICR 0x0E #define EFI_ACPI_6_3_GIC_ITS 0x0F // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_LOCAL_APIC_ENABLED BIT0 #define EFI_ACPI_6_3_LOCAL_APIC_ONLINE_CAPABLE BIT1 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_3_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_3_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_3_POLARITY (3 << 0) #define EFI_ACPI_6_3_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_3_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_3_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_3_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_3_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_3_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_3_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_3_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_3_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2; UINT16 SpeOverflowInterrupt; } EFI_ACPI_6_3_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GIC_ENABLED BIT0 #define EFI_ACPI_6_3_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_3_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_3_GIC_V1 0x01 #define EFI_ACPI_6_3_GIC_V2 0x02 #define EFI_ACPI_6_3_GIC_V3 0x03 #define EFI_ACPI_6_3_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_3_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_3_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_3_GIC_ITS_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_3_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_3_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x06 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_3_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_3_GICC_AFFINITY 0x03 #define EFI_ACPI_6_3_GIC_ITS_AFFINITY 0x04 #define EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY 0x05 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_3_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_3_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_3_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GICC_ENABLED (1 << 0) /// /// GIC Interrupt Translation Service (ITS) Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT8 Reserved[2]; UINT32 ItsId; } EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE; // // Generic Initiator Affinity Structure Device Handle Types // All other values between 0x02 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_3_ACPI_DEVICE_HANDLE 0x00 #define EFI_ACPI_6_3_PCI_DEVICE_HANDLE 0x01 /// /// Device Handle - ACPI /// typedef struct { UINT64 AcpiHid; UINT32 AcpiUid; UINT8 Reserved[4]; } EFI_ACPI_6_3_DEVICE_HANDLE_ACPI; /// /// Device Handle - PCI /// typedef struct { UINT16 PciSegment; UINT16 PciBdfNumber; UINT8 Reserved[12]; } EFI_ACPI_6_3_DEVICE_HANDLE_PCI; /// /// Generic Initiator Affinity Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1; UINT8 DeviceHandleType; UINT32 ProximityDomain; union { EFI_ACPI_6_3_DEVICE_HANDLE_ACPI Acpi; EFI_ACPI_6_3_DEVICE_HANDLE_PCI Pci; } DeviceHandle; UINT32 Flags; UINT8 Reserved2[4]; } EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE; /// /// Generic Initiator Affinity Structure Flags. All other bits are reserved /// and must be 0. /// #define EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE_ENABLED (1 << 0) /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_3_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_3_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_3_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_3_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_3_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_3_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_3_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_3_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_3_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED BIT0 #define EFI_ACPI_6_3_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED_AND_EXPOSED_TO_SOFTWARE BIT1 #define EFI_ACPI_6_3_RASF_PLATFORM_RAS_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT2 #define EFI_ACPI_6_3_RASF_PLATFORM_RAS_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT3 #define EFI_ACPI_6_3_RASF_PLATFORM_RAS_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT4 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_3_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_3_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_3_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_3_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_3_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_3_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_3_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_3_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_3_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_3_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_3_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_3_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_MEMORY_TOPOLOGY_TABLE_REVISION 0x01 /// /// Common Memory Aggregator Device Structure. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; } EFI_ACPI_6_3_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Memory Aggregator Device Type /// #define EFI_ACPI_6_3_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_3_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_3_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM 0x2 /// /// Socket Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_3_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_3_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[]; } EFI_ACPI_6_3_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// MemoryController Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_3_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT32 ReadLatency; UINT32 WriteLatency; UINT32 ReadBandwidth; UINT32 WriteBandwidth; UINT16 OptimalAccessUnit; UINT16 OptimalAccessAlignment; UINT16 Reserved; UINT16 NumberOfProximityDomains; // UINT32 ProximityDomain[NumberOfProximityDomains]; // EFI_ACPI_6_3_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[]; } EFI_ACPI_6_3_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// DIMM Memory Aggregator Device Structure. /// typedef struct { EFI_ACPI_6_3_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header; UINT16 PhysicalComponentIdentifier; UINT16 Reserved; UINT32 SizeOfDimm; UINT32 SmbiosHandle; } EFI_ACPI_6_3_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:1] = Reserved (must be zero) /// Bit [0] = Valid. A one indicates the boot image graphic is valid. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_3_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_3_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_3_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_3_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_3_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_3_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_3_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_3_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_3_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_3_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_3_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_3_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior towhen the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_3_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_3_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_3_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_3_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_3_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_3_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_3_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_3_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_3_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; UINT32 VirtualPL2TimerGSIV; UINT32 VirtualPL2TimerFlags; } EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x03 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_3_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_3_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// SBSA Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE; /// /// SBSA Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.3 spec.) // #define EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE 1 #define EFI_ACPI_6_3_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_3_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_3_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_3_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 #define EFI_ACPI_6_3_NFIT_PLATFORM_CAPABILITIES_STRUCTURE_TYPE 7 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_3_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_3_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_3_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_3_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_3_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_3_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_3_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_3_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_3_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; } EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_3_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 #define EFI_ACPI_6_3_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_NOT_MAP_NVDIMM_TO_SPA BIT6 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_3_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NVDIMMPhysicalID; UINT16 NVDIMMRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 NVDIMMRegionSize; UINT64 RegionOffset; UINT64 NVDIMMPhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 NVDIMMStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_3_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_3_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_VALID_FIELDS_MANUFACTURING BIT0 #define EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 ValidFields; UINT8 ManufacturingLocation; UINT16 ManufacturingDate; UINT8 Reserved_22[2]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_3_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_3_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_3_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; // // Definition for Platform Capabilities Structure // typedef struct { UINT16 Type; UINT16 Length; UINT8 HighestValidCapability; UINT8 Reserved_5[3]; UINT32 Capabilities; UINT8 Reserved_12[4]; } EFI_ACPI_6_3_NFIT_PLATFORM_CAPABILITIES_STRUCTURE; #define EFI_ACPI_6_3_NFIT_PLATFORM_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT0 #define EFI_ACPI_6_3_NFIT_PLATFORM_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT1 #define EFI_ACPI_6_3_NFIT_PLATFORM_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT2 /// /// Secure DEVices Table (SDEV) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_3_SECURE_DEVICES_TABLE_HEADER; /// /// SDEV Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_SECURE_DEVICES_TABLE_REVISION 0x01 /// /// Secure Devcice types /// #define EFI_ACPI_6_3_SDEV_TYPE_PCIE_ENDPOINT_DEVICE 0x01 #define EFI_ACPI_6_3_SDEV_TYPE_ACPI_NAMESPACE_DEVICE 0x00 /// /// Secure Devcice flags /// #define EFI_ACPI_6_3_SDEV_FLAG_ALLOW_HANDOFF BIT0 /// /// SDEV Structure Header /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; } EFI_ACPI_6_3_SDEV_STRUCTURE_HEADER; /// /// PCIe Endpoint Device based Secure Device Structure /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; UINT16 PciSegmentNumber; UINT16 StartBusNumber; UINT16 PciPathOffset; UINT16 PciPathLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_3_SDEV_STRUCTURE_PCIE_ENDPOINT_DEVICE; /// /// ACPI_NAMESPACE_DEVICE based Secure Device Structure /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; UINT16 DeviceIdentifierOffset; UINT16 DeviceIdentifierLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_3_SDEV_STRUCTURE_ACPI_NAMESPACE_DEVICE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_3_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_3_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_3_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_3_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_3_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_3_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_3_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_3_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; UINT8 Timestamp[8]; } EFI_ACPI_6_3_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0300 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_3_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_3_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_3_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_3_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_3_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR 0x09 #define EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_VERSION_2 0x0A #define EFI_ACPI_6_3_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK 0x0B // // Error Source structure flags. // #define EFI_ACPI_6_3_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_3_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) #define EFI_ACPI_6_3_ERROR_SOURCE_FLAG_GHES_ASSIST (1 << 2) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_3_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEA 0x08 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEI 0x09 #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_GSIV 0x0A #define EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION 0x0B /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_3_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_3_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_3_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_3_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_3_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Hardware Error Source Version 2 Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ReadAckRegister; UINT64 ReadAckPreserve; UINT64 ReadAckWrite; } EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_3_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_3_GENERIC_ERROR_STATUS_STRUCTURE; /// /// IA-32 Architecture Deferred Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_3_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_3_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE; /// /// HMAT - Heterogeneous Memory Attribute Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[4]; } EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER; /// /// HMAT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION 0x02 /// /// HMAT types /// #define EFI_ACPI_6_3_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES 0x00 #define EFI_ACPI_6_3_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO 0x01 #define EFI_ACPI_6_3_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO 0x02 /// /// HMAT Structure Header /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; } EFI_ACPI_6_3_HMAT_STRUCTURE_HEADER; /// /// Memory Proximity Domain Attributes Structure flags /// typedef struct { UINT16 InitiatorProximityDomainValid : 1; UINT16 Reserved : 15; } EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS; /// /// Memory Proximity Domain Attributes Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS Flags; UINT8 Reserved1[2]; UINT32 InitiatorProximityDomain; UINT32 MemoryProximityDomain; UINT8 Reserved2[20]; } EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES; /// /// System Locality Latency and Bandwidth Information Structure flags /// typedef struct { UINT8 MemoryHierarchy : 4; UINT8 Reserved : 4; } EFI_ACPI_6_3_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS; /// /// System Locality Latency and Bandwidth Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_3_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS Flags; UINT8 DataType; UINT8 Reserved1[2]; UINT32 NumberOfInitiatorProximityDomains; UINT32 NumberOfTargetProximityDomains; UINT8 Reserved2[4]; UINT64 EntryBaseUnit; } EFI_ACPI_6_3_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO; /// /// Memory Side Cache Information Structure cache attributes /// typedef struct { UINT32 TotalCacheLevels : 4; UINT32 CacheLevel : 4; UINT32 CacheAssociativity : 4; UINT32 WritePolicy : 4; UINT32 CacheLineSize : 16; } EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES; /// /// Memory Side Cache Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; UINT32 MemoryProximityDomain; UINT8 Reserved1[4]; UINT64 MemorySideCacheSize; EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES CacheAttributes; UINT8 Reserved2[2]; UINT16 NumberOfSmbiosHandles; } EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_3_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_3_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_3_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_3_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_3_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_3_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_3_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_3_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_3_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_3_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_3_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_3_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_3_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_3_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_3_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_3_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F #define EFI_ACPI_6_3_ERST_GET_EXECUTE_OPERATION_TIMINGS 0x10 /// /// ERST Action Command Status /// #define EFI_ACPI_6_3_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_3_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_3_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_3_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_3_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_3_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_3_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_3_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_3_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_3_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_3_ERST_NOOP 0x04 #define EFI_ACPI_6_3_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_3_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_3_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_3_ERST_ADD 0x08 #define EFI_ACPI_6_3_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_3_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_3_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_3_ERST_STALL 0x0C #define EFI_ACPI_6_3_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_3_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_3_ERST_GOTO 0x0F #define EFI_ACPI_6_3_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_3_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_3_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_3_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_3_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_3_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_3_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_3_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_3_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_3_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_3_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_3_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_3_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_3_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_3_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_3_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_3_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_3_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_3_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_3_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_3_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_3_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_3_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_3_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_3_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_3_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_3_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_3_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_3_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_3_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_3_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_3_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_3_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_3_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_3_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_3_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_3_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_3_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_3_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_3_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x02 /// /// PCCT Global Flags /// #define EFI_ACPI_6_3_PCCT_FLAGS_PLATFORM_INTERRUPT BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 #define EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC 0x03 #define EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC 0x04 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_3_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_3_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 NotifyOnCompletion : 1; } EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 PlatformInterrupt : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_3_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_3_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_3_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckWrite; } EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; /// /// Type 3 Extended PCC Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT32 AddressLength; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT32 MinimumRequestTurnaroundTime; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckSet; UINT8 Reserved1[8]; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE CommandCompleteUpdateRegister; UINT64 CommandCompleteUpdatePreserve; UINT64 CommandCompleteUpdateSet; EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; } EFI_ACPI_6_3_PCCT_SUBSPACE_3_EXTENDED_PCC; /// /// Type 4 Extended PCC Subspace Structure /// typedef EFI_ACPI_6_3_PCCT_SUBSPACE_3_EXTENDED_PCC EFI_ACPI_6_3_PCCT_SUBSPACE_4_EXTENDED_PCC; #define EFI_ACPI_6_3_PCCT_MASTER_SLAVE_COMMUNICATIONS_CHANNEL_FLAGS_NOTIFY_ON_COMPLETION BIT0 typedef struct { UINT32 Signature; UINT32 Flags; UINT32 Length; UINT32 Command; } EFI_ACPI_6_3_PCCT_EXTENDED_PCC_SHARED_MEMORY_REGION_HEADER; /// /// Platform Debug Trigger Table (PDTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 TriggerCount; UINT8 Reserved[3]; UINT32 TriggerIdentifierArrayOffset; } EFI_ACPI_6_3_PLATFORM_DEBUG_TRIGGER_TABLE_HEADER; /// /// PDTT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_PLATFORM_DEBUG_TRIGGER_TABLE_REVISION 0x00 /// /// PDTT Platform Communication Channel Identifier Structure /// typedef struct { UINT16 SubChannelIdentifer : 8; UINT16 Runtime : 1; UINT16 WaitForCompletion : 1; UINT16 TriggerOrder : 1; UINT16 Reserved : 5; } EFI_ACPI_6_3_PDTT_PCC_IDENTIFIER; /// /// PCC Commands Codes used by Platform Debug Trigger Table /// #define EFI_ACPI_6_3_PDTT_PCC_COMMAND_DOORBELL_ONLY 0x00 #define EFI_ACPI_6_3_PDTT_PCC_COMMAND_VENDOR_SPECIFIC 0x01 /// /// PPTT Platform Communication Channel /// typedef EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER EFI_ACPI_6_3_PDTT_PCC; /// /// Processor Properties Topology Table (PPTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER; /// /// PPTT Revision (as defined in ACPI 6.3 spec.) /// #define EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION 0x02 /// /// PPTT types /// #define EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR 0x00 #define EFI_ACPI_6_3_PPTT_TYPE_CACHE 0x01 #define EFI_ACPI_6_3_PPTT_TYPE_ID 0x02 /// /// PPTT Structure Header /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; } EFI_ACPI_6_3_PPTT_STRUCTURE_HEADER; /// /// For PPTT struct processor flags /// #define EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL 0x0 #define EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL 0x1 #define EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID 0x1 #define EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD 0x0 #define EFI_ACPI_6_3_PPTT_PROCESSOR_IS_THREAD 0x1 #define EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF 0x0 #define EFI_ACPI_6_3_PPTT_NODE_IS_LEAF 0x1 #define EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL 0x0 #define EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL 0x1 /// /// Processor hierarchy node structure flags /// typedef struct { UINT32 PhysicalPackage : 1; UINT32 AcpiProcessorIdValid : 1; UINT32 ProcessorIsAThread : 1; UINT32 NodeIsALeaf : 1; UINT32 IdenticalImplementation : 1; UINT32 Reserved : 27; } EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR_FLAGS; /// /// Processor hierarchy node structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR_FLAGS Flags; UINT32 Parent; UINT32 AcpiProcessorId; UINT32 NumberOfPrivateResources; } EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR; /// /// For PPTT struct cache flags /// #define EFI_ACPI_6_3_PPTT_CACHE_SIZE_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_CACHE_SIZE_VALID 0x1 #define EFI_ACPI_6_3_PPTT_NUMBER_OF_SETS_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_NUMBER_OF_SETS_VALID 0x1 #define EFI_ACPI_6_3_PPTT_ASSOCIATIVITY_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_ASSOCIATIVITY_VALID 0x1 #define EFI_ACPI_6_3_PPTT_ALLOCATION_TYPE_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_ALLOCATION_TYPE_VALID 0x1 #define EFI_ACPI_6_3_PPTT_CACHE_TYPE_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_CACHE_TYPE_VALID 0x1 #define EFI_ACPI_6_3_PPTT_WRITE_POLICY_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_WRITE_POLICY_VALID 0x1 #define EFI_ACPI_6_3_PPTT_LINE_SIZE_INVALID 0x0 #define EFI_ACPI_6_3_PPTT_LINE_SIZE_VALID 0x1 /// /// Cache Type Structure flags /// typedef struct { UINT32 SizePropertyValid : 1; UINT32 NumberOfSetsValid : 1; UINT32 AssociativityValid : 1; UINT32 AllocationTypeValid : 1; UINT32 CacheTypeValid : 1; UINT32 WritePolicyValid : 1; UINT32 LineSizeValid : 1; UINT32 Reserved : 25; } EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_FLAGS; /// /// For cache attributes /// #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ 0x0 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_WRITE 0x1 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE 0x2 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_DATA 0x0 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION 0x1 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED 0x2 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK 0x0 #define EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_THROUGH 0x1 /// /// Cache Type Structure cache attributes /// typedef struct { UINT8 AllocationType : 2; UINT8 CacheType : 2; UINT8 WritePolicy : 1; UINT8 Reserved : 3; } EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_ATTRIBUTES; /// /// Cache Type Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_FLAGS Flags; UINT32 NextLevelOfCache; UINT32 Size; UINT32 NumberOfSets; UINT8 Associativity; EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_ATTRIBUTES Attributes; UINT16 LineSize; } EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE; /// /// ID structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 VendorId; UINT64 Level1Id; UINT64 Level2Id; UINT16 MajorRev; UINT16 MinorRev; UINT16 SpinRev; } EFI_ACPI_6_3_PPTT_STRUCTURE_ID; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CDIT" Component Distance Information Table /// #define EFI_ACPI_6_3_COMPONENT_DISTANCE_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('C', 'D', 'I', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_3_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "CRAT" Component Resource Attribute Table /// #define EFI_ACPI_6_3_COMPONENT_RESOURCE_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('C', 'R', 'A', 'T') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_3_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_3_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_3_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_3_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "HMAT" Heterogeneous Memory Attribute Table /// #define EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('H', 'M', 'A', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_3_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_3_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PDTT" Platform Debug Trigger Table /// #define EFI_ACPI_6_3_PLATFORM_DEBUG_TRIGGER_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'D', 'T', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_3_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PPTT" Processor Properties Topology Table /// #define EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'P', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_3_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_3_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_3_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SDEV" Secure DEVices Table /// #define EFI_ACPI_6_3_SECURE_DEVICES_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'V') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_3_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_3_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_3_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_3_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DPPT" DMA Protection Policy Table /// #define EFI_ACPI_6_3_DMA_PROTECTION_POLICY_TABLE_SIGNATURE SIGNATURE_32('D', 'P', 'P', 'T') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_3_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_3_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_3_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_3_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_3_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_3_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_3_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_3_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "SDEI" Software Delegated Exceptions Interface Table /// #define EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'I') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_3_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Concole Redirection Table /// #define EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_3_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_3_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_3_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_3_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_3_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_3_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_3_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_3_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_3_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "WSMT" Windows SMM Security Mitigation Table /// #define EFI_ACPI_6_3_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE SIGNATURE_32('W', 'S', 'M', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_3_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi64.h ================================================ /** @file ACPI 6.4 definitions from the ACPI Specification Revision 6.4 Jan, 2021. Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2019 - 2021, ARM Ltd. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef ACPI_6_4_H_ #define ACPI_6_4_H_ #include "Acpi63.h" /// /// _CSD Revision for ACPI 6.4 /// #define EFI_ACPI_6_4_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.4 /// #define EFI_ACPI_6_4_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 6.4 /// #define EFI_ACPI_6_4_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.4 /// #define EFI_ACPI_6_4_AML_CPC_REVISION 3 // // Ensure proper structure formats // #pragma pack(1) /// /// ACPI 6.4 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_4_SYSTEM_MEMORY 0x00 #define EFI_ACPI_6_4_SYSTEM_IO 0x01 #define EFI_ACPI_6_4_PCI_CONFIGURATION_SPACE 0x02 #define EFI_ACPI_6_4_EMBEDDED_CONTROLLER 0x03 #define EFI_ACPI_6_4_SMBUS 0x04 #define EFI_ACPI_6_4_SYSTEM_CMOS 0x05 #define EFI_ACPI_6_4_PCI_BAR_TARGET 0x06 #define EFI_ACPI_6_4_IPMI 0x07 #define EFI_ACPI_6_4_GENERAL_PURPOSE_IO 0x08 #define EFI_ACPI_6_4_GENERIC_SERIAL_BUS 0x09 #define EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_4_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_4_UNDEFINED 0 #define EFI_ACPI_6_4_BYTE 1 #define EFI_ACPI_6_4_WORD 2 #define EFI_ACPI_6_4_DWORD 3 #define EFI_ACPI_6_4_QWORD 4 // // ACPI 6.4 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_4_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.4) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_4_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_4_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_4_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x04 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_4_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_4_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_4_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_4_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_4_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_4_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_4_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_4_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_4_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_4_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_4_8042 BIT1 #define EFI_ACPI_6_4_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_4_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_4_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_4_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_4_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_4_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_4_WBINVD BIT0 #define EFI_ACPI_6_4_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_4_PROC_C1 BIT2 #define EFI_ACPI_6_4_P_LVL2_UP BIT3 #define EFI_ACPI_6_4_PWR_BUTTON BIT4 #define EFI_ACPI_6_4_SLP_BUTTON BIT5 #define EFI_ACPI_6_4_FIX_RTC BIT6 #define EFI_ACPI_6_4_RTC_S4 BIT7 #define EFI_ACPI_6_4_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_4_DCK_CAP BIT9 #define EFI_ACPI_6_4_RESET_REG_SUP BIT10 #define EFI_ACPI_6_4_SEALED_CASE BIT11 #define EFI_ACPI_6_4_HEADLESS BIT12 #define EFI_ACPI_6_4_CPU_SW_SLP BIT13 #define EFI_ACPI_6_4_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_4_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_4_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_4_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_4_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_4_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_4_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_4_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_4_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_4_S4BIOS_F BIT0 #define EFI_ACPI_6_4_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_4_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_4_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_4_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x05 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_4_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x10 and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_4_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_4_IO_APIC 0x01 #define EFI_ACPI_6_4_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_4_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_4_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_4_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_4_IO_SAPIC 0x06 #define EFI_ACPI_6_4_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_4_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_4_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_4_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_4_GIC 0x0B #define EFI_ACPI_6_4_GICD 0x0C #define EFI_ACPI_6_4_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_4_GICR 0x0E #define EFI_ACPI_6_4_GIC_ITS 0x0F #define EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP 0x10 // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_4_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_LOCAL_APIC_ENABLED BIT0 #define EFI_ACPI_6_4_LOCAL_APIC_ONLINE_CAPABLE BIT1 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_4_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_4_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_4_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_4_POLARITY (3 << 0) #define EFI_ACPI_6_4_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_4_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_4_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_4_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_4_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_4_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_4_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_4_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_4_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_4_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2; UINT16 SpeOverflowInterrupt; } EFI_ACPI_6_4_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GIC_ENABLED BIT0 #define EFI_ACPI_6_4_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_4_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_4_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_4_GIC_V1 0x01 #define EFI_ACPI_6_4_GIC_V2 0x02 #define EFI_ACPI_6_4_GIC_V3 0x03 #define EFI_ACPI_6_4_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_4_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_4_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_4_GIC_ITS_STRUCTURE; /// /// Multiprocessor Wakeup Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 MailBoxVersion; UINT32 Reserved; UINT64 MailBoxAddress; } EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE; /// /// Multiprocessor Wakeup Mailbox Structure /// typedef struct { UINT16 Command; UINT16 Reserved; UINT32 AcpiId; UINT64 WakeupVector; UINT8 ReservedForOs[2032]; UINT8 ReservedForFirmware[2048]; } EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_MAILBOX_STRUCTURE; #define EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_NOOP 0x0000 #define EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_WAKEUP 0x0001 /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_4_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_4_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x06 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_4_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_4_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_4_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_4_GICC_AFFINITY 0x03 #define EFI_ACPI_6_4_GIC_ITS_AFFINITY 0x04 #define EFI_ACPI_6_4_GENERIC_INITIATOR_AFFINITY 0x05 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_4_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_4_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_4_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_4_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_4_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GICC_ENABLED (1 << 0) /// /// GIC Interrupt Translation Service (ITS) Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT8 Reserved[2]; UINT32 ItsId; } EFI_ACPI_6_4_GIC_ITS_AFFINITY_STRUCTURE; // // Generic Initiator Affinity Structure Device Handle Types // All other values between 0x02 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_4_ACPI_DEVICE_HANDLE 0x00 #define EFI_ACPI_6_4_PCI_DEVICE_HANDLE 0x01 /// /// Device Handle - ACPI /// typedef struct { UINT64 AcpiHid; UINT32 AcpiUid; UINT8 Reserved[4]; } EFI_ACPI_6_4_DEVICE_HANDLE_ACPI; /// /// Device Handle - PCI /// typedef struct { UINT16 PciSegment; UINT16 PciBdfNumber; UINT8 Reserved[12]; } EFI_ACPI_6_4_DEVICE_HANDLE_PCI; /// /// Device Handle /// typedef union { EFI_ACPI_6_4_DEVICE_HANDLE_ACPI Acpi; EFI_ACPI_6_4_DEVICE_HANDLE_PCI Pci; } EFI_ACPI_6_4_DEVICE_HANDLE; /// /// Generic Initiator Affinity Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1; UINT8 DeviceHandleType; UINT32 ProximityDomain; EFI_ACPI_6_4_DEVICE_HANDLE DeviceHandle; UINT32 Flags; UINT8 Reserved2[4]; } EFI_ACPI_6_4_GENERIC_INITIATOR_AFFINITY_STRUCTURE; /// /// Generic Initiator Affinity Structure Flags. All other bits are reserved /// and must be 0. /// #define EFI_ACPI_6_4_GENERIC_INITIATOR_AFFINITY_STRUCTURE_ENABLED BIT0 #define EFI_ACPI_6_4_GENERIC_INITIATOR_AFFINITY_STRUCTURE_ARCHITECTURAL_TRANSACTIONS BIT1 /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_4_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_4_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_4_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_4_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_4_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_4_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_4_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_4_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_4_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_4_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED BIT0 #define EFI_ACPI_6_4_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED_AND_EXPOSED_TO_SOFTWARE BIT1 #define EFI_ACPI_6_4_RASF_PLATFORM_RAS_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT2 #define EFI_ACPI_6_4_RASF_PLATFORM_RAS_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT3 #define EFI_ACPI_6_4_RASF_PLATFORM_RAS_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT4 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_4_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_4_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_4_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_4_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_4_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_4_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_4_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_4_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_4_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_4_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_4_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Platform Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 NumberOfMemoryDevices; // EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[NumberOfMemoryDevices]; } EFI_ACPI_6_4_PLATFORM_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_MEMORY_TOPOLOGY_TABLE_REVISION 0x02 /// /// Common Memory Device. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; UINT32 NumberOfMemoryDevices; // UINT8 TypeSpecificData[]; // EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[NumberOfMemoryDevices]; } EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE; /// /// Memory Device Type. /// #define EFI_ACPI_6_4_PMTT_MEMORY_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_4_PMTT_MEMORY_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_4_PMTT_MEMORY_DEVICE_TYPE_DIMM 0x2 #define EFI_ACPI_6_4_PMTT_MEMORY_DEVICE_TYPE_VENDOR_SPECIFIC_TYPE 0xFF /// /// Socket Type Data. /// typedef struct { EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_4_PMTT_SOCKET_TYPE_DATA; /// /// Memory Controller Type Data. /// typedef struct { EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT16 MemoryControllerIdentifier; UINT16 Reserved; // EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_4_PMTT_MEMORY_CONTROLLER_TYPE_DATA; /// /// DIMM Type Specific Data. /// typedef struct { EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT32 SmbiosHandle; } EFI_ACPI_6_4_PMTT_DIMM_TYPE_SPECIFIC_DATA; /// /// Vendor Specific Type Data. /// typedef struct { EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT8 TypeUuid[16]; // EFI_ACPI_6_4_PMTT_VENDOR_SPECIFIC_TYPE_DATA VendorSpecificData[]; // EFI_ACPI_6_4_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_4_PMTT_VENDOR_SPECIFIC_TYPE_DATA; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:3] = Reserved (must be zero) /// Bits[2:1] = Orientation Offset. These bits describe the clockwise /// degree offset from the image's default orientation. /// [00] = 0, no offset /// [01] = 90 /// [10] = 180 /// [11] = 270 /// Bit [0] = Displayed. A one indicates the boot image graphic is /// displayed. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_4_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_4_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_4_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_4_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_4_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_4_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_4_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_4_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_4_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_4_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_4_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_4_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_4_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_4_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior towhen the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_4_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_4_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_4_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_4_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_4_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_4_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_4_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_4_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_4_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; UINT32 VirtualPL2TimerGSIV; UINT32 VirtualPL2TimerFlags; } EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x03 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_4_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_4_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_4_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_4_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_4_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_4_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_4_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// Arm Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG_STRUCTURE; /// /// Arm Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_4_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.4 spec.) // #define EFI_ACPI_6_4_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_4_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_4_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE 1 #define EFI_ACPI_6_4_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_4_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_4_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_4_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_4_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 #define EFI_ACPI_6_4_NFIT_PLATFORM_CAPABILITIES_STRUCTURE_TYPE 7 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_4_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_4_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_4_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_4_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_SPA_LOCATION_COOKIE_VALID BIT2 #define EFI_ACPI_6_4_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_4_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_4_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_4_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_4_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_4_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_4_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_4_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; UINT64 SPALocationCookie; } EFI_ACPI_6_4_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_4_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 #define EFI_ACPI_6_4_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_NOT_MAP_NVDIMM_TO_SPA BIT6 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_4_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NVDIMMPhysicalID; UINT16 NVDIMMRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 NVDIMMRegionSize; UINT64 RegionOffset; UINT64 NVDIMMPhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 NVDIMMStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_4_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_4_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_4_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_4_NFIT_NVDIMM_CONTROL_REGION_VALID_FIELDS_MANUFACTURING BIT0 #define EFI_ACPI_6_4_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 ValidFields; UINT8 ManufacturingLocation; UINT16 ManufacturingDate; UINT8 Reserved_22[2]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_4_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_4_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_4_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_4_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; // // Definition for Platform Capabilities Structure // typedef struct { UINT16 Type; UINT16 Length; UINT8 HighestValidCapability; UINT8 Reserved_5[3]; UINT32 Capabilities; UINT8 Reserved_12[4]; } EFI_ACPI_6_4_NFIT_PLATFORM_CAPABILITIES_STRUCTURE; #define EFI_ACPI_6_4_NFIT_PLATFORM_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT0 #define EFI_ACPI_6_4_NFIT_PLATFORM_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT1 #define EFI_ACPI_6_4_NFIT_PLATFORM_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT2 /// /// Secure DEVices Table (SDEV) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_4_SECURE_DEVICES_TABLE_HEADER; /// /// SDEV Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_SECURE_DEVICES_TABLE_REVISION 0x01 /// /// Secure Device types /// #define EFI_ACPI_6_4_SDEV_TYPE_ACPI_NAMESPACE_DEVICE 0x00 #define EFI_ACPI_6_4_SDEV_TYPE_PCIE_ENDPOINT_DEVICE 0x01 /// /// Secure Device flags /// #define EFI_ACPI_6_4_SDEV_FLAG_ALLOW_HANDOFF BIT0 #define EFI_ACPI_6_4_SDEV_FLAG_SECURE_ACCESS_COMPONENTS_PRESENT BIT1 /// /// SDEV Structure Header /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; } EFI_ACPI_6_4_SDEV_STRUCTURE_HEADER; /// /// ACPI_NAMESPACE_DEVICE based Secure Device Structure /// typedef struct { EFI_ACPI_6_4_SDEV_STRUCTURE_HEADER Header; UINT16 DeviceIdentifierOffset; UINT16 DeviceIdentifierLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; UINT16 SecureAccessComponentsOffset; UINT16 SecureAccessComponentsLength; } EFI_ACPI_6_4_SDEV_STRUCTURE_ACPI_NAMESPACE_DEVICE; /// /// Secure Access Component Types /// #define EFI_ACPI_6_4_SDEV_SECURE_ACCESS_COMPONENT_TYPE_IDENTIFICATION 0x00 #define EFI_ACPI_6_4_SDEV_SECURE_ACCESS_COMPONENT_TYPE_MEMORY 0x01 /// /// Identification Based Secure Access Component /// typedef struct { EFI_ACPI_6_4_SDEV_STRUCTURE_HEADER Header; UINT16 HardwareIdentifierOffset; UINT16 HardwareIdentifierLength; UINT16 SubsystemIdentifierOffset; UINT16 SubsystemIdentifierLength; UINT16 HardwareRevision; UINT8 HardwareRevisionPresent; UINT8 ClassCodePresent; UINT8 PciCompatibleBaseClass; UINT8 PciCompatibleSubClass; UINT8 PciCompatibleProgrammingInterface; } EFI_ACPI_6_4_SDEV_SECURE_ACCESS_COMPONENT_IDENTIFICATION_STRUCTURE; /// /// Memory-based Secure Access Component /// typedef struct { EFI_ACPI_6_4_SDEV_STRUCTURE_HEADER Header; UINT32 Reserved; UINT64 MemoryAddressBase; UINT64 MemoryLength; } EFI_ACPI_6_4_SDEV_SECURE_ACCESS_COMPONENT_MEMORY_STRUCTURE; /// /// PCIe Endpoint Device based Secure Device Structure /// typedef struct { EFI_ACPI_6_4_SDEV_STRUCTURE_HEADER Header; UINT16 PciSegmentNumber; UINT16 StartBusNumber; UINT16 PciPathOffset; UINT16 PciPathLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_4_SDEV_STRUCTURE_PCIE_ENDPOINT_DEVICE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_4_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_4_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_4_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_4_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_4_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_4_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_4_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_4_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_4_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; UINT8 Timestamp[8]; } EFI_ACPI_6_4_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0300 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_4_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01 // // Error Source structure types. // #define EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_4_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_4_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_4_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_4_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_4_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_4_GENERIC_HARDWARE_ERROR 0x09 #define EFI_ACPI_6_4_GENERIC_HARDWARE_ERROR_VERSION_2 0x0A #define EFI_ACPI_6_4_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK 0x0B // // Error Source structure flags. // #define EFI_ACPI_6_4_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_4_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) #define EFI_ACPI_6_4_ERROR_SOURCE_FLAG_GHES_ASSIST (1 << 2) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_4_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEA 0x08 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEI 0x09 #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_GSIV 0x0A #define EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION 0x0B /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_4_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_4_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_4_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_4_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_4_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_4_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Hardware Error Source Version 2 Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReadAckRegister; UINT64 ReadAckPreserve; UINT64 ReadAckWrite; } EFI_ACPI_6_4_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_4_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_4_GENERIC_ERROR_STATUS_STRUCTURE; /// /// IA-32 Architecture Deferred Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_4_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_4_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE; /// /// HMAT - Heterogeneous Memory Attribute Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[4]; } EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER; /// /// HMAT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION 0x02 /// /// HMAT types /// #define EFI_ACPI_6_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES 0x00 #define EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO 0x01 #define EFI_ACPI_6_4_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO 0x02 /// /// HMAT Structure Header /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; } EFI_ACPI_6_4_HMAT_STRUCTURE_HEADER; /// /// Memory Proximity Domain Attributes Structure flags /// typedef struct { UINT16 InitiatorProximityDomainValid : 1; UINT16 Reserved : 15; } EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS; /// /// Memory Proximity Domain Attributes Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS Flags; UINT8 Reserved1[2]; UINT32 InitiatorProximityDomain; UINT32 MemoryProximityDomain; UINT8 Reserved2[20]; } EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES; /// /// System Locality Latency and Bandwidth Information Structure flags /// typedef struct { UINT8 MemoryHierarchy : 4; UINT8 AccessAttributes : 2; UINT8 Reserved : 2; } EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS; /// /// System Locality Latency and Bandwidth Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS Flags; UINT8 DataType; UINT8 MinTransferSize; UINT8 Reserved1; UINT32 NumberOfInitiatorProximityDomains; UINT32 NumberOfTargetProximityDomains; UINT8 Reserved2[4]; UINT64 EntryBaseUnit; } EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO; /// /// Memory Side Cache Information Structure cache attributes /// typedef struct { UINT32 TotalCacheLevels : 4; UINT32 CacheLevel : 4; UINT32 CacheAssociativity : 4; UINT32 WritePolicy : 4; UINT32 CacheLineSize : 16; } EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES; /// /// Memory Side Cache Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; UINT32 MemoryProximityDomain; UINT8 Reserved1[4]; UINT64 MemorySideCacheSize; EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES CacheAttributes; UINT8 Reserved2[2]; UINT16 NumberOfSmbiosHandles; } EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_4_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_4_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_4_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_4_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_4_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_4_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_4_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_4_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_4_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_4_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_4_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_4_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_4_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_4_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_4_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F #define EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS 0x10 /// /// ERST Action Command Status /// #define EFI_ACPI_6_4_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_4_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_4_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_4_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_4_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_4_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_4_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_4_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_4_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_4_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_4_ERST_NOOP 0x04 #define EFI_ACPI_6_4_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_4_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_4_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_4_ERST_ADD 0x08 #define EFI_ACPI_6_4_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_4_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_4_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_4_ERST_STALL 0x0C #define EFI_ACPI_6_4_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_4_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_4_ERST_GOTO 0x0F #define EFI_ACPI_6_4_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_4_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_4_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_4_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_4_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_4_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_ERROR_INJECTION_TABLE_REVISION 0x01 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_4_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_4_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_4_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_4_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_4_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_4_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_4_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_4_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_4_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_4_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_4_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_4_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_4_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_4_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_4_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_4_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_4_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_4_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_4_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_4_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_4_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_4_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_4_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_4_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_4_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_4_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_4_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_4_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_4_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_4_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_4_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_4_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_4_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_4_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x02 /// /// PCCT Global Flags /// #define EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC 0x03 #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC 0x04 #define EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS 0x05 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_4_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 NotifyOnCompletion : 1; } EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 PlatformInterrupt : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckWrite; } EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; /// /// Type 3 Extended PCC Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT32 AddressLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT32 MinimumRequestTurnaroundTime; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckSet; UINT8 Reserved1[8]; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CommandCompleteUpdateRegister; UINT64 CommandCompleteUpdatePreserve; UINT64 CommandCompleteUpdateSet; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; } EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC; /// /// Type 4 Extended PCC Subspace Structure /// typedef EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC; #define EFI_ACPI_6_4_PCCT_MASTER_SLAVE_COMMUNICATIONS_CHANNEL_FLAGS_NOTIFY_ON_COMPLETION BIT0 typedef struct { UINT32 Signature; UINT32 Flags; UINT32 Length; UINT32 Command; } EFI_ACPI_6_4_PCCT_EXTENDED_PCC_SHARED_MEMORY_REGION_HEADER; /// /// Type 5 HW Registers based Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Version; UINT64 BaseAddress; UINT64 SharedMemoryRangeLength; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; UINT32 NominalLatency; UINT32 MinimumRequestTurnaroundTime; } EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS; /// /// Reduced PCC Subspace Shared Memory Region /// typedef struct { UINT32 Signature; // UINT8 CommunicationSubspace[]; } EFI_6_4_PCCT_REDUCED_PCC_SUBSPACE_SHARED_MEMORY_REGION; /// /// Platform Debug Trigger Table (PDTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 TriggerCount; UINT8 Reserved[3]; UINT32 TriggerIdentifierArrayOffset; } EFI_ACPI_6_4_PLATFORM_DEBUG_TRIGGER_TABLE_HEADER; /// /// PDTT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_PLATFORM_DEBUG_TRIGGER_TABLE_REVISION 0x00 /// /// PDTT Platform Communication Channel Identifier Structure /// typedef struct { UINT16 SubChannelIdentifer : 8; UINT16 Runtime : 1; UINT16 WaitForCompletion : 1; UINT16 TriggerOrder : 1; UINT16 Reserved : 5; } EFI_ACPI_6_4_PDTT_PCC_IDENTIFIER; /// /// PCC Commands Codes used by Platform Debug Trigger Table /// #define EFI_ACPI_6_4_PDTT_PCC_COMMAND_DOORBELL_ONLY 0x00 #define EFI_ACPI_6_4_PDTT_PCC_COMMAND_VENDOR_SPECIFIC 0x01 /// /// PDTT Platform Communication Channel /// typedef EFI_ACPI_6_4_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER EFI_ACPI_6_4_PDTT_PCC; /// /// Processor Properties Topology Table (PPTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER; /// /// PPTT Revision (as defined in ACPI 6.4 spec.) /// #define EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION 0x03 /// /// PPTT types /// #define EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR 0x00 #define EFI_ACPI_6_4_PPTT_TYPE_CACHE 0x01 /// /// PPTT Structure Header /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; } EFI_ACPI_6_4_PPTT_STRUCTURE_HEADER; /// /// For PPTT struct processor flags /// #define EFI_ACPI_6_4_PPTT_PACKAGE_NOT_PHYSICAL 0x0 #define EFI_ACPI_6_4_PPTT_PACKAGE_PHYSICAL 0x1 #define EFI_ACPI_6_4_PPTT_PROCESSOR_ID_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_PROCESSOR_ID_VALID 0x1 #define EFI_ACPI_6_4_PPTT_PROCESSOR_IS_NOT_THREAD 0x0 #define EFI_ACPI_6_4_PPTT_PROCESSOR_IS_THREAD 0x1 #define EFI_ACPI_6_4_PPTT_NODE_IS_NOT_LEAF 0x0 #define EFI_ACPI_6_4_PPTT_NODE_IS_LEAF 0x1 #define EFI_ACPI_6_4_PPTT_IMPLEMENTATION_NOT_IDENTICAL 0x0 #define EFI_ACPI_6_4_PPTT_IMPLEMENTATION_IDENTICAL 0x1 /// /// Processor hierarchy node structure flags /// typedef struct { UINT32 PhysicalPackage : 1; UINT32 AcpiProcessorIdValid : 1; UINT32 ProcessorIsAThread : 1; UINT32 NodeIsALeaf : 1; UINT32 IdenticalImplementation : 1; UINT32 Reserved : 27; } EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR_FLAGS; /// /// Processor hierarchy node structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR_FLAGS Flags; UINT32 Parent; UINT32 AcpiProcessorId; UINT32 NumberOfPrivateResources; } EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR; /// /// For PPTT struct cache flags /// #define EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_CACHE_SIZE_VALID 0x1 #define EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_VALID 0x1 #define EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_VALID 0x1 #define EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_VALID 0x1 #define EFI_ACPI_6_4_PPTT_CACHE_TYPE_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_CACHE_TYPE_VALID 0x1 #define EFI_ACPI_6_4_PPTT_WRITE_POLICY_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_WRITE_POLICY_VALID 0x1 #define EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_LINE_SIZE_VALID 0x1 #define EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID 0x0 #define EFI_ACPI_6_4_PPTT_CACHE_ID_VALID 0x1 /// /// Cache Type Structure flags /// typedef struct { UINT32 SizePropertyValid : 1; UINT32 NumberOfSetsValid : 1; UINT32 AssociativityValid : 1; UINT32 AllocationTypeValid : 1; UINT32 CacheTypeValid : 1; UINT32 WritePolicyValid : 1; UINT32 LineSizeValid : 1; UINT32 CacheIdValid : 1; UINT32 Reserved : 24; } EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS; /// /// For cache attributes /// #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_READ 0x0 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_WRITE 0x1 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE 0x2 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_DATA 0x0 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION 0x1 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED 0x2 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK 0x0 #define EFI_ACPI_6_4_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_THROUGH 0x1 /// /// Cache Type Structure cache attributes /// typedef struct { UINT8 AllocationType : 2; UINT8 CacheType : 2; UINT8 WritePolicy : 1; UINT8 Reserved : 3; } EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_ATTRIBUTES; /// /// Cache Type Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS Flags; UINT32 NextLevelOfCache; UINT32 Size; UINT32 NumberOfSets; UINT8 Associativity; EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_ATTRIBUTES Attributes; UINT16 LineSize; UINT32 CacheId; } EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE; /// /// Platform Health Assessment Table (PHAT) Format /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; // UINT8 PlatformTelemetryRecords[]; } EFI_ACPI_6_4_PLATFORM_HEALTH_ASSESSMENT_TABLE; #define EFI_ACPI_6_4_PLATFORM_HEALTH_ASSESSMENT_TABLE_REVISION 0x01 /// /// PHAT Record Format /// typedef struct { UINT16 PlatformHealthAssessmentRecordType; UINT16 RecordLength; UINT8 Revision; // UINT8 Data[]; } EFI_ACPI_6_4_PHAT_RECORD; /// /// PHAT Record Type Format /// #define EFI_ACPI_6_4_PHAT_RECORD_TYPE_FIRMWARE_VERSION_DATA_RECORD 0x0000 #define EFI_ACPI_6_4_PHAT_RECORD_TYPE_FIRMWARE_HEALTH_DATA_RECORD 0x0001 /// /// PHAT Version Element /// typedef struct { GUID ComponentId; UINT64 VersionValue; UINT32 ProducerId; } EFI_ACPI_6_4_PHAT_VERSION_ELEMENT; /// /// PHAT Firmware Version Data Record /// typedef struct { UINT16 PlatformRecordType; UINT16 RecordLength; UINT8 Revision; UINT8 Reserved[3]; UINT32 RecordCount; // UINT8 PhatVersionElement[]; } EFI_ACPI_6_4_PHAT_FIRMWARE_VERISON_DATA_RECORD; #define EFI_ACPI_6_4_PHAT_FIRMWARE_VERSION_DATA_RECORD_REVISION 0x01 /// /// Firmware Health Data Record Structure /// typedef struct { UINT16 PlatformRecordType; UINT16 RecordLength; UINT8 Revision; UINT16 Reserved; UINT8 AmHealthy; GUID DeviceSignature; UINT32 DeviceSpecificDataOffset; // UINT8 DevicePath[]; // UINT8 DeviceSpecificData[]; } EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_STRUCTURE; #define EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_REVISION 0x01 /// /// Firmware Health Data Record device health state /// #define EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ERRORS_FOUND 0x00 #define EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_NO_ERRORS_FOUND 0x01 #define EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_UNKNOWN 0x02 #define EFI_ACPI_6_4_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ADVISORY 0x03 /// /// CEDT Table Revision /// #define EFI_ACPI_6_4_CEDT_CXL_EARLY_DISCOVERY_TABLE_REVISION_01 0x01 /// /// CEDT Structure Type /// #define EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_HOST_BRIDGE_STRUCTURE 0x00 #define EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_FIXED_MEMORY_WINDOW_STRUCTURE 0x01 #define EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_XOR_INTERLEAVE_MATH_STRUCTURE 0x02 #define EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_RCEC_DOWNSTREAM_PORT_ASSOCIATION_STRUCTURE 0x03 /// /// CEDT CXL Host Bridge Structure /// typedef struct { UINT8 Type; // Set to EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_HOST_BRIDGE_STRUCTURE UINT8 Reserved0; UINT16 RecordLength; UINT32 Uid; UINT32 CxlVersion; UINT32 Reserved1; UINT64 Base; UINT64 Length; } EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_STRUCTURE; /// /// CEDT CXL Version /// #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_STRUCTURE_CXL_VERSION_RCH 0x00 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_STRUCTURE_CXL_VERSION_HB 0x01 /// /// CEDT CXL Fixed Memory Window Structure /// typedef struct { UINT8 Type; // Set to EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_FIXED_MEMORY_WINDOW_STRUCTURE UINT8 Reserved0; UINT16 RecordLength; UINT32 Reserved1; UINT64 BaseHpa; UINT64 WindowSize; UINT8 EncodedNumberOfInterleaveWays; UINT8 InterleaveArithmetic; UINT16 Reserved2; UINT32 HostBridgeInterleaveGranularity; UINT16 WindowRestrictions; UINT16 QtgId; UINT32 InterleaveTargetList[]; } EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE; /// /// CEDT Fixed Memory Window Structure Host Bridge Interleave Ways /// #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_NONE 0x0 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_2_WAY 0x1 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_4_WAY 0x2 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_8_WAY 0x3 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_16_WAY 0x4 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_3_WAY 0x8 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_6_WAY 0x9 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_WAYS_12_WAY 0xA /// /// CEDT Fixed Memory Window Structure Interleave Arithmetic Type /// #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_ARITHMETIC_STANDARD_MODULO 0x00 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_INTERLEAVE_ARITHMETIC_MODULO_XOR 0x01 /// /// CEDT Host Bridge Interleave Granularity /// #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_256B 0x0 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_512B 0x1 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_1024B 0x2 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_2048B 0x3 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_4096B 0x4 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_8192B 0x5 #define EFI_ACPI_6_4_CEDT_CXL_HOST_BRIDGE_INTERLEAVE_GRANULARITY_16384B 0x6 /// /// CEDT Fixed Memory Window Structure Window Restriction /// #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_WINDOW_RESTRICTIONS_DEVICE_COHERENT BIT0 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_WINDOW_RESTRICTIONS_HOST_ONLY_COHERENT BIT1 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_WINDOW_RESTRICTIONS_VOLATILE BIT2 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_WINDOW_RESTRICTIONS_PERSISTENT BIT3 #define EFI_ACPI_6_4_CEDT_CXL_FIXED_MEMORY_WINDOW_STRUCTURE_WINDOW_RESTRICTIONS_FIXED_DEVICE_CONFIGURATION BIT4 /// /// CEDT CXL XOR Interleave Math Structure /// typedef struct { UINT8 Type; // Set to EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_CXL_XOR_INTERLEAVE_MATH_STRUCTURE UINT8 Reserved0; UINT16 RecordLength; UINT16 Reserved1; UINT8 HostBridgeInterleaveGranularity; UINT8 NumberOfBitmapEntries; UINT64 XormapList[]; } EFI_ACPI_6_4_CEDT_CXL_XOR_INTERLEAVE_MATH_STRUCTURE; /// /// CEDT RCEC Downstream Port Association Structure /// typedef struct { UINT8 Type; // Set to EFI_ACPI_6_4_CEDT_STRUCTURE_TYPE_RCEC_DOWNSTREAM_PORT_ASSOCIATION_STRUCTURE UINT8 Reserved0; UINT16 RecordLength; UINT16 RcecSegmentNumber; UINT16 RcecBusDeviceFunction; UINT8 ProtocolType; UINT64 BaseAddress; } EFI_ACPI_6_4_CEDT_RCEC_DOWNSTREAM_PORT_ASSOCIATION_STRUCTURE; /// /// CEDT RCEC Protocol Type /// #define EFI_ACPI_6_4_CEDT_RCEC_PROTOCOL_TYPE_CXL_IO 0x00 #define EFI_ACPI_6_4_CEDT_RCEC_PROTOCOL_TYPE_CXL_CACHEMEM 0x01 /// /// CXL Early Discovery Table ("CEDT") Format /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; // CedtStructure is a heterogeneous, packed list of any of the following: // - CXL Host Bridge Structure // - CXL Fixed Memory Window Structure // - CXL XOR Interleave Math Structure // - RCEC Downstream Port Association Structure // The structures share common Type and RecordLength fields that are used to // identify the type of structure and traverse the list. UINT8 CedtStructure[]; } EFI_ACPI_6_4_CXL_EARLY_DISCOVERY_TABLE; // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_4_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "APMT" Arm Performance Monitoring Unit Table /// #define EFI_ACPI_6_4_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'M', 'T') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_4_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_4_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CDIT" Component Distance Information Table /// #define EFI_ACPI_6_4_COMPONENT_DISTANCE_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('C', 'D', 'I', 'T') /// /// "CEDT" CXL Early Discovery Table /// #define EFI_ACPI_6_4_CXL_EARLY_DISCOVERY_TABLE_SIGNATURE SIGNATURE_32('C', 'E', 'D', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_4_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "CRAT" Component Resource Attribute Table /// #define EFI_ACPI_6_4_COMPONENT_RESOURCE_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('C', 'R', 'A', 'T') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_4_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_4_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_4_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_4_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_4_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_4_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_4_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "HMAT" Heterogeneous Memory Attribute Table /// #define EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('H', 'M', 'A', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_4_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_4_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_4_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PDTT" Platform Debug Trigger Table /// #define EFI_ACPI_6_4_PLATFORM_DEBUG_TRIGGER_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'D', 'T', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_4_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PPTT" Processor Properties Topology Table /// #define EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'P', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_4_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_4_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_4_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_4_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SDEV" Secure DEVices Table /// #define EFI_ACPI_6_4_SECURE_DEVICES_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'V') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_4_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_4_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_4_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_4_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_4_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_4_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_4_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_4_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_4_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_4_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_4_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_4_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_4_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_4_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_4_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_4_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_4_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_4_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "PHAT" Platform Health Assessment Table /// #define EFI_ACPI_6_4_PLATFORM_HEALTH_ASSESSMENT_TABLE_SIGNATURE SIGNATURE_32('P', 'H', 'A', 'T') /// /// "SDEI" Software Delegated Exceptions Interface Table /// #define EFI_ACPI_6_4_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'I') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_4_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Concole Redirection Table /// #define EFI_ACPI_6_4_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_4_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_4_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_4_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_4_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_4_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_4_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_4_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_4_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_4_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "WSMT" Windows SMM Security Mitigation Table /// #define EFI_ACPI_6_4_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE SIGNATURE_32('W', 'S', 'M', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_4_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') #pragma pack() #endif ================================================ FILE: src/edk2/Acpi65.h ================================================ /** @file ACPI 6.5 definitions from the ACPI Specification Revision 6.5 Aug, 2022. Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
Copyright (c) 2019 - 2024, ARM Ltd. All rights reserved.
Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef ACPI_6_5_H_ #define ACPI_6_5_H_ #include "Acpi64.h" // // Ensure proper structure formats // #pragma pack(1) /// /// _STA bit definitions ACPI 6.5 s6.3.7 /// #define ACPI_AML_STA_DEVICE_STATUS_PRESET 0x1 #define ACPI_AML_STA_DEVICE_STATUS_ENABLED 0x2 #define ACPI_AML_STA_DEVICE_STATUS_UI 0x4 #define ACPI_AML_STA_DEVICE_STATUS_FUNCTIONING 0x8 #define ACPI_AML_STA_DEVICE_STATUS_BATTERY 0x10 /// /// _CSD Revision for ACPI 6.5 /// #define EFI_ACPI_6_5_AML_CSD_REVISION 0 /// /// _CSD NumEntries for ACPI 6.5 /// #define EFI_ACPI_6_5_AML_CSD_NUM_ENTRIES 6 /// /// _PSD Revision for ACPI 6.5 /// #define EFI_ACPI_6_5_AML_PSD_REVISION 0 /// /// _CPC Revision for ACPI 6.5 /// #define EFI_ACPI_6_5_AML_CPC_REVISION 3 /// /// ACPI 6.5 Generic Address Space definition /// typedef struct { UINT8 AddressSpaceId; UINT8 RegisterBitWidth; UINT8 RegisterBitOffset; UINT8 AccessSize; UINT64 Address; } EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE; // // Generic Address Space Address IDs // #define EFI_ACPI_6_5_SYSTEM_MEMORY 0x00 #define EFI_ACPI_6_5_SYSTEM_IO 0x01 #define EFI_ACPI_6_5_PCI_CONFIGURATION_SPACE 0x02 #define EFI_ACPI_6_5_EMBEDDED_CONTROLLER 0x03 #define EFI_ACPI_6_5_SMBUS 0x04 #define EFI_ACPI_6_5_SYSTEM_CMOS 0x05 #define EFI_ACPI_6_5_PCI_BAR_TARGET 0x06 #define EFI_ACPI_6_5_IPMI 0x07 #define EFI_ACPI_6_5_GENERAL_PURPOSE_IO 0x08 #define EFI_ACPI_6_5_GENERIC_SERIAL_BUS 0x09 #define EFI_ACPI_6_5_PLATFORM_COMMUNICATION_CHANNEL 0x0A #define EFI_ACPI_6_5_PLATFORM_RUNTIME_MECHANISM 0x0B #define EFI_ACPI_6_5_FUNCTIONAL_FIXED_HARDWARE 0x7F // // Generic Address Space Access Sizes // #define EFI_ACPI_6_5_UNDEFINED 0 #define EFI_ACPI_6_5_BYTE 1 #define EFI_ACPI_6_5_WORD 2 #define EFI_ACPI_6_5_DWORD 3 #define EFI_ACPI_6_5_QWORD 4 // // ACPI 6.5 table structures // /// /// Root System Description Pointer Structure /// typedef struct { UINT64 Signature; UINT8 Checksum; UINT8 OemId[6]; UINT8 Revision; UINT32 RsdtAddress; UINT32 Length; UINT64 XsdtAddress; UINT8 ExtendedChecksum; UINT8 Reserved[3]; } EFI_ACPI_6_5_ROOT_SYSTEM_DESCRIPTION_POINTER; /// /// RSD_PTR Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 ///< ACPISpec (Revision 6.5) says current value is 2 /// /// Common table header, this prefaces all ACPI tables, including FACS, but /// excluding the RSD PTR structure /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_5_COMMON_HEADER; // // Root System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers. // /// /// RSDT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 // // Extended System Description Table // No definition needed as it is a common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers. // /// /// XSDT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01 /// /// Fixed ACPI Description Table Structure (FADT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 FirmwareCtrl; UINT32 Dsdt; UINT8 Reserved0; UINT8 PreferredPmProfile; UINT16 SciInt; UINT32 SmiCmd; UINT8 AcpiEnable; UINT8 AcpiDisable; UINT8 S4BiosReq; UINT8 PstateCnt; UINT32 Pm1aEvtBlk; UINT32 Pm1bEvtBlk; UINT32 Pm1aCntBlk; UINT32 Pm1bCntBlk; UINT32 Pm2CntBlk; UINT32 PmTmrBlk; UINT32 Gpe0Blk; UINT32 Gpe1Blk; UINT8 Pm1EvtLen; UINT8 Pm1CntLen; UINT8 Pm2CntLen; UINT8 PmTmrLen; UINT8 Gpe0BlkLen; UINT8 Gpe1BlkLen; UINT8 Gpe1Base; UINT8 CstCnt; UINT16 PLvl2Lat; UINT16 PLvl3Lat; UINT16 FlushSize; UINT16 FlushStride; UINT8 DutyOffset; UINT8 DutyWidth; UINT8 DayAlrm; UINT8 MonAlrm; UINT8 Century; UINT16 IaPcBootArch; UINT8 Reserved1; UINT32 Flags; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg; UINT8 ResetValue; UINT16 ArmBootArch; UINT8 MinorVersion; UINT64 XFirmwareCtrl; UINT64 XDsdt; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe0Blk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe1Blk; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepControlReg; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepStatusReg; UINT64 HypervisorVendorIdentity; } EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE; /// /// FADT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06 #define EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x05 // // Fixed ACPI Description Table Preferred Power Management Profile // #define EFI_ACPI_6_5_PM_PROFILE_UNSPECIFIED 0 #define EFI_ACPI_6_5_PM_PROFILE_DESKTOP 1 #define EFI_ACPI_6_5_PM_PROFILE_MOBILE 2 #define EFI_ACPI_6_5_PM_PROFILE_WORKSTATION 3 #define EFI_ACPI_6_5_PM_PROFILE_ENTERPRISE_SERVER 4 #define EFI_ACPI_6_5_PM_PROFILE_SOHO_SERVER 5 #define EFI_ACPI_6_5_PM_PROFILE_APPLIANCE_PC 6 #define EFI_ACPI_6_5_PM_PROFILE_PERFORMANCE_SERVER 7 #define EFI_ACPI_6_5_PM_PROFILE_TABLET 8 // // Fixed ACPI Description Table Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_5_LEGACY_DEVICES BIT0 #define EFI_ACPI_6_5_8042 BIT1 #define EFI_ACPI_6_5_VGA_NOT_PRESENT BIT2 #define EFI_ACPI_6_5_MSI_NOT_SUPPORTED BIT3 #define EFI_ACPI_6_5_PCIE_ASPM_CONTROLS BIT4 #define EFI_ACPI_6_5_CMOS_RTC_NOT_PRESENT BIT5 // // Fixed ACPI Description Table Arm Boot Architecture Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_5_ARM_PSCI_COMPLIANT BIT0 #define EFI_ACPI_6_5_ARM_PSCI_USE_HVC BIT1 // // Fixed ACPI Description Table Fixed Feature Flags // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_5_WBINVD BIT0 #define EFI_ACPI_6_5_WBINVD_FLUSH BIT1 #define EFI_ACPI_6_5_PROC_C1 BIT2 #define EFI_ACPI_6_5_P_LVL2_UP BIT3 #define EFI_ACPI_6_5_PWR_BUTTON BIT4 #define EFI_ACPI_6_5_SLP_BUTTON BIT5 #define EFI_ACPI_6_5_FIX_RTC BIT6 #define EFI_ACPI_6_5_RTC_S4 BIT7 #define EFI_ACPI_6_5_TMR_VAL_EXT BIT8 #define EFI_ACPI_6_5_DCK_CAP BIT9 #define EFI_ACPI_6_5_RESET_REG_SUP BIT10 #define EFI_ACPI_6_5_SEALED_CASE BIT11 #define EFI_ACPI_6_5_HEADLESS BIT12 #define EFI_ACPI_6_5_CPU_SW_SLP BIT13 #define EFI_ACPI_6_5_PCI_EXP_WAK BIT14 #define EFI_ACPI_6_5_USE_PLATFORM_CLOCK BIT15 #define EFI_ACPI_6_5_S4_RTC_STS_VALID BIT16 #define EFI_ACPI_6_5_REMOTE_POWER_ON_CAPABLE BIT17 #define EFI_ACPI_6_5_FORCE_APIC_CLUSTER_MODEL BIT18 #define EFI_ACPI_6_5_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 #define EFI_ACPI_6_5_HW_REDUCED_ACPI BIT20 #define EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE BIT21 /// /// Firmware ACPI Control Structure /// typedef struct { UINT32 Signature; UINT32 Length; UINT32 HardwareSignature; UINT32 FirmwareWakingVector; UINT32 GlobalLock; UINT32 Flags; UINT64 XFirmwareWakingVector; UINT8 Version; UINT8 Reserved0[3]; UINT32 OspmFlags; UINT8 Reserved1[24]; } EFI_ACPI_6_5_FIRMWARE_ACPI_CONTROL_STRUCTURE; /// /// FACS Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x02 /// /// Firmware Control Structure Feature Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_5_S4BIOS_F BIT0 #define EFI_ACPI_6_5_64BIT_WAKE_SUPPORTED_F BIT1 /// /// OSPM Enabled Firmware Control Structure Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_5_OSPM_64BIT_WAKE_F BIT0 // // Differentiated System Description Table, // Secondary System Description Table // and Persistent System Description Table, // no definition needed as they are common description table header, the same with // EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block. // #define EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 #define EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02 /// /// Multiple APIC Description Table header definition. The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 LocalApicAddress; UINT32 Flags; } EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER; /// /// MADT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x06 /// /// Multiple APIC Flags /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_5_PCAT_COMPAT BIT0 // // Multiple APIC Description Table APIC structure types // All other values between 0x18 and 0x7F are reserved and // will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM. // #define EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC 0x00 #define EFI_ACPI_6_5_IO_APIC 0x01 #define EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE 0x02 #define EFI_ACPI_6_5_NON_MASKABLE_INTERRUPT_SOURCE 0x03 #define EFI_ACPI_6_5_LOCAL_APIC_NMI 0x04 #define EFI_ACPI_6_5_LOCAL_APIC_ADDRESS_OVERRIDE 0x05 #define EFI_ACPI_6_5_IO_SAPIC 0x06 #define EFI_ACPI_6_5_LOCAL_SAPIC 0x07 #define EFI_ACPI_6_5_PLATFORM_INTERRUPT_SOURCES 0x08 #define EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC 0x09 #define EFI_ACPI_6_5_LOCAL_X2APIC_NMI 0x0A #define EFI_ACPI_6_5_GIC 0x0B #define EFI_ACPI_6_5_GICD 0x0C #define EFI_ACPI_6_5_GIC_MSI_FRAME 0x0D #define EFI_ACPI_6_5_GICR 0x0E #define EFI_ACPI_6_5_GIC_ITS 0x0F #define EFI_ACPI_6_5_MULTIPROCESSOR_WAKEUP 0x10 #define EFI_ACPI_6_5_CORE_PIC 0x11 #define EFI_ACPI_6_5_LIO_PIC 0x12 #define EFI_ACPI_6_5_HT_PIC 0x13 #define EFI_ACPI_6_5_EIO_PIC 0x14 #define EFI_ACPI_6_5_MSI_PIC 0x15 #define EFI_ACPI_6_5_BIO_PIC 0x16 #define EFI_ACPI_6_5_LPC_PIC 0x17 // // APIC Structure Definitions // /// /// Processor Local APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT8 ApicId; UINT32 Flags; } EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_STRUCTURE; /// /// Local APIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_LOCAL_APIC_ENABLED BIT0 #define EFI_ACPI_6_5_LOCAL_APIC_ONLINE_CAPABLE BIT1 /// /// IO APIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 IoApicAddress; UINT32 GlobalSystemInterruptBase; } EFI_ACPI_6_5_IO_APIC_STRUCTURE; /// /// Interrupt Source Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Bus; UINT8 Source; UINT32 GlobalSystemInterrupt; UINT16 Flags; } EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE; /// /// Platform Interrupt Sources Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; UINT8 CpeiProcessorOverride; UINT8 Reserved[31]; } EFI_ACPI_6_5_PLATFORM_INTERRUPT_APIC_STRUCTURE; // // MPS INTI flags. // All other bits are reserved and must be set to 0. // #define EFI_ACPI_6_5_POLARITY (3 << 0) #define EFI_ACPI_6_5_TRIGGER_MODE (3 << 2) /// /// Non-Maskable Interrupt Source Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 GlobalSystemInterrupt; } EFI_ACPI_6_5_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE; /// /// Local APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorUid; UINT16 Flags; UINT8 LocalApicLint; } EFI_ACPI_6_5_LOCAL_APIC_NMI_STRUCTURE; /// /// Local APIC Address Override Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 LocalApicAddress; } EFI_ACPI_6_5_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE; /// /// IO SAPIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 IoApicId; UINT8 Reserved; UINT32 GlobalSystemInterruptBase; UINT64 IoSapicAddress; } EFI_ACPI_6_5_IO_SAPIC_STRUCTURE; /// /// Local SAPIC Structure /// This struct followed by a null-terminated ASCII string - ACPI Processor UID String /// typedef struct { UINT8 Type; UINT8 Length; UINT8 AcpiProcessorId; UINT8 LocalSapicId; UINT8 LocalSapicEid; UINT8 Reserved[3]; UINT32 Flags; UINT32 ACPIProcessorUIDValue; } EFI_ACPI_6_5_PROCESSOR_LOCAL_SAPIC_STRUCTURE; /// /// Platform Interrupt Sources Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT8 InterruptType; UINT8 ProcessorId; UINT8 ProcessorEid; UINT8 IoSapicVector; UINT32 GlobalSystemInterrupt; UINT32 PlatformInterruptSourceFlags; } EFI_ACPI_6_5_PLATFORM_INTERRUPT_SOURCES_STRUCTURE; /// /// Platform Interrupt Source Flags. /// All other bits are reserved and must be set to 0. /// #define EFI_ACPI_6_5_CPEI_PROCESSOR_OVERRIDE BIT0 /// /// Processor Local x2APIC Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; UINT32 X2ApicId; UINT32 Flags; UINT32 AcpiProcessorUid; } EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE; /// /// Local x2APIC NMI Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Flags; UINT32 AcpiProcessorUid; UINT8 LocalX2ApicLint; UINT8 Reserved[3]; } EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE; /// /// GIC Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 CPUInterfaceNumber; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ParkingProtocolVersion; UINT32 PerformanceInterruptGsiv; UINT64 ParkedAddress; UINT64 PhysicalBaseAddress; UINT64 GICV; UINT64 GICH; UINT32 VGICMaintenanceInterrupt; UINT64 GICRBaseAddress; UINT64 MPIDR; UINT8 ProcessorPowerEfficiencyClass; UINT8 Reserved2; UINT16 SpeOverflowInterrupt; UINT16 TrbeInterrupt; } EFI_ACPI_6_5_GIC_STRUCTURE; /// /// GIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GIC_ENABLED BIT0 #define EFI_ACPI_6_5_PERFORMANCE_INTERRUPT_MODEL BIT1 #define EFI_ACPI_6_5_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS BIT2 #define EFI_ACPI_6_5_GIC_ONLINE_CAPABLE BIT3 /// /// GIC Distributor Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicId; UINT64 PhysicalBaseAddress; UINT32 SystemVectorBase; UINT8 GicVersion; UINT8 Reserved2[3]; } EFI_ACPI_6_5_GIC_DISTRIBUTOR_STRUCTURE; /// /// GIC Version /// #define EFI_ACPI_6_5_GIC_V1 0x01 #define EFI_ACPI_6_5_GIC_V2 0x02 #define EFI_ACPI_6_5_GIC_V3 0x03 #define EFI_ACPI_6_5_GIC_V4 0x04 /// /// GIC MSI Frame Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved1; UINT32 GicMsiFrameId; UINT64 PhysicalBaseAddress; UINT32 Flags; UINT16 SPICount; UINT16 SPIBase; } EFI_ACPI_6_5_GIC_MSI_FRAME_STRUCTURE; /// /// GIC MSI Frame Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_SPI_COUNT_BASE_SELECT BIT0 /// /// GICR Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT64 DiscoveryRangeBaseAddress; UINT32 DiscoveryRangeLength; } EFI_ACPI_6_5_GICR_STRUCTURE; /// /// GIC Interrupt Translation Service Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Reserved; UINT32 GicItsId; UINT64 PhysicalBaseAddress; UINT32 Reserved2; } EFI_ACPI_6_5_GIC_ITS_STRUCTURE; /// /// Multiprocessor Wakeup Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 MailBoxVersion; UINT32 Reserved; UINT64 MailBoxAddress; } EFI_ACPI_6_5_MULTIPROCESSOR_WAKEUP_STRUCTURE; /// /// Multiprocessor Wakeup Mailbox Structure /// typedef struct { UINT16 Command; UINT16 Reserved; UINT32 AcpiId; UINT64 WakeupVector; UINT8 ReservedForOs[2032]; UINT8 ReservedForFirmware[2048]; } EFI_ACPI_6_5_MULTIPROCESSOR_WAKEUP_MAILBOX_STRUCTURE; #define EFI_ACPI_6_5_MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_NOOP 0x0000 #define EFI_ACPI_6_5_MULTIPROCESSOR_WAKEUP_MAILBOX_COMMAND_WAKEUP 0x0001 /// /// Core Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT32 ProcessorId; UINT32 CoreId; UINT32 Flags; } EFI_ACPI_6_5_CORE_PIC_STRUCTURE; /// /// Legacy I/O Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT64 Address; UINT16 Size; UINT8 Cascade[2]; UINT32 CascadeMap[2]; } EFI_ACPI_6_5_LIO_PIC_STRUCTURE; /// /// HyperTransport Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT64 Address; UINT16 Size; UINT8 Cascade[8]; } EFI_ACPI_6_5_HT_PIC_STRUCTURE; /// /// Extend I/O Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT8 Cascade; UINT8 Node; UINT64 NodeMap; } EFI_ACPI_6_5_EIO_PIC_STRUCTURE; /// /// MSI Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT64 MsgAddress; UINT32 Start; UINT32 Count; } EFI_ACPI_6_5_MSI_PIC_STRUCTURE; /// /// Bridge I/O Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT64 Address; UINT16 Size; UINT16 Id; UINT16 GsiBase; } EFI_ACPI_6_5_BIO_PIC_STRUCTURE; /// /// Low Pin Count Programmable Interrupt Controller /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Version; UINT64 Address; UINT16 Size; UINT8 Cascade; } EFI_ACPI_6_5_LPC_PIC_STRUCTURE; /// /// Smart Battery Description Table (SBST) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 WarningEnergyLevel; UINT32 LowEnergyLevel; UINT32 CriticalEnergyLevel; } EFI_ACPI_6_5_SMART_BATTERY_DESCRIPTION_TABLE; /// /// SBST Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01 /// /// Embedded Controller Boot Resources Table (ECDT) /// The table is followed by a null terminated ASCII string that contains /// a fully qualified reference to the name space object. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE EcControl; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE EcData; UINT32 Uid; UINT8 GpeBit; } EFI_ACPI_6_5_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE; /// /// ECDT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01 /// /// System Resource Affinity Table (SRAT). The rest of the table /// must be defined in a platform specific manner. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved1; ///< Must be set to 1 UINT64 Reserved2; } EFI_ACPI_6_5_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER; /// /// SRAT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x03 // // SRAT structure types. // All other values between 0x06 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00 #define EFI_ACPI_6_5_MEMORY_AFFINITY 0x01 #define EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_AFFINITY 0x02 #define EFI_ACPI_6_5_GICC_AFFINITY 0x03 #define EFI_ACPI_6_5_GIC_ITS_AFFINITY 0x04 #define EFI_ACPI_6_5_GENERIC_INITIATOR_AFFINITY 0x05 /// /// Processor Local APIC/SAPIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProximityDomain7To0; UINT8 ApicId; UINT32 Flags; UINT8 LocalSapicEid; UINT8 ProximityDomain31To8[3]; UINT32 ClockDomain; } EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE; /// /// Local APIC/SAPIC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0) /// /// Memory Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT16 Reserved1; UINT32 AddressBaseLow; UINT32 AddressBaseHigh; UINT32 LengthLow; UINT32 LengthHigh; UINT32 Reserved2; UINT32 Flags; UINT64 Reserved3; } EFI_ACPI_6_5_MEMORY_AFFINITY_STRUCTURE; // // Memory Flags. All other bits are reserved and must be 0. // #define EFI_ACPI_6_5_MEMORY_ENABLED (1 << 0) #define EFI_ACPI_6_5_MEMORY_HOT_PLUGGABLE (1 << 1) #define EFI_ACPI_6_5_MEMORY_NONVOLATILE (1 << 2) /// /// Processor Local x2APIC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1[2]; UINT32 ProximityDomain; UINT32 X2ApicId; UINT32 Flags; UINT32 ClockDomain; UINT8 Reserved2[4]; } EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE; /// /// GICC Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT32 AcpiProcessorUid; UINT32 Flags; UINT32 ClockDomain; } EFI_ACPI_6_5_GICC_AFFINITY_STRUCTURE; /// /// GICC Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GICC_ENABLED (1 << 0) /// /// GIC Interrupt Translation Service (ITS) Affinity Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT32 ProximityDomain; UINT8 Reserved[2]; UINT32 ItsId; } EFI_ACPI_6_5_GIC_ITS_AFFINITY_STRUCTURE; // // Generic Initiator Affinity Structure Device Handle Types // All other values between 0x02 an 0xFF are reserved and // will be ignored by OSPM. // #define EFI_ACPI_6_5_ACPI_DEVICE_HANDLE 0x00 #define EFI_ACPI_6_5_PCI_DEVICE_HANDLE 0x01 /// /// Device Handle - ACPI /// typedef struct { UINT64 AcpiHid; UINT32 AcpiUid; UINT8 Reserved[4]; } EFI_ACPI_6_5_DEVICE_HANDLE_ACPI; /// /// Device Handle - PCI /// typedef struct { UINT16 PciSegment; UINT16 PciBdfNumber; UINT8 Reserved[12]; } EFI_ACPI_6_5_DEVICE_HANDLE_PCI; /// /// Device Handle /// typedef union { EFI_ACPI_6_5_DEVICE_HANDLE_ACPI Acpi; EFI_ACPI_6_5_DEVICE_HANDLE_PCI Pci; } EFI_ACPI_6_5_DEVICE_HANDLE; /// /// Generic Initiator Affinity Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved1; UINT8 DeviceHandleType; UINT32 ProximityDomain; EFI_ACPI_6_5_DEVICE_HANDLE DeviceHandle; UINT32 Flags; UINT8 Reserved2[4]; } EFI_ACPI_6_5_GENERIC_INITIATOR_AFFINITY_STRUCTURE; /// /// Generic Initiator Affinity Structure Flags. All other bits are reserved /// and must be 0. /// #define EFI_ACPI_6_5_GENERIC_INITIATOR_AFFINITY_STRUCTURE_ENABLED BIT0 #define EFI_ACPI_6_5_GENERIC_INITIATOR_AFFINITY_STRUCTURE_ARCHITECTURAL_TRANSACTIONS BIT1 /// /// System Locality Distance Information Table (SLIT). /// The rest of the table is a matrix. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 NumberOfSystemLocalities; } EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER; /// /// SLIT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01 /// /// Corrected Platform Error Polling Table (CPEP) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[8]; } EFI_ACPI_6_5_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER; /// /// CPEP Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01 // // CPEP processor structure types. // #define EFI_ACPI_6_5_CPEP_PROCESSOR_APIC_SAPIC 0x00 /// /// Corrected Platform Error Polling Processor Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; UINT8 ProcessorId; UINT8 ProcessorEid; UINT32 PollingInterval; } EFI_ACPI_6_5_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE; /// /// Maximum System Characteristics Table (MSCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 OffsetProxDomInfo; UINT32 MaximumNumberOfProximityDomains; UINT32 MaximumNumberOfClockDomains; UINT64 MaximumPhysicalAddress; } EFI_ACPI_6_5_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER; /// /// MSCT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01 /// /// Maximum Proximity Domain Information Structure Definition /// typedef struct { UINT8 Revision; UINT8 Length; UINT32 ProximityDomainRangeLow; UINT32 ProximityDomainRangeHigh; UINT32 MaximumProcessorCapacity; UINT64 MaximumMemoryCapacity; } EFI_ACPI_6_5_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE; /// /// ACPI RAS Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier[12]; } EFI_ACPI_6_5_RAS_FEATURE_TABLE; /// /// RASF Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_RAS_FEATURE_TABLE_REVISION 0x01 /// /// ACPI RASF Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT16 Version; UINT8 RASCapabilities[16]; UINT8 SetRASCapabilities[16]; UINT16 NumberOfRASFParameterBlocks; UINT32 SetRASCapabilitiesStatus; } EFI_ACPI_6_5_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI RASF PCC command code /// #define EFI_ACPI_6_5_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND 0x01 /// /// ACPI RASF Platform RAS Capabilities /// #define EFI_ACPI_6_5_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED BIT0 #define EFI_ACPI_6_5_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPORTED_AND_EXPOSED_TO_SOFTWARE BIT1 #define EFI_ACPI_6_5_RASF_PLATFORM_RAS_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT2 #define EFI_ACPI_6_5_RASF_PLATFORM_RAS_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT3 #define EFI_ACPI_6_5_RASF_PLATFORM_RAS_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT4 /// /// ACPI RASF Parameter Block structure for PATROL_SCRUB /// typedef struct { UINT16 Type; UINT16 Version; UINT16 Length; UINT16 PatrolScrubCommand; UINT64 RequestedAddressRange[2]; UINT64 ActualAddressRange[2]; UINT16 Flags; UINT8 RequestedSpeed; } EFI_ACPI_6_5_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE; /// /// ACPI RASF Patrol Scrub command /// #define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS 0x01 #define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER 0x02 #define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03 /// /// ACPI RAS2 PCC Descriptor /// typedef struct { UINT8 PccId; UINT8 Reserved[2]; UINT8 RasFeatureType; UINT32 Instance; } EFI_ACPI_RAS2_PCC_DESCRIPTOR; /// /// ACPI RAS2 Feature Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT16 Reserved; UINT16 PccCount; // EFI_ACPI_RAS2_PCC_DESCRIPTOR Descriptors[PccCount]; } EFI_ACPI_6_5_RAS2_FEATURE_TABLE; /// /// Memory Power State Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 PlatformCommunicationChannelIdentifier; UINT8 Reserved[3]; // Memory Power Node Structure // Memory Power State Characteristics } EFI_ACPI_6_5_MEMORY_POWER_STATUS_TABLE; /// /// MPST Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_MEMORY_POWER_STATE_TABLE_REVISION 0x01 /// /// MPST Platform Communication Channel Shared Memory Region definition. /// typedef struct { UINT32 Signature; UINT16 Command; UINT16 Status; UINT32 MemoryPowerCommandRegister; UINT32 MemoryPowerStatusRegister; UINT32 PowerStateId; UINT32 MemoryPowerNodeId; UINT64 MemoryEnergyConsumed; UINT64 ExpectedAveragePowerComsuned; } EFI_ACPI_6_5_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION; /// /// ACPI MPST PCC command code /// #define EFI_ACPI_6_5_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND 0x03 /// /// ACPI MPST Memory Power command /// #define EFI_ACPI_6_5_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE 0x01 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE 0x02 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED 0x03 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED 0x04 /// /// MPST Memory Power Node Table /// typedef struct { UINT8 PowerStateValue; UINT8 PowerStateInformationIndex; } EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE; typedef struct { UINT8 Flag; UINT8 Reserved; UINT16 MemoryPowerNodeId; UINT32 Length; UINT64 AddressBase; UINT64 AddressLength; UINT32 NumberOfPowerStates; UINT32 NumberOfPhysicalComponents; // EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE MemoryPowerState[NumberOfPowerStates]; // UINT16 PhysicalComponentIdentifier[NumberOfPhysicalComponents]; } EFI_ACPI_6_5_MPST_MEMORY_POWER_STRUCTURE; #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE 0x01 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED 0x02 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE 0x04 typedef struct { UINT16 MemoryPowerNodeCount; UINT8 Reserved[2]; } EFI_ACPI_6_5_MPST_MEMORY_POWER_NODE_TABLE; /// /// MPST Memory Power State Characteristics Table /// typedef struct { UINT8 PowerStateStructureID; UINT8 Flag; UINT16 Reserved; UINT32 AveragePowerConsumedInMPS0; UINT32 RelativePowerSavingToMPS0; UINT64 ExitLatencyToMPS0; } EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE; #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED 0x01 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY 0x02 #define EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT 0x04 typedef struct { UINT16 MemoryPowerStateCharacteristicsCount; UINT8 Reserved[2]; } EFI_ACPI_6_5_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE; /// /// Platform Memory Topology Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 NumberOfMemoryDevices; // EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[NumberOfMemoryDevices]; } EFI_ACPI_6_5_PLATFORM_MEMORY_TOPOLOGY_TABLE; /// /// PMTT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_MEMORY_TOPOLOGY_TABLE_REVISION 0x02 /// /// Common Memory Device. /// typedef struct { UINT8 Type; UINT8 Reserved; UINT16 Length; UINT16 Flags; UINT16 Reserved1; UINT32 NumberOfMemoryDevices; // UINT8 TypeSpecificData[]; // EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[NumberOfMemoryDevices]; } EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE; /// /// Memory Device Type. /// #define EFI_ACPI_6_5_PMTT_MEMORY_DEVICE_TYPE_SOCKET 0x0 #define EFI_ACPI_6_5_PMTT_MEMORY_DEVICE_TYPE_MEMORY_CONTROLLER 0x1 #define EFI_ACPI_6_5_PMTT_MEMORY_DEVICE_TYPE_DIMM 0x2 #define EFI_ACPI_6_5_PMTT_MEMORY_DEVICE_TYPE_VENDOR_SPECIFIC_TYPE 0xFF /// /// Socket Type Data. /// typedef struct { EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT16 SocketIdentifier; UINT16 Reserved; // EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_5_PMTT_SOCKET_TYPE_DATA; /// /// Memory Controller Type Data. /// typedef struct { EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT16 MemoryControllerIdentifier; UINT16 Reserved; // EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_5_PMTT_MEMORY_CONTROLLER_TYPE_DATA; /// /// DIMM Type Specific Data. /// typedef struct { EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT32 SmbiosHandle; } EFI_ACPI_6_5_PMTT_DIMM_TYPE_SPECIFIC_DATA; /// /// Vendor Specific Type Data. /// typedef struct { EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE CommonMemoryDeviceHeader; UINT8 TypeUuid[16]; // EFI_ACPI_6_5_PMTT_VENDOR_SPECIFIC_TYPE_DATA VendorSpecificData[]; // EFI_ACPI_6_5_PMTT_COMMON_MEMORY_DEVICE MemoryDeviceStructure[]; } EFI_ACPI_6_5_PMTT_VENDOR_SPECIFIC_TYPE_DATA; /// /// Boot Graphics Resource Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; /// /// 2-bytes (16 bit) version ID. This value must be 1. /// UINT16 Version; /// /// 1-byte status field indicating current status about the table. /// Bits[7:3] = Reserved (must be zero) /// Bits[2:1] = Orientation Offset. These bits describe the clockwise /// degree offset from the image's default orientation. /// [00] = 0, no offset /// [01] = 90 /// [10] = 180 /// [11] = 270 /// Bit [0] = Displayed. A one indicates the boot image graphic is /// displayed. /// UINT8 Status; /// /// 1-byte enumerated type field indicating format of the image. /// 0 = Bitmap /// 1 - 255 Reserved (for future use) /// UINT8 ImageType; /// /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy /// of the image bitmap. /// UINT64 ImageAddress; /// /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetX; /// /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. /// (X, Y) display offset of the top left corner of the boot image. /// The top left corner of the display is at offset (0, 0). /// UINT32 ImageOffsetY; } EFI_ACPI_6_5_BOOT_GRAPHICS_RESOURCE_TABLE; /// /// BGRT Revision /// #define EFI_ACPI_6_5_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1 /// /// BGRT Version /// #define EFI_ACPI_6_5_BGRT_VERSION 0x01 /// /// BGRT Status /// #define EFI_ACPI_6_5_BGRT_STATUS_NOT_DISPLAYED 0x00 #define EFI_ACPI_6_5_BGRT_STATUS_DISPLAYED 0x01 /// /// BGRT Image Type /// #define EFI_ACPI_6_5_BGRT_IMAGE_TYPE_BMP 0x00 /// /// FPDT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01 /// /// FPDT Performance Record Types /// #define EFI_ACPI_6_5_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER 0x0000 #define EFI_ACPI_6_5_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER 0x0001 /// /// FPDT Performance Record Revision /// #define EFI_ACPI_6_5_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER 0x01 #define EFI_ACPI_6_5_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01 /// /// FPDT Runtime Performance Record Types /// #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME 0x0000 #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND 0x0001 #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT 0x0002 /// /// FPDT Runtime Performance Record Revision /// #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME 0x01 #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND 0x01 #define EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT 0x02 /// /// FPDT Performance Record header /// typedef struct { UINT16 Type; UINT8 Length; UINT8 Revision; } EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER; /// /// FPDT Performance Table header /// typedef struct { UINT32 Signature; UINT32 Length; } EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER; /// /// FPDT Firmware Basic Boot Performance Pointer Record Structure /// typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the Basic Boot Performance Table. /// UINT64 BootPerformanceTablePointer; } EFI_ACPI_6_5_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT S3 Performance Table Pointer Record Structure /// typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// 64-bit processor-relative physical address of the S3 Performance Table. /// UINT64 S3PerformanceTablePointer; } EFI_ACPI_6_5_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD; /// /// FPDT Firmware Basic Boot Performance Record Structure /// typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER Header; UINT32 Reserved; /// /// Timer value logged at the beginning of firmware image execution. /// This may not always be zero or near zero. /// UINT64 ResetEnd; /// /// Timer value logged just prior to loading the OS boot loader into memory. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 OsLoaderLoadImageStart; /// /// Timer value logged just prior to launching the previously loaded OS boot loader image. /// For non-UEFI compatible boots, the timer value logged will be just prior /// to the INT 19h handler invocation. /// UINT64 OsLoaderStartImageStart; /// /// Timer value logged at the point when the OS loader calls the /// ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesEntry; /// /// Timer value logged at the point just prior towhen the OS loader gaining /// control back from calls the ExitBootServices function for UEFI compatible firmware. /// For non-UEFI compatible boots, this field must be zero. /// UINT64 ExitBootServicesExit; } EFI_ACPI_6_5_FPDT_FIRMWARE_BASIC_BOOT_RECORD; /// /// FPDT Firmware Basic Boot Performance Table signature /// #define EFI_ACPI_6_5_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('F', 'B', 'P', 'T') // // FPDT Firmware Basic Boot Performance Table // typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_5_FPDT_FIRMWARE_BASIC_BOOT_TABLE; /// /// FPDT "S3PT" S3 Performance Table /// #define EFI_ACPI_6_5_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE SIGNATURE_32('S', '3', 'P', 'T') // // FPDT Firmware S3 Boot Performance Table // typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER Header; // // one or more Performance Records. // } EFI_ACPI_6_5_FPDT_FIRMWARE_S3_BOOT_TABLE; /// /// FPDT Basic S3 Resume Performance Record /// typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// A count of the number of S3 resume cycles since the last full boot sequence. /// UINT32 ResumeCount; /// /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the /// OS waking vector. Only the most recent resume cycle's time is retained. /// UINT64 FullResume; /// /// Average timer value of all resume cycles logged since the last full boot /// sequence, including the most recent resume. Note that the entire log of /// timer values does not need to be retained in order to calculate this average. /// UINT64 AverageResume; } EFI_ACPI_6_5_FPDT_S3_RESUME_RECORD; /// /// FPDT Basic S3 Suspend Performance Record /// typedef struct { EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER Header; /// /// Timer value recorded at the OS write to SLP_TYP upon entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendStart; /// /// Timer value recorded at the final firmware write to SLP_TYP (or other /// mechanism) used to trigger hardware entry to S3. /// Only the most recent suspend cycle's timer value is retained. /// UINT64 SuspendEnd; } EFI_ACPI_6_5_FPDT_S3_SUSPEND_RECORD; /// /// Firmware Performance Record Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_5_FIRMWARE_PERFORMANCE_RECORD_TABLE; /// /// Generic Timer Description Table definition. /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT64 CntControlBasePhysicalAddress; UINT32 Reserved; UINT32 SecurePL1TimerGSIV; UINT32 SecurePL1TimerFlags; UINT32 NonSecurePL1TimerGSIV; UINT32 NonSecurePL1TimerFlags; UINT32 VirtualTimerGSIV; UINT32 VirtualTimerFlags; UINT32 NonSecurePL2TimerGSIV; UINT32 NonSecurePL2TimerFlags; UINT64 CntReadBasePhysicalAddress; UINT32 PlatformTimerCount; UINT32 PlatformTimerOffset; UINT32 VirtualPL2TimerGSIV; UINT32 VirtualPL2TimerFlags; } EFI_ACPI_6_5_GENERIC_TIMER_DESCRIPTION_TABLE; /// /// GTDT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x03 /// /// Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_5_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_5_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY BIT2 /// /// Platform Timer Type /// #define EFI_ACPI_6_5_GTDT_GT_BLOCK 0 #define EFI_ACPI_6_5_GTDT_ARM_GENERIC_WATCHDOG 1 /// /// GT Block Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 CntCtlBase; UINT32 GTBlockTimerCount; UINT32 GTBlockTimerOffset; } EFI_ACPI_6_5_GTDT_GT_BLOCK_STRUCTURE; /// /// GT Block Timer Structure /// typedef struct { UINT8 GTFrameNumber; UINT8 Reserved[3]; UINT64 CntBaseX; UINT64 CntEL0BaseX; UINT32 GTxPhysicalTimerGSIV; UINT32 GTxPhysicalTimerFlags; UINT32 GTxVirtualTimerGSIV; UINT32 GTxVirtualTimerFlags; UINT32 GTxCommonFlags; } EFI_ACPI_6_5_GTDT_GT_BLOCK_TIMER_STRUCTURE; /// /// GT Block Physical Timers and Virtual Timers Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_5_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY BIT1 /// /// Common Flags Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER BIT0 #define EFI_ACPI_6_5_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY BIT1 /// /// Arm Generic Watchdog Structure /// typedef struct { UINT8 Type; UINT16 Length; UINT8 Reserved; UINT64 RefreshFramePhysicalAddress; UINT64 WatchdogControlFramePhysicalAddress; UINT32 WatchdogTimerGSIV; UINT32 WatchdogTimerFlags; } EFI_ACPI_6_5_GTDT_ARM_GENERIC_WATCHDOG_STRUCTURE; /// /// Arm Generic Watchdog Timer Flags. All other bits are reserved and must be 0. /// #define EFI_ACPI_6_5_GTDT_ARM_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE BIT0 #define EFI_ACPI_6_5_GTDT_ARM_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY BIT1 #define EFI_ACPI_6_5_GTDT_ARM_GENERIC_WATCHDOG_FLAG_SECURE_TIMER BIT2 // // NVDIMM Firmware Interface Table definition. // typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Reserved; } EFI_ACPI_6_5_NVDIMM_FIRMWARE_INTERFACE_TABLE; // // NFIT Version (as defined in ACPI 6.5 spec.) // #define EFI_ACPI_6_5_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1 // // Definition for NFIT Table Structure Types // #define EFI_ACPI_6_5_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE 0 #define EFI_ACPI_6_5_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE 1 #define EFI_ACPI_6_5_NFIT_INTERLEAVE_STRUCTURE_TYPE 2 #define EFI_ACPI_6_5_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE 3 #define EFI_ACPI_6_5_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE 4 #define EFI_ACPI_6_5_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE 5 #define EFI_ACPI_6_5_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE 6 #define EFI_ACPI_6_5_NFIT_PLATFORM_CAPABILITIES_STRUCTURE_TYPE 7 // // Definition for NFIT Structure Header // typedef struct { UINT16 Type; UINT16 Length; } EFI_ACPI_6_5_NFIT_STRUCTURE_HEADER; // // Definition for System Physical Address Range Structure // #define EFI_ACPI_6_5_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT BIT0 #define EFI_ACPI_6_5_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID BIT1 #define EFI_ACPI_6_5_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_SPA_LOCATION_COOKIE_VALID BIT2 #define EFI_ACPI_6_5_NFIT_GUID_VOLATILE_MEMORY_REGION { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }} #define EFI_ACPI_6_5_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }} #define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }} #define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} #define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} typedef struct { UINT16 Type; UINT16 Length; UINT16 SPARangeStructureIndex; UINT16 Flags; UINT32 Reserved_8; UINT32 ProximityDomain; GUID AddressRangeTypeGUID; UINT64 SystemPhysicalAddressRangeBase; UINT64 SystemPhysicalAddressRangeLength; UINT64 AddressRangeMemoryMappingAttribute; UINT64 SPALocationCookie; } EFI_ACPI_6_5_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE; // // Definition for Memory Device to System Physical Address Range Mapping Structure // typedef struct { UINT32 DIMMNumber : 4; UINT32 MemoryChannelNumber : 4; UINT32 MemoryControllerID : 4; UINT32 SocketID : 4; UINT32 NodeControllerID : 12; UINT32 Reserved_28 : 4; } EFI_ACPI_6_5_NFIT_DEVICE_HANDLE; #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL BIT0 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL BIT1 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL BIT2 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF BIT3 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF BIT4 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS BIT5 #define EFI_ACPI_6_5_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_NOT_MAP_NVDIMM_TO_SPA BIT6 typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_5_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NVDIMMPhysicalID; UINT16 NVDIMMRegionID; UINT16 SPARangeStructureIndex; UINT16 NVDIMMControlRegionStructureIndex; UINT64 NVDIMMRegionSize; UINT64 RegionOffset; UINT64 NVDIMMPhysicalAddressRegionBase; UINT16 InterleaveStructureIndex; UINT16 InterleaveWays; UINT16 NVDIMMStateFlags; UINT16 Reserved_46; } EFI_ACPI_6_5_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE; // // Definition for Interleave Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 InterleaveStructureIndex; UINT16 Reserved_6; UINT32 NumberOfLines; UINT32 LineSize; // UINT32 LineOffset[NumberOfLines]; } EFI_ACPI_6_5_NFIT_INTERLEAVE_STRUCTURE; // // Definition for SMBIOS Management Information Structure // typedef struct { UINT16 Type; UINT16 Length; UINT32 Reserved_4; // UINT8 Data[]; } EFI_ACPI_6_5_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE; // // Definition for NVDIMM Control Region Structure // #define EFI_ACPI_6_5_NFIT_NVDIMM_CONTROL_REGION_VALID_FIELDS_MANUFACTURING BIT0 #define EFI_ACPI_6_5_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED BIT0 typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 VendorID; UINT16 DeviceID; UINT16 RevisionID; UINT16 SubsystemVendorID; UINT16 SubsystemDeviceID; UINT16 SubsystemRevisionID; UINT8 ValidFields; UINT8 ManufacturingLocation; UINT16 ManufacturingDate; UINT8 Reserved_22[2]; UINT32 SerialNumber; UINT16 RegionFormatInterfaceCode; UINT16 NumberOfBlockControlWindows; UINT64 SizeOfBlockControlWindow; UINT64 CommandRegisterOffsetInBlockControlWindow; UINT64 SizeOfCommandRegisterInBlockControlWindows; UINT64 StatusRegisterOffsetInBlockControlWindow; UINT64 SizeOfStatusRegisterInBlockControlWindows; UINT16 NVDIMMControlRegionFlag; UINT8 Reserved_74[6]; } EFI_ACPI_6_5_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE; // // Definition for NVDIMM Block Data Window Region Structure // typedef struct { UINT16 Type; UINT16 Length; UINT16 NVDIMMControlRegionStructureIndex; UINT16 NumberOfBlockDataWindows; UINT64 BlockDataWindowStartOffset; UINT64 SizeOfBlockDataWindow; UINT64 BlockAccessibleMemoryCapacity; UINT64 BeginningAddressOfFirstBlockInBlockAccessibleMemory; } EFI_ACPI_6_5_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE; // // Definition for Flush Hint Address Structure // typedef struct { UINT16 Type; UINT16 Length; EFI_ACPI_6_5_NFIT_DEVICE_HANDLE NFITDeviceHandle; UINT16 NumberOfFlushHintAddresses; UINT8 Reserved_10[6]; // UINT64 FlushHintAddress[NumberOfFlushHintAddresses]; } EFI_ACPI_6_5_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE; // // Definition for Platform Capabilities Structure // typedef struct { UINT16 Type; UINT16 Length; UINT8 HighestValidCapability; UINT8 Reserved_5[3]; UINT32 Capabilities; UINT8 Reserved_12[4]; } EFI_ACPI_6_5_NFIT_PLATFORM_CAPABILITIES_STRUCTURE; #define EFI_ACPI_6_5_NFIT_PLATFORM_CAPABILITY_CPU_CACHE_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT0 #define EFI_ACPI_6_5_NFIT_PLATFORM_CAPABILITY_MEMORY_CONTROLLER_FLUSH_TO_NVDIMM_DURABILITY_ON_POWER_LOSS BIT1 #define EFI_ACPI_6_5_NFIT_PLATFORM_CAPABILITY_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_HARDWARE_MIRRORING BIT2 /// /// Secure DEVices Table (SDEV) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_5_SECURE_DEVICES_TABLE_HEADER; /// /// SDEV Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_SECURE_DEVICES_TABLE_REVISION 0x01 /// /// Secure Device types /// #define EFI_ACPI_6_5_SDEV_TYPE_ACPI_NAMESPACE_DEVICE 0x00 #define EFI_ACPI_6_5_SDEV_TYPE_PCIE_ENDPOINT_DEVICE 0x01 /// /// Secure Device flags /// #define EFI_ACPI_6_5_SDEV_FLAG_ALLOW_HANDOFF BIT0 #define EFI_ACPI_6_5_SDEV_FLAG_SECURE_ACCESS_COMPONENTS_PRESENT BIT1 /// /// SDEV Structure Header /// typedef struct { UINT8 Type; UINT8 Flags; UINT16 Length; } EFI_ACPI_6_5_SDEV_STRUCTURE_HEADER; /// /// ACPI_NAMESPACE_DEVICE based Secure Device Structure /// typedef struct { EFI_ACPI_6_5_SDEV_STRUCTURE_HEADER Header; UINT16 DeviceIdentifierOffset; UINT16 DeviceIdentifierLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; UINT16 SecureAccessComponentsOffset; UINT16 SecureAccessComponentsLength; } EFI_ACPI_6_5_SDEV_STRUCTURE_ACPI_NAMESPACE_DEVICE; /// /// Secure Access Component Types /// #define EFI_ACPI_6_5_SDEV_SECURE_ACCESS_COMPONENT_TYPE_IDENTIFICATION 0x00 #define EFI_ACPI_6_5_SDEV_SECURE_ACCESS_COMPONENT_TYPE_MEMORY 0x01 /// /// Identification Based Secure Access Component /// typedef struct { EFI_ACPI_6_5_SDEV_STRUCTURE_HEADER Header; UINT16 HardwareIdentifierOffset; UINT16 HardwareIdentifierLength; UINT16 SubsystemIdentifierOffset; UINT16 SubsystemIdentifierLength; UINT16 HardwareRevision; UINT8 HardwareRevisionPresent; UINT8 ClassCodePresent; UINT8 PciCompatibleBaseClass; UINT8 PciCompatibleSubClass; UINT8 PciCompatibleProgrammingInterface; } EFI_ACPI_6_5_SDEV_SECURE_ACCESS_COMPONENT_IDENTIFICATION_STRUCTURE; /// /// Memory-based Secure Access Component /// typedef struct { EFI_ACPI_6_5_SDEV_STRUCTURE_HEADER Header; UINT32 Reserved; UINT64 MemoryAddressBase; UINT64 MemoryLength; } EFI_ACPI_6_5_SDEV_SECURE_ACCESS_COMPONENT_MEMORY_STRUCTURE; /// /// PCIe Endpoint Device based Secure Device Structure /// typedef struct { EFI_ACPI_6_5_SDEV_STRUCTURE_HEADER Header; UINT16 PciSegmentNumber; UINT16 StartBusNumber; UINT16 PciPathOffset; UINT16 PciPathLength; UINT16 VendorSpecificDataOffset; UINT16 VendorSpecificDataLength; } EFI_ACPI_6_5_SDEV_STRUCTURE_PCIE_ENDPOINT_DEVICE; /// /// Boot Error Record Table (BERT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 BootErrorRegionLength; UINT64 BootErrorRegion; } EFI_ACPI_6_5_BOOT_ERROR_RECORD_TABLE_HEADER; /// /// BERT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_BOOT_ERROR_RECORD_TABLE_REVISION 0x01 /// /// Boot Error Region Block Status Definition /// typedef struct { UINT32 UncorrectableErrorValid : 1; UINT32 CorrectableErrorValid : 1; UINT32 MultipleUncorrectableErrors : 1; UINT32 MultipleCorrectableErrors : 1; UINT32 ErrorDataEntryCount : 10; UINT32 Reserved : 18; } EFI_ACPI_6_5_ERROR_BLOCK_STATUS; /// /// Boot Error Region Definition /// typedef struct { EFI_ACPI_6_5_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_5_BOOT_ERROR_REGION_STRUCTURE; // // Boot Error Severity types // #define EFI_ACPI_6_5_ERROR_SEVERITY_RECOVERABLE 0x00 #define EFI_ACPI_6_5_ERROR_SEVERITY_FATAL 0x01 #define EFI_ACPI_6_5_ERROR_SEVERITY_CORRECTED 0x02 #define EFI_ACPI_6_5_ERROR_SEVERITY_NONE 0x03 // // The term 'Correctable' is no longer being used as an error severity of the // reported error since ACPI Specification Version 5.1 Errata B. // The below macro is considered as deprecated and should no longer be used. // #define EFI_ACPI_6_5_ERROR_SEVERITY_CORRECTABLE 0x00 /// /// Generic Error Data Entry Definition /// typedef struct { UINT8 SectionType[16]; UINT32 ErrorSeverity; UINT16 Revision; UINT8 ValidationBits; UINT8 Flags; UINT32 ErrorDataLength; UINT8 FruId[16]; UINT8 FruText[20]; UINT8 Timestamp[8]; } EFI_ACPI_6_5_GENERIC_ERROR_DATA_ENTRY_STRUCTURE; /// /// Generic Error Data Entry Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_GENERIC_ERROR_DATA_ENTRY_REVISION 0x0300 /// /// HEST - Hardware Error Source Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 ErrorSourceCount; } EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_HEADER; /// /// HEST Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x02 // // Error Source structure types. // #define EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION 0x00 #define EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK 0x01 #define EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR 0x02 #define EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER 0x06 #define EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER 0x07 #define EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER 0x08 #define EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR 0x09 #define EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_VERSION_2 0x0A #define EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK 0x0B // // Error Source structure flags. // #define EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST (1 << 0) #define EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GLOBAL (1 << 1) #define EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GHES_ASSIST (1 << 2) /// /// IA-32 Architecture Machine Check Exception Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT64 GlobalCapabilityInitData; UINT64 GlobalControlInitData; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[7]; } EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure Definition /// typedef struct { UINT8 BankNumber; UINT8 ClearStatusOnInitialization; UINT8 StatusDataFormat; UINT8 Reserved0; UINT32 ControlRegisterMsrAddress; UINT64 ControlInitData; UINT32 StatusRegisterMsrAddress; UINT32 AddressRegisterMsrAddress; UINT32 MiscRegisterMsrAddress; } EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE; /// /// IA-32 Architecture Machine Check Bank Structure MCA data format /// #define EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32 0x00 #define EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64 0x01 #define EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64 0x02 // // Hardware Error Notification types. All other values are reserved // #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_POLLED 0x00 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT 0x01 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT 0x02 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SCI 0x03 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_NMI 0x04 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_CMCI 0x05 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_MCE 0x06 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL 0x07 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEA 0x08 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_ARMV8_SEI 0x09 #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_GSIV 0x0A #define EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION 0x0B /// /// Hardware Error Notification Configuration Write Enable Structure Definition /// typedef struct { UINT16 Type : 1; UINT16 PollInterval : 1; UINT16 SwitchToPollingThresholdValue : 1; UINT16 SwitchToPollingThresholdWindow : 1; UINT16 ErrorThresholdValue : 1; UINT16 ErrorThresholdWindow : 1; UINT16 Reserved : 10; } EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE; /// /// Hardware Error Notification Structure Definition /// typedef struct { UINT8 Type; UINT8 Length; EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE ConfigurationWriteEnable; UINT32 PollInterval; UINT32 Vector; UINT32 SwitchToPollingThresholdValue; UINT32 SwitchToPollingThresholdWindow; UINT32 ErrorThresholdValue; UINT32 ErrorThresholdWindow; } EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE; /// /// IA-32 Architecture Corrected Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE; /// /// IA-32 Architecture NMI Error Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; } EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE; /// /// PCI Express Root Port AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 RootErrorCommand; } EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE; /// /// PCI Express Device AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER_STRUCTURE; /// /// PCI Express Bridge AER Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 Bus; UINT16 Device; UINT16 Function; UINT16 DeviceControl; UINT8 Reserved1[2]; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 SecondaryUncorrectableErrorMask; UINT32 SecondaryUncorrectableErrorSeverity; UINT32 SecondaryAdvancedErrorCapabilitiesAndControl; } EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER_STRUCTURE; /// /// Generic Hardware Error Source Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; } EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE; /// /// Generic Hardware Error Source Version 2 Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT16 RelatedSourceId; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; UINT32 MaxRawDataLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ErrorStatusAddress; EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT32 ErrorStatusBlockLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ReadAckRegister; UINT64 ReadAckPreserve; UINT64 ReadAckWrite; } EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE; /// /// Generic Error Status Definition /// typedef struct { EFI_ACPI_6_5_ERROR_BLOCK_STATUS BlockStatus; UINT32 RawDataOffset; UINT32 RawDataLength; UINT32 DataLength; UINT32 ErrorSeverity; } EFI_ACPI_6_5_GENERIC_ERROR_STATUS_STRUCTURE; /// /// IA-32 Architecture Deferred Machine Check Structure Definition /// typedef struct { UINT16 Type; UINT16 SourceId; UINT8 Reserved0[2]; UINT8 Flags; UINT8 Enabled; UINT32 NumberOfRecordsToPreAllocate; UINT32 MaxSectionsPerRecord; EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE NotificationStructure; UINT8 NumberOfHardwareBanks; UINT8 Reserved1[3]; } EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE; /// /// HMAT - Heterogeneous Memory Attribute Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 Reserved[4]; } EFI_ACPI_6_5_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER; /// /// HMAT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION 0x02 /// /// HMAT types /// #define EFI_ACPI_6_5_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES 0x00 #define EFI_ACPI_6_5_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO 0x01 #define EFI_ACPI_6_5_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO 0x02 /// /// HMAT Structure Header /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; } EFI_ACPI_6_5_HMAT_STRUCTURE_HEADER; /// /// Memory Proximity Domain Attributes Structure flags /// typedef struct { UINT16 InitiatorProximityDomainValid : 1; UINT16 Reserved : 15; } EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS; /// /// Memory Proximity Domain Attributes Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_FLAGS Flags; UINT8 Reserved1[2]; UINT32 InitiatorProximityDomain; UINT32 MemoryProximityDomain; UINT8 Reserved2[20]; } EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES; /// /// System Locality Latency and Bandwidth Information Structure flags /// typedef struct { UINT8 MemoryHierarchy : 4; UINT8 AccessAttributes : 2; UINT8 Reserved : 2; } EFI_ACPI_6_5_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS; /// /// System Locality Latency and Bandwidth Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; EFI_ACPI_6_5_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS Flags; UINT8 DataType; UINT8 MinTransferSize; UINT8 Reserved1; UINT32 NumberOfInitiatorProximityDomains; UINT32 NumberOfTargetProximityDomains; UINT8 Reserved2[4]; UINT64 EntryBaseUnit; } EFI_ACPI_6_5_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO; /// /// Memory Side Cache Information Structure cache attributes /// typedef struct { UINT32 TotalCacheLevels : 4; UINT32 CacheLevel : 4; UINT32 CacheAssociativity : 4; UINT32 WritePolicy : 4; UINT32 CacheLineSize : 16; } EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES; /// /// Memory Side Cache Information Structure /// typedef struct { UINT16 Type; UINT8 Reserved[2]; UINT32 Length; UINT32 MemoryProximityDomain; UINT8 Reserved1[4]; UINT64 MemorySideCacheSize; EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES CacheAttributes; UINT8 Reserved2[2]; UINT16 NumberOfSmbiosHandles; } EFI_ACPI_6_5_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO; /// /// ERST - Error Record Serialization Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 SerializationHeaderSize; UINT8 Reserved0[4]; UINT32 InstructionEntryCount; } EFI_ACPI_6_5_ERROR_RECORD_SERIALIZATION_TABLE_HEADER; /// /// ERST Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01 /// /// ERST Serialization Actions /// #define EFI_ACPI_6_5_ERST_BEGIN_WRITE_OPERATION 0x00 #define EFI_ACPI_6_5_ERST_BEGIN_READ_OPERATION 0x01 #define EFI_ACPI_6_5_ERST_BEGIN_CLEAR_OPERATION 0x02 #define EFI_ACPI_6_5_ERST_END_OPERATION 0x03 #define EFI_ACPI_6_5_ERST_SET_RECORD_OFFSET 0x04 #define EFI_ACPI_6_5_ERST_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_5_ERST_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_5_ERST_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_5_ERST_GET_RECORD_IDENTIFIER 0x08 #define EFI_ACPI_6_5_ERST_SET_RECORD_IDENTIFIER 0x09 #define EFI_ACPI_6_5_ERST_GET_RECORD_COUNT 0x0A #define EFI_ACPI_6_5_ERST_BEGIN_DUMMY_WRITE_OPERATION 0x0B #define EFI_ACPI_6_5_ERST_GET_ERROR_LOG_ADDRESS_RANGE 0x0D #define EFI_ACPI_6_5_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH 0x0E #define EFI_ACPI_6_5_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0x0F #define EFI_ACPI_6_5_ERST_GET_EXECUTE_OPERATION_TIMINGS 0x10 /// /// ERST Action Command Status /// #define EFI_ACPI_6_5_ERST_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_5_ERST_STATUS_NOT_ENOUGH_SPACE 0x01 #define EFI_ACPI_6_5_ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x02 #define EFI_ACPI_6_5_ERST_STATUS_FAILED 0x03 #define EFI_ACPI_6_5_ERST_STATUS_RECORD_STORE_EMPTY 0x04 #define EFI_ACPI_6_5_ERST_STATUS_RECORD_NOT_FOUND 0x05 /// /// ERST Serialization Instructions /// #define EFI_ACPI_6_5_ERST_READ_REGISTER 0x00 #define EFI_ACPI_6_5_ERST_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_5_ERST_WRITE_REGISTER 0x02 #define EFI_ACPI_6_5_ERST_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_5_ERST_NOOP 0x04 #define EFI_ACPI_6_5_ERST_LOAD_VAR1 0x05 #define EFI_ACPI_6_5_ERST_LOAD_VAR2 0x06 #define EFI_ACPI_6_5_ERST_STORE_VAR1 0x07 #define EFI_ACPI_6_5_ERST_ADD 0x08 #define EFI_ACPI_6_5_ERST_SUBTRACT 0x09 #define EFI_ACPI_6_5_ERST_ADD_VALUE 0x0A #define EFI_ACPI_6_5_ERST_SUBTRACT_VALUE 0x0B #define EFI_ACPI_6_5_ERST_STALL 0x0C #define EFI_ACPI_6_5_ERST_STALL_WHILE_TRUE 0x0D #define EFI_ACPI_6_5_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E #define EFI_ACPI_6_5_ERST_GOTO 0x0F #define EFI_ACPI_6_5_ERST_SET_SRC_ADDRESS_BASE 0x10 #define EFI_ACPI_6_5_ERST_SET_DST_ADDRESS_BASE 0x11 #define EFI_ACPI_6_5_ERST_MOVE_DATA 0x12 /// /// ERST Instruction Flags /// #define EFI_ACPI_6_5_ERST_PRESERVE_REGISTER 0x01 /// /// ERST Serialization Instruction Entry /// typedef struct { UINT8 SerializationAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_5_ERST_SERIALIZATION_INSTRUCTION_ENTRY; /// /// EINJ - Error Injection Table /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 InjectionHeaderSize; UINT8 InjectionFlags; UINT8 Reserved0[3]; UINT32 InjectionEntryCount; } EFI_ACPI_6_5_ERROR_INJECTION_TABLE_HEADER; /// /// EINJ Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION 0x02 /// /// EINJ Error Injection Actions /// #define EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION 0x00 #define EFI_ACPI_6_5_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE 0x01 #define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE 0x02 #define EFI_ACPI_6_5_EINJ_GET_ERROR_TYPE 0x03 #define EFI_ACPI_6_5_EINJ_END_OPERATION 0x04 #define EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION 0x05 #define EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS 0x06 #define EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS 0x07 #define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08 #define EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09 #define EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE 0x10 #define EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE 0x11 #define EFI_ACPI_6_5_EINJ_TRIGGER_ERROR 0xFF /// /// EINJ Action Command Status /// #define EFI_ACPI_6_5_EINJ_STATUS_SUCCESS 0x00 #define EFI_ACPI_6_5_EINJ_STATUS_UNKNOWN_FAILURE 0x01 #define EFI_ACPI_6_5_EINJ_STATUS_INVALID_ACCESS 0x02 /// /// EINJ Error Type Definition /// #define EFI_ACPI_6_5_EINJ_ERROR_PROCESSOR_CORRECTABLE (1 << 0) #define EFI_ACPI_6_5_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL (1 << 1) #define EFI_ACPI_6_5_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL (1 << 2) #define EFI_ACPI_6_5_EINJ_ERROR_MEMORY_CORRECTABLE (1 << 3) #define EFI_ACPI_6_5_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL (1 << 4) #define EFI_ACPI_6_5_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL (1 << 5) #define EFI_ACPI_6_5_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE (1 << 6) #define EFI_ACPI_6_5_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL (1 << 7) #define EFI_ACPI_6_5_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL (1 << 8) #define EFI_ACPI_6_5_EINJ_ERROR_PLATFORM_CORRECTABLE (1 << 9) #define EFI_ACPI_6_5_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL (1 << 10) #define EFI_ACPI_6_5_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL (1 << 11) /// /// EINJ Injection Instructions /// #define EFI_ACPI_6_5_EINJ_READ_REGISTER 0x00 #define EFI_ACPI_6_5_EINJ_READ_REGISTER_VALUE 0x01 #define EFI_ACPI_6_5_EINJ_WRITE_REGISTER 0x02 #define EFI_ACPI_6_5_EINJ_WRITE_REGISTER_VALUE 0x03 #define EFI_ACPI_6_5_EINJ_NOOP 0x04 /// /// EINJ Instruction Flags /// #define EFI_ACPI_6_5_EINJ_PRESERVE_REGISTER 0x01 /// /// EINJ Injection Instruction Entry /// typedef struct { UINT8 InjectionAction; UINT8 Instruction; UINT8 Flags; UINT8 Reserved0; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE RegisterRegion; UINT64 Value; UINT64 Mask; } EFI_ACPI_6_5_EINJ_INJECTION_INSTRUCTION_ENTRY; /// /// EINJ Trigger Action Table /// typedef struct { UINT32 HeaderSize; UINT32 Revision; UINT32 TableSize; UINT32 EntryCount; } EFI_ACPI_6_5_EINJ_TRIGGER_ACTION_TABLE; /// /// Platform Communications Channel Table (PCCT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT32 Flags; UINT64 Reserved; } EFI_ACPI_6_5_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER; /// /// PCCT Version (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x02 /// /// PCCT Global Flags /// #define EFI_ACPI_6_5_PCCT_FLAGS_PLATFORM_INTERRUPT BIT0 // // PCCT Subspace type // #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_GENERIC 0x00 #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS 0x01 #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS 0x02 #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC 0x03 #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC 0x04 #define EFI_ACPI_6_5_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS 0x05 /// /// PCC Subspace Structure Header /// typedef struct { UINT8 Type; UINT8 Length; } EFI_ACPI_6_5_PCCT_SUBSPACE_HEADER; /// /// Generic Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[6]; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_5_PCCT_SUBSPACE_GENERIC; /// /// Generic Communications Channel Shared Memory Region /// typedef struct { UINT8 Command; UINT8 Reserved : 7; UINT8 NotifyOnCompletion : 1; } EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND; typedef struct { UINT8 CommandComplete : 1; UINT8 PlatformInterrupt : 1; UINT8 Error : 1; UINT8 PlatformNotification : 1; UINT8 Reserved : 4; UINT8 Reserved1; } EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS; typedef struct { UINT32 Signature; EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND Command; EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS Status; } EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER; #define EFI_ACPI_6_5_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_POLARITY BIT0 #define EFI_ACPI_6_5_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE BIT1 /// /// Type 1 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; } EFI_ACPI_6_5_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS; /// /// Type 2 HW-Reduced Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT64 AddressLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT16 MinimumRequestTurnaroundTime; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckWrite; } EFI_ACPI_6_5_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS; /// /// Type 3 Extended PCC Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT32 PlatformInterrupt; UINT8 PlatformInterruptFlags; UINT8 Reserved; UINT64 BaseAddress; UINT32 AddressLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; UINT32 NominalLatency; UINT32 MaximumPeriodicAccessRate; UINT32 MinimumRequestTurnaroundTime; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE PlatformInterruptAckRegister; UINT64 PlatformInterruptAckPreserve; UINT64 PlatformInterruptAckSet; UINT8 Reserved1[8]; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE CommandCompleteUpdateRegister; UINT64 CommandCompleteUpdatePreserve; UINT64 CommandCompleteUpdateSet; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; } EFI_ACPI_6_5_PCCT_SUBSPACE_3_EXTENDED_PCC; /// /// Type 4 Extended PCC Subspace Structure /// typedef EFI_ACPI_6_5_PCCT_SUBSPACE_3_EXTENDED_PCC EFI_ACPI_6_5_PCCT_SUBSPACE_4_EXTENDED_PCC; #define EFI_ACPI_6_5_PCCT_MASTER_SLAVE_COMMUNICATIONS_CHANNEL_FLAGS_NOTIFY_ON_COMPLETION BIT0 typedef struct { UINT32 Signature; UINT32 Flags; UINT32 Length; UINT32 Command; } EFI_ACPI_6_5_PCCT_EXTENDED_PCC_SHARED_MEMORY_REGION_HEADER; /// /// Type 5 HW Registers based Communications Subspace Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT16 Version; UINT64 BaseAddress; UINT64 SharedMemoryRangeLength; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE DoorbellRegister; UINT64 DoorbellPreserve; UINT64 DoorbellWrite; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE CommandCompleteCheckRegister; UINT64 CommandCompleteCheckMask; EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ErrorStatusRegister; UINT64 ErrorStatusMask; UINT32 NominalLatency; UINT32 MinimumRequestTurnaroundTime; } EFI_ACPI_6_5_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS; /// /// Reduced PCC Subspace Shared Memory Region /// typedef struct { UINT32 Signature; // UINT8 CommunicationSubspace[]; } EFI_6_5_PCCT_REDUCED_PCC_SUBSPACE_SHARED_MEMORY_REGION; /// /// Platform Debug Trigger Table (PDTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; UINT8 TriggerCount; UINT8 Reserved[3]; UINT32 TriggerIdentifierArrayOffset; } EFI_ACPI_6_5_PLATFORM_DEBUG_TRIGGER_TABLE_HEADER; /// /// PDTT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_PLATFORM_DEBUG_TRIGGER_TABLE_REVISION 0x00 /// /// PDTT Platform Communication Channel Identifier Structure /// typedef struct { UINT16 SubChannelIdentifer : 8; UINT16 Runtime : 1; UINT16 WaitForCompletion : 1; UINT16 TriggerOrder : 1; UINT16 Reserved : 5; } EFI_ACPI_6_5_PDTT_PCC_IDENTIFIER; /// /// PCC Commands Codes used by Platform Debug Trigger Table /// #define EFI_ACPI_6_5_PDTT_PCC_COMMAND_DOORBELL_ONLY 0x00 #define EFI_ACPI_6_5_PDTT_PCC_COMMAND_VENDOR_SPECIFIC 0x01 /// /// PDTT Platform Communication Channel /// typedef EFI_ACPI_6_5_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER EFI_ACPI_6_5_PDTT_PCC; /// /// Processor Properties Topology Table (PPTT) /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; } EFI_ACPI_6_5_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER; /// /// PPTT Revision (as defined in ACPI 6.5 spec.) /// #define EFI_ACPI_6_5_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION 0x03 /// /// PPTT types /// #define EFI_ACPI_6_5_PPTT_TYPE_PROCESSOR 0x00 #define EFI_ACPI_6_5_PPTT_TYPE_CACHE 0x01 /// /// PPTT Structure Header /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; } EFI_ACPI_6_5_PPTT_STRUCTURE_HEADER; /// /// For PPTT struct processor flags /// #define EFI_ACPI_6_5_PPTT_PACKAGE_NOT_PHYSICAL 0x0 #define EFI_ACPI_6_5_PPTT_PACKAGE_PHYSICAL 0x1 #define EFI_ACPI_6_5_PPTT_PROCESSOR_ID_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_PROCESSOR_ID_VALID 0x1 #define EFI_ACPI_6_5_PPTT_PROCESSOR_IS_NOT_THREAD 0x0 #define EFI_ACPI_6_5_PPTT_PROCESSOR_IS_THREAD 0x1 #define EFI_ACPI_6_5_PPTT_NODE_IS_NOT_LEAF 0x0 #define EFI_ACPI_6_5_PPTT_NODE_IS_LEAF 0x1 #define EFI_ACPI_6_5_PPTT_IMPLEMENTATION_NOT_IDENTICAL 0x0 #define EFI_ACPI_6_5_PPTT_IMPLEMENTATION_IDENTICAL 0x1 /// /// Processor hierarchy node structure flags /// typedef struct { UINT32 PhysicalPackage : 1; UINT32 AcpiProcessorIdValid : 1; UINT32 ProcessorIsAThread : 1; UINT32 NodeIsALeaf : 1; UINT32 IdenticalImplementation : 1; UINT32 Reserved : 27; } EFI_ACPI_6_5_PPTT_STRUCTURE_PROCESSOR_FLAGS; /// /// Processor hierarchy node structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_5_PPTT_STRUCTURE_PROCESSOR_FLAGS Flags; UINT32 Parent; UINT32 AcpiProcessorId; UINT32 NumberOfPrivateResources; } EFI_ACPI_6_5_PPTT_STRUCTURE_PROCESSOR; /// /// For PPTT struct cache flags /// #define EFI_ACPI_6_5_PPTT_CACHE_SIZE_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_CACHE_SIZE_VALID 0x1 #define EFI_ACPI_6_5_PPTT_NUMBER_OF_SETS_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_NUMBER_OF_SETS_VALID 0x1 #define EFI_ACPI_6_5_PPTT_ASSOCIATIVITY_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_ASSOCIATIVITY_VALID 0x1 #define EFI_ACPI_6_5_PPTT_ALLOCATION_TYPE_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_ALLOCATION_TYPE_VALID 0x1 #define EFI_ACPI_6_5_PPTT_CACHE_TYPE_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_CACHE_TYPE_VALID 0x1 #define EFI_ACPI_6_5_PPTT_WRITE_POLICY_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_WRITE_POLICY_VALID 0x1 #define EFI_ACPI_6_5_PPTT_LINE_SIZE_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_LINE_SIZE_VALID 0x1 #define EFI_ACPI_6_5_PPTT_CACHE_ID_INVALID 0x0 #define EFI_ACPI_6_5_PPTT_CACHE_ID_VALID 0x1 /// /// Cache Type Structure flags /// typedef struct { UINT32 SizePropertyValid : 1; UINT32 NumberOfSetsValid : 1; UINT32 AssociativityValid : 1; UINT32 AllocationTypeValid : 1; UINT32 CacheTypeValid : 1; UINT32 WritePolicyValid : 1; UINT32 LineSizeValid : 1; UINT32 CacheIdValid : 1; UINT32 Reserved : 24; } EFI_ACPI_6_5_PPTT_STRUCTURE_CACHE_FLAGS; /// /// For cache attributes /// #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_ALLOCATION_READ 0x0 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_ALLOCATION_WRITE 0x1 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE 0x2 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_CACHE_TYPE_DATA 0x0 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION 0x1 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED 0x2 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK 0x0 #define EFI_ACPI_6_5_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_THROUGH 0x1 /// /// Cache Type Structure cache attributes /// typedef struct { UINT8 AllocationType : 2; UINT8 CacheType : 2; UINT8 WritePolicy : 1; UINT8 Reserved : 3; } EFI_ACPI_6_5_PPTT_STRUCTURE_CACHE_ATTRIBUTES; /// /// Cache Type Structure /// typedef struct { UINT8 Type; UINT8 Length; UINT8 Reserved[2]; EFI_ACPI_6_5_PPTT_STRUCTURE_CACHE_FLAGS Flags; UINT32 NextLevelOfCache; UINT32 Size; UINT32 NumberOfSets; UINT8 Associativity; EFI_ACPI_6_5_PPTT_STRUCTURE_CACHE_ATTRIBUTES Attributes; UINT16 LineSize; UINT32 CacheId; } EFI_ACPI_6_5_PPTT_STRUCTURE_CACHE; /// /// Platform Health Assessment Table (PHAT) Format /// typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; // UINT8 PlatformTelemetryRecords[]; } EFI_ACPI_6_5_PLATFORM_HEALTH_ASSESSMENT_TABLE; #define EFI_ACPI_6_5_PLATFORM_HEALTH_ASSESSMENT_TABLE_REVISION 0x01 /// /// PHAT Record Format /// typedef struct { UINT16 PlatformHealthAssessmentRecordType; UINT16 RecordLength; UINT8 Revision; // UINT8 Data[]; } EFI_ACPI_6_5_PHAT_RECORD; /// /// PHAT Record Type Format /// #define EFI_ACPI_6_5_PHAT_RECORD_TYPE_FIRMWARE_VERSION_DATA_RECORD 0x0000 #define EFI_ACPI_6_5_PHAT_RECORD_TYPE_FIRMWARE_HEALTH_DATA_RECORD 0x0001 /// /// PHAT Version Element /// typedef struct { GUID ComponentId; UINT64 VersionValue; UINT32 ProducerId; } EFI_ACPI_6_5_PHAT_VERSION_ELEMENT; /// /// PHAT Firmware Version Data Record /// typedef struct { UINT16 PlatformRecordType; UINT16 RecordLength; UINT8 Revision; UINT8 Reserved[3]; UINT32 RecordCount; // UINT8 PhatVersionElement[]; } EFI_ACPI_6_5_PHAT_FIRMWARE_VERISON_DATA_RECORD; #define EFI_ACPI_6_5_PHAT_FIRMWARE_VERSION_DATA_RECORD_REVISION 0x01 /// /// Firmware Health Data Record Structure /// typedef struct { UINT16 PlatformRecordType; UINT16 RecordLength; UINT8 Revision; UINT16 Reserved; UINT8 AmHealthy; GUID DeviceSignature; UINT32 DeviceSpecificDataOffset; // UINT8 DevicePath[]; // UINT8 DeviceSpecificData[]; } EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_STRUCTURE; #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_REVISION 0x01 /// /// Firmware Health Data Record device health state /// #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ERRORS_FOUND 0x00 #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_NO_ERRORS_FOUND 0x01 #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_UNKNOWN 0x02 #define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ADVISORY 0x03 /// /// Reset Reason Health Record Vendor Data Entry /// typedef struct { GUID VendorDataID; UINT16 Length; UINT16 Revision; // UINTN Data[]; } EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY; /// /// Reset Reason Health Record Structure /// typedef struct { UINT8 SupportedSources; UINT8 Source; UINT8 SubSource; UINT8 Reason; UINT16 VendorCount; // EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY VendorSpecificResetReasonEntry[]; } EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_STRUCTURE; #define EFI_ACPI_6_5_PHAT_RESET_REASON_HEADER_GUID { 0x7a014ce2, 0xf263, 0x4b77, { 0xb8, 0x8a, 0xe6, 0x33, 0x6b, 0x78, 0x2c, 0x14 }} #define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_UNKNOWN BIT0 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_HARDWARE BIT1 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_FIRMWARE BIT2 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SOFTWARE BIT3 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SUPERVISOR BIT4 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_UNKNOWN BIT0 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_HARDWARE BIT1 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_FIRMWARE BIT2 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SOFTWARE BIT3 #define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SUPERVISOR BIT4 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNKNOWN 0x00 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_BOOT 0x01 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_RESET 0x02 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_WARM_RESET 0x03 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UPDATE 0x04 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNEXPECTED_RESET 0x20 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_FAULT 0x21 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_TIMEOUT 0x22 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_THERMAL 0x23 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_LOSS 0x24 #define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_BUTTON 0x25 // // Known table signatures // /// /// "RSD PTR " Root System Description Pointer /// #define EFI_ACPI_6_5_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ') /// /// "APIC" Multiple APIC Description Table /// #define EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'I', 'C') /// /// "APMT" Arm Performance Monitoring Unit Table /// #define EFI_ACPI_6_5_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE SIGNATURE_32('A', 'P', 'M', 'T') /// /// "BERT" Boot Error Record Table /// #define EFI_ACPI_6_5_BOOT_ERROR_RECORD_TABLE_SIGNATURE SIGNATURE_32('B', 'E', 'R', 'T') /// /// "BGRT" Boot Graphics Resource Table /// #define EFI_ACPI_6_5_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('B', 'G', 'R', 'T') /// /// "CDIT" Component Distance Information Table /// #define EFI_ACPI_6_5_COMPONENT_DISTANCE_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('C', 'D', 'I', 'T') /// /// "CPEP" Corrected Platform Error Polling Table /// #define EFI_ACPI_6_5_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE SIGNATURE_32('C', 'P', 'E', 'P') /// /// "CRAT" Component Resource Attribute Table /// #define EFI_ACPI_6_5_COMPONENT_RESOURCE_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('C', 'R', 'A', 'T') /// /// "DSDT" Differentiated System Description Table /// #define EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('D', 'S', 'D', 'T') /// /// "ECDT" Embedded Controller Boot Resources Table /// #define EFI_ACPI_6_5_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE SIGNATURE_32('E', 'C', 'D', 'T') /// /// "EINJ" Error Injection Table /// #define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_SIGNATURE SIGNATURE_32('E', 'I', 'N', 'J') /// /// "ERST" Error Record Serialization Table /// #define EFI_ACPI_6_5_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE SIGNATURE_32('E', 'R', 'S', 'T') /// /// "FACP" Fixed ACPI Description Table /// #define EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'P') /// /// "FACS" Firmware ACPI Control Structure /// #define EFI_ACPI_6_5_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE SIGNATURE_32('F', 'A', 'C', 'S') /// /// "FPDT" Firmware Performance Data Table /// #define EFI_ACPI_6_5_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE SIGNATURE_32('F', 'P', 'D', 'T') /// /// "GTDT" Generic Timer Description Table /// #define EFI_ACPI_6_5_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('G', 'T', 'D', 'T') /// /// "HEST" Hardware Error Source Table /// #define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('H', 'E', 'S', 'T') /// /// "HMAT" Heterogeneous Memory Attribute Table /// #define EFI_ACPI_6_5_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE SIGNATURE_32('H', 'M', 'A', 'T') /// /// "MPST" Memory Power State Table /// #define EFI_ACPI_6_5_MEMORY_POWER_STATE_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'S', 'T') /// /// "MSCT" Maximum System Characteristics Table /// #define EFI_ACPI_6_5_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'C', 'T') /// /// "NFIT" NVDIMM Firmware Interface Table /// #define EFI_ACPI_6_5_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('N', 'F', 'I', 'T') /// /// "PDTT" Platform Debug Trigger Table /// #define EFI_ACPI_6_5_PLATFORM_DEBUG_TRIGGER_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'D', 'T', 'T') /// /// "PMTT" Platform Memory Topology Table /// #define EFI_ACPI_6_5_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE SIGNATURE_32('P', 'M', 'T', 'T') /// /// "PPTT" Processor Properties Topology Table /// #define EFI_ACPI_6_5_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('P', 'P', 'T', 'T') /// /// "PSDT" Persistent System Description Table /// #define EFI_ACPI_6_5_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T') /// /// "RAS2" ACPI RAS2 Feature Table /// #define EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', '2') /// /// "RASF" ACPI RAS Feature Table /// #define EFI_ACPI_6_5_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F') /// /// "RSDT" Root System Description Table /// #define EFI_ACPI_6_5_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('R', 'S', 'D', 'T') /// /// "SBST" Smart Battery Specification Table /// #define EFI_ACPI_6_5_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE SIGNATURE_32('S', 'B', 'S', 'T') /// /// "SDEV" Secure DEVices Table /// #define EFI_ACPI_6_5_SECURE_DEVICES_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'V') /// /// "SLIT" System Locality Information Table /// #define EFI_ACPI_6_5_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'T') /// /// "SRAT" System Resource Affinity Table /// #define EFI_ACPI_6_5_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE SIGNATURE_32('S', 'R', 'A', 'T') /// /// "SSDT" Secondary System Description Table /// #define EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('S', 'S', 'D', 'T') /// /// "XSDT" Extended System Description Table /// #define EFI_ACPI_6_5_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('X', 'S', 'D', 'T') /// /// "BOOT" MS Simple Boot Spec /// #define EFI_ACPI_6_5_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE SIGNATURE_32('B', 'O', 'O', 'T') /// /// "CSRT" MS Core System Resource Table /// #define EFI_ACPI_6_5_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('C', 'S', 'R', 'T') /// /// "DBG2" MS Debug Port 2 Spec /// #define EFI_ACPI_6_5_DEBUG_PORT_2_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '2') /// /// "DBGP" MS Debug Port Spec /// #define EFI_ACPI_6_5_DEBUG_PORT_TABLE_SIGNATURE SIGNATURE_32('D', 'B', 'G', 'P') /// /// "DMAR" DMA Remapping Table /// #define EFI_ACPI_6_5_DMA_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('D', 'M', 'A', 'R') /// /// "DRTM" Dynamic Root of Trust for Measurement Table /// #define EFI_ACPI_6_5_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE SIGNATURE_32('D', 'R', 'T', 'M') /// /// "ETDT" Event Timer Description Table /// #define EFI_ACPI_6_5_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('E', 'T', 'D', 'T') /// /// "HPET" IA-PC High Precision Event Timer Table /// #define EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE SIGNATURE_32('H', 'P', 'E', 'T') /// /// "iBFT" iSCSI Boot Firmware Table /// #define EFI_ACPI_6_5_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE SIGNATURE_32('i', 'B', 'F', 'T') /// /// "IORT" I/O Remapping Table /// #define EFI_ACPI_6_5_IO_REMAPPING_TABLE_SIGNATURE SIGNATURE_32('I', 'O', 'R', 'T') /// /// "IVRS" I/O Virtualization Reporting Structure /// #define EFI_ACPI_6_5_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE SIGNATURE_32('I', 'V', 'R', 'S') /// /// "LPIT" Low Power Idle Table /// #define EFI_ACPI_6_5_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE SIGNATURE_32('L', 'P', 'I', 'T') /// /// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table /// #define EFI_ACPI_6_5_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'F', 'G') /// /// "MCHI" Management Controller Host Interface Table /// #define EFI_ACPI_6_5_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('M', 'C', 'H', 'I') /// /// "MSDM" MS Data Management Table /// #define EFI_ACPI_6_5_DATA_MANAGEMENT_TABLE_SIGNATURE SIGNATURE_32('M', 'S', 'D', 'M') /// /// "PCCT" Platform Communications Channel Table /// #define EFI_ACPI_6_5_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE SIGNATURE_32('P', 'C', 'C', 'T') /// /// "PHAT" Platform Health Assessment Table /// #define EFI_ACPI_6_5_PLATFORM_HEALTH_ASSESSMENT_TABLE_SIGNATURE SIGNATURE_32('P', 'H', 'A', 'T') /// /// "SDEI" Software Delegated Exceptions Interface Table /// #define EFI_ACPI_6_5_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'I') /// /// "SLIC" MS Software Licensing Table Specification /// #define EFI_ACPI_6_5_SOFTWARE_LICENSING_TABLE_SIGNATURE SIGNATURE_32('S', 'L', 'I', 'C') /// /// "SPCR" Serial Port Concole Redirection Table /// #define EFI_ACPI_6_5_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'C', 'R') /// /// "SPMI" Server Platform Management Interface Table /// #define EFI_ACPI_6_5_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'P', 'M', 'I') /// /// "STAO" _STA Override Table /// #define EFI_ACPI_6_5_STA_OVERRIDE_TABLE_SIGNATURE SIGNATURE_32('S', 'T', 'A', 'O') /// /// "TCPA" Trusted Computing Platform Alliance Capabilities Table /// #define EFI_ACPI_6_5_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('T', 'C', 'P', 'A') /// /// "TPM2" Trusted Computing Platform 1 Table /// #define EFI_ACPI_6_5_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE SIGNATURE_32('T', 'P', 'M', '2') /// /// "UEFI" UEFI ACPI Data Table /// #define EFI_ACPI_6_5_UEFI_ACPI_DATA_TABLE_SIGNATURE SIGNATURE_32('U', 'E', 'F', 'I') /// /// "WAET" Windows ACPI Emulated Devices Table /// #define EFI_ACPI_6_5_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE SIGNATURE_32('W', 'A', 'E', 'T') /// /// "WDAT" Watchdog Action Table /// #define EFI_ACPI_6_5_WATCHDOG_ACTION_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'A', 'T') /// /// "WDRT" Watchdog Resource Table /// #define EFI_ACPI_6_5_WATCHDOG_RESOURCE_TABLE_SIGNATURE SIGNATURE_32('W', 'D', 'R', 'T') /// /// "WPBT" MS Platform Binary Table /// #define EFI_ACPI_6_5_PLATFORM_BINARY_TABLE_SIGNATURE SIGNATURE_32('W', 'P', 'B', 'T') /// /// "WSMT" Windows SMM Security Mitigation Table /// #define EFI_ACPI_6_5_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE SIGNATURE_32('W', 'S', 'M', 'T') /// /// "XENV" Xen Project Table /// #define EFI_ACPI_6_5_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V') /// /// "MPAM" Memory System Resource Partitioning and Monitoring Table /// #define EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'A', 'M') #pragma pack() #endif ================================================ FILE: src/edk2/AcpiAml.h ================================================ /** @file This file contains AML code definition in the latest ACPI spec. Copyright (c) 2011, Intel Corporation. All rights reserved.
Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_AML_H_ #define _ACPI_AML_H_ // // ACPI AML definition // // // Primary OpCode // #define AML_ZERO_OP 0x00 #define AML_ONE_OP 0x01 #define AML_ALIAS_OP 0x06 #define AML_NAME_OP 0x08 #define AML_BYTE_PREFIX 0x0a #define AML_WORD_PREFIX 0x0b #define AML_DWORD_PREFIX 0x0c #define AML_STRING_PREFIX 0x0d #define AML_QWORD_PREFIX 0x0e #define AML_SCOPE_OP 0x10 #define AML_BUFFER_OP 0x11 #define AML_PACKAGE_OP 0x12 #define AML_VAR_PACKAGE_OP 0x13 #define AML_METHOD_OP 0x14 #define AML_EXTERNAL_OP 0x15 #define AML_DUAL_NAME_PREFIX 0x2e #define AML_MULTI_NAME_PREFIX 0x2f #define AML_NAME_CHAR_A 0x41 #define AML_NAME_CHAR_B 0x42 #define AML_NAME_CHAR_C 0x43 #define AML_NAME_CHAR_D 0x44 #define AML_NAME_CHAR_E 0x45 #define AML_NAME_CHAR_F 0x46 #define AML_NAME_CHAR_G 0x47 #define AML_NAME_CHAR_H 0x48 #define AML_NAME_CHAR_I 0x49 #define AML_NAME_CHAR_J 0x4a #define AML_NAME_CHAR_K 0x4b #define AML_NAME_CHAR_L 0x4c #define AML_NAME_CHAR_M 0x4d #define AML_NAME_CHAR_N 0x4e #define AML_NAME_CHAR_O 0x4f #define AML_NAME_CHAR_P 0x50 #define AML_NAME_CHAR_Q 0x51 #define AML_NAME_CHAR_R 0x52 #define AML_NAME_CHAR_S 0x53 #define AML_NAME_CHAR_T 0x54 #define AML_NAME_CHAR_U 0x55 #define AML_NAME_CHAR_V 0x56 #define AML_NAME_CHAR_W 0x57 #define AML_NAME_CHAR_X 0x58 #define AML_NAME_CHAR_Y 0x59 #define AML_NAME_CHAR_Z 0x5a #define AML_ROOT_CHAR 0x5c #define AML_PARENT_PREFIX_CHAR 0x5e #define AML_NAME_CHAR__ 0x5f #define AML_LOCAL0 0x60 #define AML_LOCAL1 0x61 #define AML_LOCAL2 0x62 #define AML_LOCAL3 0x63 #define AML_LOCAL4 0x64 #define AML_LOCAL5 0x65 #define AML_LOCAL6 0x66 #define AML_LOCAL7 0x67 #define AML_ARG0 0x68 #define AML_ARG1 0x69 #define AML_ARG2 0x6a #define AML_ARG3 0x6b #define AML_ARG4 0x6c #define AML_ARG5 0x6d #define AML_ARG6 0x6e #define AML_STORE_OP 0x70 #define AML_REF_OF_OP 0x71 #define AML_ADD_OP 0x72 #define AML_CONCAT_OP 0x73 #define AML_SUBTRACT_OP 0x74 #define AML_INCREMENT_OP 0x75 #define AML_DECREMENT_OP 0x76 #define AML_MULTIPLY_OP 0x77 #define AML_DIVIDE_OP 0x78 #define AML_SHIFT_LEFT_OP 0x79 #define AML_SHIFT_RIGHT_OP 0x7a #define AML_AND_OP 0x7b #define AML_NAND_OP 0x7c #define AML_OR_OP 0x7d #define AML_NOR_OP 0x7e #define AML_XOR_OP 0x7f #define AML_NOT_OP 0x80 #define AML_FIND_SET_LEFT_BIT_OP 0x81 #define AML_FIND_SET_RIGHT_BIT_OP 0x82 #define AML_DEREF_OF_OP 0x83 #define AML_CONCAT_RES_OP 0x84 #define AML_MOD_OP 0x85 #define AML_NOTIFY_OP 0x86 #define AML_SIZE_OF_OP 0x87 #define AML_INDEX_OP 0x88 #define AML_MATCH_OP 0x89 #define AML_CREATE_DWORD_FIELD_OP 0x8a #define AML_CREATE_WORD_FIELD_OP 0x8b #define AML_CREATE_BYTE_FIELD_OP 0x8c #define AML_CREATE_BIT_FIELD_OP 0x8d #define AML_OBJECT_TYPE_OP 0x8e #define AML_CREATE_QWORD_FIELD_OP 0x8f #define AML_LAND_OP 0x90 #define AML_LOR_OP 0x91 #define AML_LNOT_OP 0x92 #define AML_LEQUAL_OP 0x93 #define AML_LGREATER_OP 0x94 #define AML_LLESS_OP 0x95 #define AML_TO_BUFFER_OP 0x96 #define AML_TO_DEC_STRING_OP 0x97 #define AML_TO_HEX_STRING_OP 0x98 #define AML_TO_INTEGER_OP 0x99 #define AML_TO_STRING_OP 0x9c #define AML_COPY_OBJECT_OP 0x9d #define AML_MID_OP 0x9e #define AML_CONTINUE_OP 0x9f #define AML_IF_OP 0xa0 #define AML_ELSE_OP 0xa1 #define AML_WHILE_OP 0xa2 #define AML_NOOP_OP 0xa3 #define AML_RETURN_OP 0xa4 #define AML_BREAK_OP 0xa5 #define AML_BREAK_POINT_OP 0xcc #define AML_ONES_OP 0xff // // Extended OpCode // #define AML_EXT_OP 0x5b #define AML_EXT_MUTEX_OP 0x01 #define AML_EXT_EVENT_OP 0x02 #define AML_EXT_COND_REF_OF_OP 0x12 #define AML_EXT_CREATE_FIELD_OP 0x13 #define AML_EXT_LOAD_TABLE_OP 0x1f #define AML_EXT_LOAD_OP 0x20 #define AML_EXT_STALL_OP 0x21 #define AML_EXT_SLEEP_OP 0x22 #define AML_EXT_ACQUIRE_OP 0x23 #define AML_EXT_SIGNAL_OP 0x24 #define AML_EXT_WAIT_OP 0x25 #define AML_EXT_RESET_OP 0x26 #define AML_EXT_RELEASE_OP 0x27 #define AML_EXT_FROM_BCD_OP 0x28 #define AML_EXT_TO_BCD_OP 0x29 #define AML_EXT_UNLOAD_OP 0x2a #define AML_EXT_REVISION_OP 0x30 #define AML_EXT_DEBUG_OP 0x31 #define AML_EXT_FATAL_OP 0x32 #define AML_EXT_TIMER_OP 0x33 #define AML_EXT_REGION_OP 0x80 #define AML_EXT_FIELD_OP 0x81 #define AML_EXT_DEVICE_OP 0x82 #define AML_EXT_PROCESSOR_OP 0x83 #define AML_EXT_POWER_RES_OP 0x84 #define AML_EXT_THERMAL_ZONE_OP 0x85 #define AML_EXT_INDEX_FIELD_OP 0x86 #define AML_EXT_BANK_FIELD_OP 0x87 #define AML_EXT_DATA_REGION_OP 0x88 // // FieldElement OpCode // #define AML_FIELD_RESERVED_OP 0x00 #define AML_FIELD_ACCESS_OP 0x01 #define AML_FIELD_CONNECTION_OP 0x02 #define AML_FIELD_EXT_ACCESS_OP 0x03 // // AML Name segment definitions // #define AML_NAME_SEG_SIZE 4 #endif ================================================ FILE: src/edk2/Coreboot.h ================================================ /** @file Coreboot PEI module include file. Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ /* * This file is part of the libpayload project. * * Copyright (C) 2008 Advanced Micro Devices, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _COREBOOT_PEI_H_INCLUDED_ #define _COREBOOT_PEI_H_INCLUDED_ #include #if defined (_MSC_VER) #pragma warning( disable : 4200 ) #endif #define DYN_CBMEM_ALIGN_SIZE (4096) #define IMD_ENTRY_MAGIC (~0xC0389481) #define CBMEM_ENTRY_MAGIC (~0xC0389479) struct cbmem_entry { UINT32 magic; UINT32 start; UINT32 size; UINT32 id; }; struct cbmem_root { UINT32 max_entries; UINT32 num_entries; UINT32 locked; UINT32 size; struct cbmem_entry entries[0]; }; struct imd_entry { UINT32 magic; UINT32 start_offset; UINT32 size; UINT32 id; }; struct imd_root { UINT32 max_entries; UINT32 num_entries; UINT32 flags; UINT32 entry_align; UINT32 max_offset; struct imd_entry entries[0]; }; struct cbuint64 { UINT32 lo; UINT32 hi; }; #define CB_HEADER_SIGNATURE 0x4F49424C struct cb_header { UINT32 signature; UINT32 header_bytes; UINT32 header_checksum; UINT32 table_bytes; UINT32 table_checksum; UINT32 table_entries; }; struct cb_record { UINT32 tag; UINT32 size; }; #define CB_TAG_UNUSED 0x0000 #define CB_TAG_MEMORY 0x0001 struct cb_memory_range { struct cbuint64 start; struct cbuint64 size; UINT32 type; }; #define CB_MEM_RAM 1 #define CB_MEM_RESERVED 2 #define CB_MEM_ACPI 3 #define CB_MEM_NVS 4 #define CB_MEM_UNUSABLE 5 #define CB_MEM_VENDOR_RSVD 6 #define CB_MEM_TABLE 16 struct cb_memory { UINT32 tag; UINT32 size; struct cb_memory_range map[0]; }; #define CB_TAG_MAINBOARD 0x0003 struct cb_mainboard { UINT32 tag; UINT32 size; UINT8 vendor_idx; UINT8 part_number_idx; UINT8 strings[0]; }; #define CB_TAG_VERSION 0x0004 #define CB_TAG_EXTRA_VERSION 0x0005 #define CB_TAG_BUILD 0x0006 #define CB_TAG_COMPILE_TIME 0x0007 #define CB_TAG_COMPILE_BY 0x0008 #define CB_TAG_COMPILE_HOST 0x0009 #define CB_TAG_COMPILE_DOMAIN 0x000a #define CB_TAG_COMPILER 0x000b #define CB_TAG_LINKER 0x000c #define CB_TAG_ASSEMBLER 0x000d struct cb_string { UINT32 tag; UINT32 size; UINT8 string[0]; }; #define CB_TAG_SERIAL 0x000f struct cb_serial { UINT32 tag; UINT32 size; #define CB_SERIAL_TYPE_IO_MAPPED 1 #define CB_SERIAL_TYPE_MEMORY_MAPPED 2 UINT32 type; UINT32 baseaddr; UINT32 baud; UINT32 regwidth; // Crystal or input frequency to the chip containing the UART. // Provide the board specific details to allow the payload to // initialize the chip containing the UART and make independent // decisions as to which dividers to select and their values // to eventually arrive at the desired console baud-rate. UINT32 input_hertz; // UART PCI address: bus, device, function // 1 << 31 - Valid bit, PCI UART in use // Bus << 20 // Device << 15 // Function << 12 UINT32 uart_pci_addr; }; #define CB_TAG_CONSOLE 0x00010 struct cb_console { UINT32 tag; UINT32 size; UINT16 type; }; #define CB_TAG_CONSOLE_SERIAL8250 0 #define CB_TAG_CONSOLE_VGA 1 // OBSOLETE #define CB_TAG_CONSOLE_BTEXT 2 // OBSOLETE #define CB_TAG_CONSOLE_LOGBUF 3 #define CB_TAG_CONSOLE_SROM 4// OBSOLETE #define CB_TAG_CONSOLE_EHCI 5 #define CB_TAG_FORWARD 0x00011 struct cb_forward { UINT32 tag; UINT32 size; UINT64 forward; }; struct cb_cbmem_ref { UINT32 tag; // Field contains size of this struct == 0x0010 UINT32 size; UINT64 cbmem_addr; }; #define CB_TAG_FRAMEBUFFER 0x0012 struct cb_framebuffer { UINT32 tag; UINT32 size; UINT64 physical_address; UINT32 x_resolution; UINT32 y_resolution; UINT32 bytes_per_line; UINT8 bits_per_pixel; UINT8 red_mask_pos; UINT8 red_mask_size; UINT8 green_mask_pos; UINT8 green_mask_size; UINT8 blue_mask_pos; UINT8 blue_mask_size; UINT8 reserved_mask_pos; UINT8 reserved_mask_size; }; #define CB_TAG_VDAT 0x0015 struct cb_vdat { UINT32 tag; UINT32 size; /* size of the entire entry */ UINT64 vdat_addr; UINT32 vdat_size; }; #define CB_TAG_TIMESTAMPS 0x0016 #define CB_TAG_CBMEM_CONSOLE 0x0017 struct cbmem_console { UINT32 size; UINT32 cursor; UINT8 body[0]; } __attribute__ ((packed)); #define CB_TAG_MRC_CACHE 0x0018 struct cb_cbmem_tab { UINT32 tag; UINT32 size; UINT64 cbmem_tab; }; #define CB_TAG_SMMSTOREV2 0x0039 struct cb_smmstorev2 { UINT32 tag; UINT32 size; UINT32 num_blocks; /* Number of writeable blocks in Smm */ UINT32 block_size; /* Size of a block in byte. Default: 64 KiB */ UINT32 mmap_addr; /* MMIO address of the store for read only access */ UINT32 com_buffer; /* Physical address of the communication buffer */ UINT32 com_buffer_size; /* Size of the communication buffer in byte */ UINT8 apm_cmd; /* The command byte to write to the APM I/O port */ UINT8 unused[3]; /* Set to zero */ UINT64 mmap_addr_ext; /* 64-bit MMIO address of the store for read only access. * Only available when size field >= 40. */ } __attribute__ ((packed)); #define CB_TAG_CFR_ROOT 0x0047 struct cb_cfr { UINT32 tag; UINT32 size; UINT32 version; UINT32 checksum; /* Of the following data only; excludes these 3 fields */ /* CFR_FORM forms[] */ }; /* Helpful macros */ #define MEM_RANGE_COUNT(_rec) \ (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0])) #define MEM_RANGE_PTR(_rec, _idx) \ (void *)(((UINT8 *) (_rec)) + sizeof(*(_rec)) \ + (sizeof((_rec)->map[0]) * (_idx))) typedef struct cb_memory CB_MEMORY; #define CB_TAG_TPM_PPI_HANDOFF 0x003a enum lb_tmp_ppi_tpm_version { LB_TPM_VERSION_UNSPEC = 0, LB_TPM_VERSION_TPM_VERSION_1_2, LB_TPM_VERSION_TPM_VERSION_2, }; /* * Handoff buffer for TPM Physical Presence Interface. * * ppi_address Pointer to PPI buffer shared with ACPI * The layout of the buffer matches the QEMU virtual memory device * that is generated by QEMU. * See files 'hw/i386/acpi-build.c' and 'include/hw/acpi/tpm.h' * for details. * * tpm_version TPM version: 1 for TPM1.2, 2 for TPM2.0 * * ppi_version BCD encoded version of TPM PPI interface */ struct cb_tpm_physical_presence { UINT32 tag; UINT32 size; UINT32 ppi_address; /* Address of ACPI PPI communication buffer */ UINT8 tpm_version; /* 1: TPM1.2, 2: TPM2.0 */ UINT8 ppi_version; /* BCD encoded */ } __attribute__((packed)); #endif // _COREBOOT_PEI_H_INCLUDED_ ================================================ FILE: src/edk2/E820.h ================================================ /** @file Copyright (c) 2013, Citrix Systems UK Ltd. Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __E820_H__ #define __E820_H__ #include #pragma pack(1) typedef enum { EfiAcpiAddressRangeMemory = 1, EfiAcpiAddressRangeReserved = 2, EfiAcpiAddressRangeACPI = 3, EfiAcpiAddressRangeNVS = 4 } EFI_ACPI_MEMORY_TYPE; typedef struct { UINT64 BaseAddr; UINT64 Length; EFI_ACPI_MEMORY_TYPE Type; } EFI_E820_ENTRY64; typedef struct { UINT32 BassAddrLow; UINT32 BaseAddrHigh; UINT32 LengthLow; UINT32 LengthHigh; EFI_ACPI_MEMORY_TYPE Type; } EFI_E820_ENTRY; #pragma pack() #endif /* __E820_H__ */ ================================================ FILE: src/edk2/Edk2Compat.h ================================================ #ifndef _EDK2_COMPAT_H_ #define _EDK2_COMPAT_H_ #include /* Packed is already handled by pragmas */ #define PACKED #define GUID EFI_GUID #define SIGNATURE_16(A,B) EFI_SIGNATURE_16(A,B) #define SIGNATURE_32(A,B,C,D) EFI_SIGNATURE_32(A,B,C,D) #define SIGNATURE_64(A,B,C,D,E,F,G,H) EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) /* Debug Macros */ // // Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint() // #define DEBUG_INIT 0x00000001 // Initialization #define DEBUG_WARN 0x00000002 // Warnings #define DEBUG_LOAD 0x00000004 // Load events #define DEBUG_FS 0x00000008 // EFI File system #define DEBUG_POOL 0x00000010 // Alloc & Free (pool) #define DEBUG_PAGE 0x00000020 // Alloc & Free (page) #define DEBUG_INFO 0x00000040 // Informational debug messages #define DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers #define DEBUG_VARIABLE 0x00000100 // Variable #define DEBUG_BM 0x00000400 // Boot Manager #define DEBUG_BLKIO 0x00001000 // BlkIo Driver #define DEBUG_NET 0x00004000 // Network Io Driver #define DEBUG_UNDI 0x00010000 // UNDI Driver #define DEBUG_LOADFILE 0x00020000 // LoadFile #define DEBUG_EVENT 0x00080000 // Event messages #define DEBUG_GCD 0x00100000 // Global Coherency Database changes #define DEBUG_CACHE 0x00200000 // Memory range cachability changes #define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may // significantly impact boot performance #define DEBUG_MANAGEABILITY 0x00800000 // Detailed debug and payload manageability messages // related to modules such as Redfish, IPMI, MCTP etc. #define DEBUG_ERROR 0x80000000 // Error messages #ifndef DEBUG_PRINT_LEVEL #define DEBUG_PRINT_LEVEL (DEBUG_ERROR) #endif #define _DEBUG_PRINT(PrintLevel, ...) \ do { \ if (PrintLevel & DEBUG_PRINT_LEVEL) { \ printf (#__VA_ARGS__); \ } \ } while (FALSE) #define _DEBUGLIB_DEBUG(Expression) _DEBUG_PRINT Expression #define DEBUG(Expression) \ do { \ if (TRUE) { \ _DEBUGLIB_DEBUG (Expression); \ } \ } while (FALSE) #endif /* _EDK2_COMPAT_H_ */ ================================================ FILE: src/edk2/LegacyBios.h ================================================ /** @file The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage under EFI and Legacy OS boot. This file also includes all the related COMPATIBILITY16 structures and definitions. Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow well known naming conventions. Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode environment. Reverse thunk is the code that does the opposite. 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.98. **/ #ifndef _EFI_LEGACY_BIOS_H_ #define _EFI_LEGACY_BIOS_H_ #include /// /// /// #pragma pack(1) typedef UINT8 SERIAL_MODE; typedef UINT8 PARALLEL_MODE; #define EFI_COMPATIBILITY16_TABLE_SIGNATURE EFI_SIGNATURE_32 ('I', 'F', 'E', '$') /// /// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx /// physical address range. It is located on a 16-byte boundary and provides the physical address of the /// entry point for the Compatibility16 functions. These functions provide the platform-specific /// information that is required by the generic EfiCompatibility code. The functions are invoked via /// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical /// entry point. /// typedef struct { /// /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32. /// UINT32 Signature; /// /// The value required such that byte checksum of TableLength equals zero. /// UINT8 TableChecksum; /// /// The length of this table. /// UINT8 TableLength; /// /// The major EFI revision for which this table was generated. /// UINT8 EfiMajorRevision; /// /// The minor EFI revision for which this table was generated. /// UINT8 EfiMinorRevision; /// /// The major revision of this table. /// UINT8 TableMajorRevision; /// /// The minor revision of this table. /// UINT8 TableMinorRevision; /// /// Reserved for future usage. /// UINT16 Reserved; /// /// The segment of the entry point within the traditional BIOS for Compatibility16 functions. /// UINT16 Compatibility16CallSegment; /// /// The offset of the entry point within the traditional BIOS for Compatibility16 functions. /// UINT16 Compatibility16CallOffset; /// /// The segment of the entry point within the traditional BIOS for EfiCompatibility /// to invoke the PnP installation check. /// UINT16 PnPInstallationCheckSegment; /// /// The Offset of the entry point within the traditional BIOS for EfiCompatibility /// to invoke the PnP installation check. /// UINT16 PnPInstallationCheckOffset; /// /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS). /// UINT32 EfiSystemTable; /// /// The address of an OEM-provided identifier string. The string is null terminated. /// UINT32 OemIdStringPointer; /// /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI /// RSD PTR with either the ACPI 1.0b or 2.0 values. /// UINT32 AcpiRsdPtrPointer; /// /// The OEM revision number. Usage is undefined but provided for OEM module usage. /// UINT16 OemRevision; /// /// The 32-bit physical address where INT15 E820 data is stored within the traditional /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the /// data to the indicated area. /// UINT32 E820Pointer; /// /// The length of the E820 data and is filled in by the EfiCompatibility code. /// UINT32 E820Length; /// /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS. /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and /// copy the data to the indicated area. /// UINT32 IrqRoutingTablePointer; /// /// The length of the $PIR table and is filled in by the EfiCompatibility code. /// UINT32 IrqRoutingTableLength; /// /// The 32-bit physical address where the MP table is stored in the traditional BIOS. /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data /// to the indicated area. /// UINT32 MpTablePtr; /// /// The length of the MP table and is filled in by the EfiCompatibility code. /// UINT32 MpTableLength; /// /// The segment of the OEM-specific INT table/code. /// UINT16 OemIntSegment; /// /// The offset of the OEM-specific INT table/code. /// UINT16 OemIntOffset; /// /// The segment of the OEM-specific 32-bit table/code. /// UINT16 Oem32Segment; /// /// The offset of the OEM-specific 32-bit table/code. /// UINT16 Oem32Offset; /// /// The segment of the OEM-specific 16-bit table/code. /// UINT16 Oem16Segment; /// /// The offset of the OEM-specific 16-bit table/code. /// UINT16 Oem16Offset; /// /// The segment of the TPM binary passed to 16-bit CSM. /// UINT16 TpmSegment; /// /// The offset of the TPM binary passed to 16-bit CSM. /// UINT16 TpmOffset; /// /// A pointer to a string identifying the independent BIOS vendor. /// UINT32 IbvPointer; /// /// This field is NULL for all systems not supporting PCI Express. This field is the base /// value of the start of the PCI Express memory-mapped configuration registers and /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function /// Compatibility16InitializeYourself(). /// Compatibility16InitializeYourself() is defined in Compatibility16 /// Functions. /// UINT32 PciExpressBase; /// /// Maximum PCI bus number assigned. /// UINT8 LastPciBus; /// /// Start Address of Upper Memory Area (UMA) to be set as Read/Write. If /// UmaAddress is a valid address in the shadow RAM, it also indicates that the region /// from 0xC0000 to (UmaAddress - 1) can be used for Option ROM. /// UINT32 UmaAddress; /// /// Upper Memory Area size in bytes to be set as Read/Write. If zero, no UMA region /// will be set as Read/Write (i.e. all Shadow RAM is set as Read-Only). /// UINT32 UmaSize; /// /// Start Address of high memory that can be used for permanent allocation. If zero, /// high memory is not available for permanent allocation. /// UINT32 HiPermanentMemoryAddress; /// /// Size of high memory that can be used for permanent allocation in bytes. If zero, /// high memory is not available for permanent allocation. /// UINT32 HiPermanentMemorySize; /// /// CSMWrap extension. 32-bit physical address of a u8 array of extra /// PCI root bus numbers (i.e., roots other than bus 0). Zero if the /// loader does not provide a list. /// UINT32 ExtraPciRootListPointer; /// /// CSMWrap extension. Number of entries in the array pointed to by /// ExtraPciRootListPointer. /// UINT8 ExtraPciRootListCount; } EFI_COMPATIBILITY16_TABLE; /// /// Functions provided by the CSM binary which communicate between the EfiCompatibility /// and Compatibility16 code. /// /// Inconsistent with the specification here: /// The member's name started with "Compatibility16" [defined in Intel Framework /// Compatibility Support Module Specification / 0.97 version] /// has been changed to "Legacy16" since keeping backward compatible. /// typedef enum { /// /// Causes the Compatibility16 code to do any internal initialization required. /// Input: /// AX = Compatibility16InitializeYourself /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE /// Return: /// AX = Return Status codes /// Legacy16InitializeYourself = 0x0000, /// /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence. /// Input: /// AX = Compatibility16UpdateBbs /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE /// Return: /// AX = Returned status codes /// Legacy16UpdateBbs = 0x0001, /// /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16 /// code is read/write. /// Input: /// AX = Compatibility16PrepareToBoot /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure /// Return: /// AX = Returned status codes /// Legacy16PrepareToBoot = 0x0002, /// /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only. /// Input: /// AX = Compatibility16Boot /// Output: /// AX = Returned status codes /// Legacy16Boot = 0x0003, /// /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is /// stored in CMOS and is the priority number of the last attempted boot device. /// Input: /// AX = Compatibility16RetrieveLastBootDevice /// Output: /// AX = Returned status codes /// BX = Priority number of the boot device. /// Legacy16RetrieveLastBootDevice = 0x0004, /// /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM. /// Input: /// AX = Compatibility16DispatchOprom /// ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE /// Output: /// AX = Returned status codes /// BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant. /// Legacy16DispatchOprom = 0x0005, /// /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address /// of that region. /// Input: /// AX = Compatibility16GetTableAddress /// BX = Allocation region /// 00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks. /// Bit 0 = 1 Allocate from 0xF0000 64 KB block /// Bit 1 = 1 Allocate from 0xE0000 64 KB block /// CX = Requested length in bytes. /// DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment. /// Output: /// AX = Returned status codes /// DS:BX = Address of the region /// Legacy16GetTableAddress = 0x0006, /// /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state. /// Input: /// AX = Compatibility16SetKeyboardLeds /// CL = LED status. /// Bit 0 Scroll Lock 0 = Off /// Bit 1 NumLock /// Bit 2 Caps Lock /// Output: /// AX = Returned status codes /// Legacy16SetKeyboardLeds = 0x0007, /// /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that /// do not have an OpROM associated with them. An example is SATA. /// Input: /// AX = Compatibility16InstallPciHandler /// ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure /// Output: /// AX = Returned status codes /// Legacy16InstallPciHandler = 0x0008 } EFI_COMPATIBILITY_FUNCTIONS; /// /// EFI_DISPATCH_OPROM_TABLE /// typedef struct { UINT16 PnPInstallationCheckSegment; ///< A pointer to the PnpInstallationCheck data structure. UINT16 PnPInstallationCheckOffset; ///< A pointer to the PnpInstallationCheck data structure. UINT16 OpromSegment; ///< The segment where the OpROM was placed. Offset is assumed to be 3. UINT8 PciBus; ///< The PCI bus. UINT8 PciDeviceFunction; ///< The PCI device * 0x08 | PCI function. UINT8 NumberBbsEntries; ///< The number of valid BBS table entries upon entry and exit. The IBV code may ///< increase this number, if BBS-compliant devices also hook INTs in order to force the ///< OpROM BIOS Setup to be executed. UINT32 BbsTablePointer; ///< A pointer to the BBS table. UINT16 RuntimeSegment; ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this ///< means that the relocation of this run time code is not supported. ///< Inconsistent with specification here: ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] ///< has been changed to "RuntimeSegment" since keeping backward compatible. } EFI_DISPATCH_OPROM_TABLE; /// /// EFI_TO_COMPATIBILITY16_INIT_TABLE /// typedef struct { /// /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF. /// UINT32 BiosLessThan1MB; /// /// The starting address of the high memory block. /// UINT32 HiPmmMemory; /// /// The length of high memory block. /// UINT32 HiPmmMemorySizeInBytes; /// /// The segment of the reverse thunk call code. /// UINT16 ReverseThunkCallSegment; /// /// The offset of the reverse thunk call code. /// UINT16 ReverseThunkCallOffset; /// /// The number of E820 entries copied to the Compatibility16 BIOS. /// UINT32 NumberE820Entries; /// /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory. /// UINT32 OsMemoryAbove1Mb; /// /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM. /// UINT32 ThunkStart; /// /// The size of the thunk code. /// UINT32 ThunkSizeInBytes; /// /// Starting address of memory under 1 MB. /// UINT32 LowPmmMemory; /// /// The length of low Memory block. /// UINT32 LowPmmMemorySizeInBytes; } EFI_TO_COMPATIBILITY16_INIT_TABLE; /// /// DEVICE_PRODUCER_SERIAL. /// typedef struct { UINT16 Address; ///< I/O address assigned to the serial port. UINT8 Irq; ///< IRQ assigned to the serial port. SERIAL_MODE Mode; ///< Mode of serial port. Values are defined below. } DEVICE_PRODUCER_SERIAL; /// /// DEVICE_PRODUCER_SERIAL's modes. ///@{ #define DEVICE_SERIAL_MODE_NORMAL 0x00 #define DEVICE_SERIAL_MODE_IRDA 0x01 #define DEVICE_SERIAL_MODE_ASK_IR 0x02 #define DEVICE_SERIAL_MODE_DUPLEX_HALF 0x00 #define DEVICE_SERIAL_MODE_DUPLEX_FULL 0x10 ///@) /// /// DEVICE_PRODUCER_PARALLEL. /// typedef struct { UINT16 Address; ///< I/O address assigned to the parallel port. UINT8 Irq; ///< IRQ assigned to the parallel port. UINT8 Dma; ///< DMA assigned to the parallel port. PARALLEL_MODE Mode; ///< Mode of the parallel port. Values are defined below. } DEVICE_PRODUCER_PARALLEL; /// /// DEVICE_PRODUCER_PARALLEL's modes. ///@{ #define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY 0x00 #define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01 #define DEVICE_PARALLEL_MODE_MODE_EPP 0x02 #define DEVICE_PARALLEL_MODE_MODE_ECP 0x03 ///@} /// /// DEVICE_PRODUCER_FLOPPY /// typedef struct { UINT16 Address; ///< I/O address assigned to the floppy. UINT8 Irq; ///< IRQ assigned to the floppy. UINT8 Dma; ///< DMA assigned to the floppy. UINT8 NumberOfFloppy; ///< Number of floppies in the system. } DEVICE_PRODUCER_FLOPPY; /// /// LEGACY_DEVICE_FLAGS /// typedef struct { UINT32 A20Kybd : 1; ///< A20 controller by keyboard controller. UINT32 A20Port90 : 1; ///< A20 controlled by port 0x92. UINT32 Reserved : 30; ///< Reserved for future usage. } LEGACY_DEVICE_FLAGS; /// /// DEVICE_PRODUCER_DATA_HEADER /// typedef struct { DEVICE_PRODUCER_SERIAL Serial[4]; ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below. DEVICE_PRODUCER_PARALLEL Parallel[3]; ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below. DEVICE_PRODUCER_FLOPPY Floppy; ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below. UINT8 MousePresent; ///< Flag to indicate if mouse is present. LEGACY_DEVICE_FLAGS Flags; ///< Miscellaneous Boolean state information passed to CSM. } DEVICE_PRODUCER_DATA_HEADER; /// /// ATAPI_IDENTIFY /// typedef struct { UINT16 Raw[256]; ///< Raw data from the IDE IdentifyDrive command. } ATAPI_IDENTIFY; /// /// HDD_INFO /// typedef struct { /// /// Status of IDE device. Values are defined below. There is one HDD_INFO structure /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index /// 1 is slave. /// UINT16 Status; /// /// PCI bus of IDE controller. /// UINT32 Bus; /// /// PCI device of IDE controller. /// UINT32 Device; /// /// PCI function of IDE controller. /// UINT32 Function; /// /// Command ports base address. /// UINT16 CommandBaseAddress; /// /// Control ports base address. /// UINT16 ControlBaseAddress; /// /// Bus master address. /// UINT16 BusMasterAddress; UINT8 HddIrq; /// /// Data that identifies the drive data; one per possible attached drive. /// ATAPI_IDENTIFY IdentifyDrive[2]; } HDD_INFO; /// /// HDD_INFO status bits /// #define HDD_PRIMARY 0x01 #define HDD_SECONDARY 0x02 #define HDD_MASTER_ATAPI_CDROM 0x04 #define HDD_SLAVE_ATAPI_CDROM 0x08 #define HDD_MASTER_IDE 0x20 #define HDD_SLAVE_IDE 0x40 #define HDD_MASTER_ATAPI_ZIPDISK 0x10 #define HDD_SLAVE_ATAPI_ZIPDISK 0x80 /// /// BBS_STATUS_FLAGS;\. /// typedef struct { UINT16 OldPosition : 4; ///< Prior priority. UINT16 Reserved1 : 4; ///< Reserved for future use. UINT16 Enabled : 1; ///< If 0, ignore this entry. UINT16 Failed : 1; ///< 0 = Not known if boot failure occurred. ///< 1 = Boot attempted failed. /// /// State of media present. /// 00 = No bootable media is present in the device. /// 01 = Unknown if a bootable media present. /// 10 = Media is present and appears bootable. /// 11 = Reserved. /// UINT16 MediaPresent : 2; UINT16 Reserved2 : 4; ///< Reserved for future use. } BBS_STATUS_FLAGS; /// /// BBS_TABLE, device type values & boot priority values. /// typedef struct { /// /// The boot priority for this boot device. Values are defined below. /// UINT16 BootPriority; /// /// The PCI bus for this boot device. /// UINT32 Bus; /// /// The PCI device for this boot device. /// UINT32 Device; /// /// The PCI function for the boot device. /// UINT32 Function; /// /// The PCI class for this boot device. /// UINT8 Class; /// /// The PCI Subclass for this boot device. /// UINT8 SubClass; /// /// Segment:offset address of an ASCIIZ description string describing the manufacturer. /// UINT16 MfgStringOffset; /// /// Segment:offset address of an ASCIIZ description string describing the manufacturer. /// UINT16 MfgStringSegment; /// /// BBS device type. BBS device types are defined below. /// UINT16 DeviceType; /// /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below. /// BBS_STATUS_FLAGS StatusFlags; /// /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for /// BCV devices. /// UINT16 BootHandlerOffset; /// /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for /// BCV devices. /// UINT16 BootHandlerSegment; /// /// Segment:offset address of an ASCIIZ description string describing this device. /// UINT16 DescStringOffset; /// /// Segment:offset address of an ASCIIZ description string describing this device. /// UINT16 DescStringSegment; /// /// Reserved. /// UINT32 InitPerReserved; /// /// The use of these fields is IBV dependent. They can be used to flag that an OpROM /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup /// UINT32 AdditionalIrq13Handler; /// /// The use of these fields is IBV dependent. They can be used to flag that an OpROM /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup /// UINT32 AdditionalIrq18Handler; /// /// The use of these fields is IBV dependent. They can be used to flag that an OpROM /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup /// UINT32 AdditionalIrq19Handler; /// /// The use of these fields is IBV dependent. They can be used to flag that an OpROM /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup /// UINT32 AdditionalIrq40Handler; UINT8 AssignedDriveNumber; UINT32 AdditionalIrq41Handler; UINT32 AdditionalIrq46Handler; UINT32 IBV1; UINT32 IBV2; } BBS_TABLE; /// /// BBS device type values ///@{ #define BBS_FLOPPY 0x01 #define BBS_HARDDISK 0x02 #define BBS_CDROM 0x03 #define BBS_PCMCIA 0x04 #define BBS_USB 0x05 #define BBS_EMBED_NETWORK 0x06 #define BBS_BEV_DEVICE 0x80 #define BBS_UNKNOWN 0xff ///@} /// /// BBS boot priority values ///@{ #define BBS_DO_NOT_BOOT_FROM 0xFFFC #define BBS_LOWEST_PRIORITY 0xFFFD #define BBS_UNPRIORITIZED_ENTRY 0xFFFE #define BBS_IGNORE_ENTRY 0xFFFF ///@} /// /// SMM_ATTRIBUTES /// typedef struct { /// /// Access mechanism used to generate the soft SMI. Defined types are below. The other /// values are reserved for future usage. /// UINT16 Type : 3; /// /// The size of "port" in bits. Defined values are below. /// UINT16 PortGranularity : 3; /// /// The size of data in bits. Defined values are below. /// UINT16 DataGranularity : 3; /// /// Reserved for future use. /// UINT16 Reserved : 7; } SMM_ATTRIBUTES; /// /// SMM_ATTRIBUTES type values. ///@{ #define STANDARD_IO 0x00 #define STANDARD_MEMORY 0x01 ///@} /// /// SMM_ATTRIBUTES port size constants. ///@{ #define PORT_SIZE_8 0x00 #define PORT_SIZE_16 0x01 #define PORT_SIZE_32 0x02 #define PORT_SIZE_64 0x03 ///@} /// /// SMM_ATTRIBUTES data size constants. ///@{ #define DATA_SIZE_8 0x00 #define DATA_SIZE_16 0x01 #define DATA_SIZE_32 0x02 #define DATA_SIZE_64 0x03 ///@} /// /// SMM_FUNCTION & relating constants. /// typedef struct { UINT16 Function : 15; UINT16 Owner : 1; } SMM_FUNCTION; /// /// SMM_FUNCTION Function constants. ///@{ #define INT15_D042 0x0000 #define GET_USB_BOOT_INFO 0x0001 #define DMI_PNP_50_57 0x0002 ///@} /// /// SMM_FUNCTION Owner constants. ///@{ #define STANDARD_OWNER 0x0 #define OEM_OWNER 0x1 ///@} /// /// This structure assumes both port and data sizes are 1. SmmAttribute must be /// properly to reflect that assumption. /// typedef struct { /// /// Describes the access mechanism, SmmPort, and SmmData sizes. Type /// SMM_ATTRIBUTES is defined below. /// SMM_ATTRIBUTES SmmAttributes; /// /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below. /// SMM_FUNCTION SmmFunction; /// /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. /// UINT8 SmmPort; /// /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. /// UINT8 SmmData; } SMM_ENTRY; /// /// SMM_TABLE /// typedef struct { UINT16 NumSmmEntries; ///< Number of entries represented by SmmEntry. SMM_ENTRY SmmEntry; ///< One entry per function. Type SMM_ENTRY is defined below. } SMM_TABLE; /// /// UDC_ATTRIBUTES /// typedef struct { /// /// This bit set indicates that the ServiceAreaData is valid. /// UINT8 DirectoryServiceValidity : 1; /// /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if /// DirectoryServiceValidity is 0. /// UINT8 RabcaUsedFlag : 1; /// /// This bit set indicates to execute hard disk diagnostics. /// UINT8 ExecuteHddDiagnosticsFlag : 1; /// /// Reserved for future use. Set to 0. /// UINT8 Reserved : 5; } UDC_ATTRIBUTES; /// /// UD_TABLE /// typedef struct { /// /// This field contains the bit-mapped attributes of the PARTIES information. Type /// UDC_ATTRIBUTES is defined below. /// UDC_ATTRIBUTES Attributes; /// /// This field contains the zero-based device on which the selected /// ServiceDataArea is present. It is 0 for master and 1 for the slave device. /// UINT8 DeviceNumber; /// /// This field contains the zero-based index into the BbsTable for the parent device. /// This index allows the user to reference the parent device information such as PCI /// bus, device function. /// UINT8 BbsTableEntryNumberForParentDevice; /// /// This field contains the zero-based index into the BbsTable for the boot entry. /// UINT8 BbsTableEntryNumberForBoot; /// /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry. /// UINT8 BbsTableEntryNumberForHddDiag; /// /// The raw Beer data. /// UINT8 BeerData[128]; /// /// The raw data of selected service area. /// UINT8 ServiceAreaData[64]; } UD_TABLE; #define EFI_TO_LEGACY_MAJOR_VERSION 0x02 #define EFI_TO_LEGACY_MINOR_VERSION 0x00 #define MAX_IDE_CONTROLLER 8 /// /// EFI_TO_COMPATIBILITY16_BOOT_TABLE /// typedef struct { UINT16 MajorVersion; ///< The EfiCompatibility major version number. UINT16 MinorVersion; ///< The EfiCompatibility minor version number. UINT32 AcpiTable; ///< The location of the RSDT ACPI table. < 4G range. UINT32 SmbiosTable; ///< The location of the SMBIOS table in EFI memory. < 4G range. UINT32 SmbiosTableLength; // // Legacy SIO state // DEVICE_PRODUCER_DATA_HEADER SioData; ///< Standard traditional device information. UINT16 DevicePathType; ///< The default boot type. UINT16 PciIrqMask; ///< Mask of which IRQs have been assigned to PCI. UINT32 NumberE820Entries; ///< Number of E820 entries. The number can change from the ///< Compatibility16InitializeYourself() function. // // Controller & Drive Identify[2] per controller information // HDD_INFO HddInfo[MAX_IDE_CONTROLLER]; ///< Hard disk drive information, including raw Identify Drive data. UINT32 NumberBbsEntries; ///< Number of entries in the BBS table UINT32 BbsTable; ///< A pointer to the BBS table. Type BBS_TABLE is defined below. UINT32 SmmTable; ///< A pointer to the SMM table. Type SMM_TABLE is defined below. UINT32 OsMemoryAbove1Mb; ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more ///< memory may have been discovered. UINT32 UnconventionalDeviceTable; ///< Information to boot off an unconventional device like a PARTIES partition. Type ///< UD_TABLE is defined below. // // CSMWrap extension: MP table pointer (not part of original EFI CSM spec) // UINT32 MpTable; ///< The location of the MP floating pointer structure. < 4G range. } EFI_TO_COMPATIBILITY16_BOOT_TABLE; /// /// EFI_LEGACY_INSTALL_PCI_HANDLER /// typedef struct { UINT8 PciBus; ///< The PCI bus of the device. UINT8 PciDeviceFun; ///< The PCI device in bits 7:3 and function in bits 2:0. UINT8 PciSegment; ///< The PCI segment of the device. UINT8 PciClass; ///< The PCI class code of the device. UINT8 PciSubclass; ///< The PCI subclass code of the device. UINT8 PciInterface; ///< The PCI interface code of the device. // // Primary section // UINT8 PrimaryIrq; ///< The primary device IRQ. UINT8 PrimaryReserved; ///< Reserved. UINT16 PrimaryControl; ///< The primary device control I/O base. UINT16 PrimaryBase; ///< The primary device I/O base. UINT16 PrimaryBusMaster; ///< The primary device bus master I/O base. // // Secondary Section // UINT8 SecondaryIrq; ///< The secondary device IRQ. UINT8 SecondaryReserved; ///< Reserved. UINT16 SecondaryControl; ///< The secondary device control I/O base. UINT16 SecondaryBase; ///< The secondary device I/O base. UINT16 SecondaryBusMaster; ///< The secondary device bus master I/O base. } EFI_LEGACY_INSTALL_PCI_HANDLER; // // Restore default pack value // #pragma pack() #define EFI_LEGACY_BIOS_PROTOCOL_GUID \ { \ 0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \ } typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL; /// /// Flags returned by CheckPciRom(). /// #define NO_ROM 0x00 #define ROM_FOUND 0x01 #define VALID_LEGACY_ROM 0x02 #define ROM_WITH_CONFIG 0x04 ///< Not defined in the Framework CSM Specification. /// /// The following macros do not appear in the Framework CSM Specification and /// are kept for backward compatibility only. They convert 32-bit address (_Adr) /// to Segment:Offset 16-bit form. /// ///@{ #define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000) #define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff) ///@} #define CARRY_FLAG 0x01 /// /// EFI_EFLAGS_REG /// typedef struct { UINT32 CF:1; UINT32 Reserved1:1; UINT32 PF:1; UINT32 Reserved2:1; UINT32 AF:1; UINT32 Reserved3:1; UINT32 ZF:1; UINT32 SF:1; UINT32 TF:1; UINT32 IF:1; UINT32 DF:1; UINT32 OF:1; UINT32 IOPL:2; UINT32 NT:1; UINT32 Reserved4:2; UINT32 VM:1; UINT32 Reserved5:14; } EFI_EFLAGS_REG; /// /// EFI_DWORD_REGS /// typedef struct { UINT32 EAX; UINT32 EBX; UINT32 ECX; UINT32 EDX; UINT32 ESI; UINT32 EDI; EFI_EFLAGS_REG EFlags; UINT16 ES; UINT16 CS; UINT16 SS; UINT16 DS; UINT16 FS; UINT16 GS; UINT32 EBP; UINT32 ESP; } EFI_DWORD_REGS; /// /// EFI_FLAGS_REG /// typedef struct { UINT16 CF:1; UINT16 Reserved1:1; UINT16 PF:1; UINT16 Reserved2:1; UINT16 AF:1; UINT16 Reserved3:1; UINT16 ZF:1; UINT16 SF:1; UINT16 TF:1; UINT16 IF:1; UINT16 DF:1; UINT16 OF:1; UINT16 IOPL:2; UINT16 NT:1; UINT16 Reserved4:1; } EFI_FLAGS_REG; /// /// EFI_WORD_REGS /// typedef struct { UINT16 AX; UINT16 ReservedAX; UINT16 BX; UINT16 ReservedBX; UINT16 CX; UINT16 ReservedCX; UINT16 DX; UINT16 ReservedDX; UINT16 SI; UINT16 ReservedSI; UINT16 DI; UINT16 ReservedDI; EFI_FLAGS_REG Flags; UINT16 ReservedFlags; UINT16 ES; UINT16 CS; UINT16 SS; UINT16 DS; UINT16 FS; UINT16 GS; UINT16 BP; UINT16 ReservedBP; UINT16 SP; UINT16 ReservedSP; } EFI_WORD_REGS; /// /// EFI_BYTE_REGS /// typedef struct { UINT8 AL, AH; UINT16 ReservedAX; UINT8 BL, BH; UINT16 ReservedBX; UINT8 CL, CH; UINT16 ReservedCX; UINT8 DL, DH; UINT16 ReservedDX; } EFI_BYTE_REGS; /// /// EFI_IA32_REGISTER_SET /// typedef union { EFI_DWORD_REGS E; EFI_WORD_REGS X; EFI_BYTE_REGS H; } EFI_IA32_REGISTER_SET; /** Thunk to 16-bit real mode and execute a software interrupt with a vector of BiosInt. Regs will contain the 16-bit register context on entry and exit. @param[in] This The protocol instance pointer. @param[in] BiosInt The processor interrupt vector to invoke. @param[in,out] Reg Register contexted passed into (and returned) from thunk to 16-bit mode. @retval TRUE Thunk completed with no BIOS errors in the target code. See Regs for status. @retval FALSE There was a BIOS error in the target code. **/ typedef BOOLEAN (EFIAPI *EFI_LEGACY_BIOS_INT86)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UINT8 BiosInt, IN OUT EFI_IA32_REGISTER_SET *Regs ); /** Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the 16-bit register context on entry and exit. Arguments can be passed on the Stack argument @param[in] This The protocol instance pointer. @param[in] Segment The segemnt of 16-bit mode call. @param[in] Offset The offset of 16-bit mdoe call. @param[in] Reg Register contexted passed into (and returned) from thunk to 16-bit mode. @param[in] Stack The caller allocated stack used to pass arguments. @param[in] StackSize The size of Stack in bytes. @retval FALSE Thunk completed with no BIOS errors in the target code. See Regs for status. @retval TRUE There was a BIOS error in the target code. **/ typedef BOOLEAN (EFIAPI *EFI_LEGACY_BIOS_FARCALL86)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UINT16 Segment, IN UINT16 Offset, IN EFI_IA32_REGISTER_SET *Regs, IN VOID *Stack, IN UINTN StackSize ); /** Test to see if a legacy PCI ROM exists for this device. Optionally return the Legacy ROM instance for this PCI device. @param[in] This The protocol instance pointer. @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded @param[out] RomImage Return the legacy PCI ROM for this device. @param[out] RomSize The size of ROM Image. @param[out] Flags Indicates if ROM found and if PC-AT. Multiple bits can be set as follows: - 00 = No ROM. - 01 = ROM Found. - 02 = ROM is a valid legacy ROM. @retval EFI_SUCCESS The Legacy Option ROM available for this device @retval EFI_UNSUPPORTED The Legacy Option ROM is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN EFI_HANDLE PciHandle, OUT VOID **RomImage, OPTIONAL OUT UINTN *RomSize, OPTIONAL OUT UINTN *Flags ); /** Load a legacy PC-AT OPROM on the PciHandle device. Return information about how many disks were added by the OPROM and the shadow address and size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: @param[in] This The protocol instance pointer. @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded. This value is NULL if RomImage is non-NULL. This is the normal case. @param[in] RomImage A PCI PC-AT ROM image. This argument is non-NULL if there is no hardware associated with the ROM and thus no PciHandle, otherwise is must be NULL. Example is PXE base code. @param[out] Flags The type of ROM discovered. Multiple bits can be set, as follows: - 00 = No ROM. - 01 = ROM found. - 02 = ROM is a valid legacy ROM. @param[out] DiskStart The disk number of first device hooked by the ROM. If DiskStart is the same as DiskEnd no disked were hooked. @param[out] DiskEnd disk number of the last device hooked by the ROM. @param[out] RomShadowAddress Shadow address of PC-AT ROM. @param[out] RomShadowSize Size of RomShadowAddress in bytes. @retval EFI_SUCCESS Thunk completed, see Regs for status. @retval EFI_INVALID_PARAMETER PciHandle not found **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN EFI_HANDLE PciHandle, IN VOID **RomImage, OUT UINTN *Flags, OUT UINT8 *DiskStart, OPTIONAL OUT UINT8 *DiskEnd, OPTIONAL OUT VOID **RomShadowAddress, OPTIONAL OUT UINT32 *ShadowedRomSize OPTIONAL ); /** This function attempts to traditionally boot the specified BootOption. If the EFI context has been compromised, this function will not return. This procedure is not used for loading an EFI-aware OS off a traditional device. The following actions occur: - Get EFI SMBIOS data structures, convert them to a traditional format, and copy to Compatibility16. - Get a pointer to ACPI data structures and copy the Compatibility16 RSD PTR to F0000 block. - Find the traditional SMI handler from a firmware volume and register the traditional SMI handler with the EFI SMI handler. - Build onboard IDE information and pass this information to the Compatibility16 code. - Make sure all PCI Interrupt Line registers are programmed to match 8259. - Reconfigure SIO devices from EFI mode (polled) into traditional mode (interrupt driven). - Shadow all PCI ROMs. - Set up BDA and EBDA standard areas before the legacy boot. - Construct the Compatibility16 boot memory map and pass it to the Compatibility16 code. - Invoke the Compatibility16 table function Compatibility16PrepareToBoot(). This invocation causes a thunk into the Compatibility16 code, which sets all appropriate internal data structures. The boot device list is a parameter. - Invoke the Compatibility16 Table function Compatibility16Boot(). This invocation causes a thunk into the Compatibility16 code, which does an INT19. - If the Compatibility16Boot() function returns, then the boot failed in a graceful manner--meaning that the EFI code is still valid. An ungraceful boot failure causes a reset because the state of EFI code is unknown. @param[in] This The protocol instance pointer. @param[in] BootOption The EFI Device Path from BootXXXX variable. @param[in] LoadOptionSize The size of LoadOption in size. @param[in] LoadOption LThe oadOption from BootXXXX variable. @retval EFI_DEVICE_ERROR Failed to boot from any boot device and memory is uncorrupted. Note: This function normally does not returns. It will either boot the OS or reset the system if memory has been "corrupted" by loading a boot sector and passing control to it. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_BOOT)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN BBS_BBS_DEVICE_PATH *BootOption, IN UINT32 LoadOptionsSize, IN VOID *LoadOptions ); /** This function takes the Leds input parameter and sets/resets the BDA accordingly. Leds is also passed to Compatibility16 code, in case any special processing is required. This function is normally called from EFI Setup drivers that handle user-selectable keyboard options such as boot with NUM LOCK on/off. This function does not touch the keyboard or keyboard LEDs but only the BDA. @param[in] This The protocol instance pointer. @param[in] Leds The status of current Scroll, Num & Cap lock LEDS: - Bit 0 is Scroll Lock 0 = Not locked. - Bit 1 is Num Lock. - Bit 2 is Caps Lock. @retval EFI_SUCCESS The BDA was updated successfully. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UINT8 Leds ); /** Retrieve legacy BBS info and assign boot priority. @param[in] This The protocol instance pointer. @param[out] HddCount The number of HDD_INFO structures. @param[out] HddInfo Onboard IDE controller information. @param[out] BbsCount The number of BBS_TABLE structures. @param[in,out] BbsTable Points to List of BBS_TABLE. @retval EFI_SUCCESS Tables were returned. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)( IN EFI_LEGACY_BIOS_PROTOCOL *This, OUT UINT16 *HddCount, OUT HDD_INFO **HddInfo, OUT UINT16 *BbsCount, IN OUT BBS_TABLE **BbsTable ); /** Assign drive number to legacy HDD drives prior to booting an EFI aware OS so the OS can access drives without an EFI driver. @param[in] This The protocol instance pointer. @param[out] BbsCount The number of BBS_TABLE structures @param[out] BbsTable List of BBS entries @retval EFI_SUCCESS Drive numbers assigned. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)( IN EFI_LEGACY_BIOS_PROTOCOL *This, OUT UINT16 *BbsCount, OUT BBS_TABLE **BbsTable ); /** To boot from an unconventional device like parties and/or execute HDD diagnostics. @param[in] This The protocol instance pointer. @param[in] Attributes How to interpret the other input parameters. @param[in] BbsEntry The 0-based index into the BbsTable for the parent device. @param[in] BeerData A pointer to the 128 bytes of ram BEER data. @param[in] ServiceAreaData A pointer to the 64 bytes of raw Service Area data. The caller must provide a pointer to the specific Service Area and not the start all Service Areas. @retval EFI_INVALID_PARAMETER If error. Does NOT return if no error. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UDC_ATTRIBUTES Attributes, IN UINTN BbsEntry, IN VOID *BeerData, IN VOID *ServiceAreaData ); /** Shadow all legacy16 OPROMs that haven't been shadowed. Warning: Use this with caution. This routine disconnects all EFI drivers. If used externally, then the caller must re-connect EFI drivers. @param[in] This The protocol instance pointer. @retval EFI_SUCCESS OPROMs were shadowed. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)( IN EFI_LEGACY_BIOS_PROTOCOL *This ); /** Get a region from the LegacyBios for S3 usage. @param[in] This The protocol instance pointer. @param[in] LegacyMemorySize The size of required region. @param[in] Region The region to use. 00 = Either 0xE0000 or 0xF0000 block. - Bit0 = 1 0xF0000 block. - Bit1 = 1 0xE0000 block. @param[in] Alignment Address alignment. Bit mapped. The first non-zero bit from right is alignment. @param[out] LegacyMemoryAddress The Region Assigned @retval EFI_SUCCESS The Region was assigned. @retval EFI_ACCESS_DENIED The function was previously invoked. @retval Other The Region was not assigned. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UINTN LegacyMemorySize, IN UINTN Region, IN UINTN Alignment, OUT VOID **LegacyMemoryAddress ); /** Get a region from the LegacyBios for Tiano usage. Can only be invoked once. @param[in] This The protocol instance pointer. @param[in] LegacyMemorySize The size of data to copy. @param[in] LegacyMemoryAddress The Legacy Region destination address. Note: must be in region assigned by LegacyBiosGetLegacyRegion. @param[in] LegacyMemorySourceAddress The source of the data to copy. @retval EFI_SUCCESS The Region assigned. @retval EFI_ACCESS_DENIED Destination was outside an assigned region. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)( IN EFI_LEGACY_BIOS_PROTOCOL *This, IN UINTN LegacyMemorySize, IN VOID *LegacyMemoryAddress, IN VOID *LegacyMemorySourceAddress ); /// /// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot() /// member function allows the BDS to support booting a traditional OS. /// EFI thunks drivers that make EFI bindings for BIOS INT services use /// all the other member functions. /// struct _EFI_LEGACY_BIOS_PROTOCOL { /// /// Performs traditional software INT. See the Int86() function description. /// EFI_LEGACY_BIOS_INT86 Int86; /// /// Performs a far call into Compatibility16 or traditional OpROM code. /// EFI_LEGACY_BIOS_FARCALL86 FarCall86; /// /// Checks if a traditional OpROM exists for this device. /// EFI_LEGACY_BIOS_CHECK_ROM CheckPciRom; /// /// Loads a traditional OpROM in traditional OpROM address space. /// EFI_LEGACY_BIOS_INSTALL_ROM InstallPciRom; /// /// Boots a traditional OS. /// EFI_LEGACY_BIOS_BOOT LegacyBoot; /// /// Updates BDA to reflect the current EFI keyboard LED status. /// EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS UpdateKeyboardLedStatus; /// /// Allows an external agent, such as BIOS Setup, to get the BBS data. /// EFI_LEGACY_BIOS_GET_BBS_INFO GetBbsInfo; /// /// Causes all legacy OpROMs to be shadowed. /// EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS ShadowAllLegacyOproms; /// /// Performs all actions prior to boot. Used when booting an EFI-aware OS /// rather than a legacy OS. /// EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI PrepareToBootEfi; /// /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block. /// EFI_LEGACY_BIOS_GET_LEGACY_REGION GetLegacyRegion; /// /// Allows EFI to copy data to the area specified by GetLegacyRegion. /// EFI_LEGACY_BIOS_COPY_LEGACY_REGION CopyLegacyRegion; /// /// Allows the user to boot off an unconventional device such as a PARTIES partition. /// EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE BootUnconventionalDevice; }; // // Legacy BIOS needs to access memory in page 0 (0-4095), which is disabled if // NULL pointer detection feature is enabled. Following macro can be used to // enable/disable page 0 before/after accessing it. // #define ACCESS_PAGE0_CODE(statements) \ do { \ EFI_STATUS Status_; \ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc_; \ \ Desc_.Attributes = 0; \ Status_ = gDS->GetMemorySpaceDescriptor (0, &Desc_); \ ASSERT_EFI_ERROR (Status_); \ if ((Desc_.Attributes & EFI_MEMORY_RP) != 0) { \ Status_ = gDS->SetMemorySpaceAttributes ( \ 0, \ EFI_PAGES_TO_SIZE(1), \ Desc_.Attributes & ~(UINT64)EFI_MEMORY_RP \ ); \ ASSERT_EFI_ERROR (Status_); \ } \ \ { \ statements; \ } \ \ if ((Desc_.Attributes & EFI_MEMORY_RP) != 0) { \ Status_ = gDS->SetMemorySpaceAttributes ( \ 0, \ EFI_PAGES_TO_SIZE(1), \ Desc_.Attributes \ ); \ ASSERT_EFI_ERROR (Status_); \ } \ } while (FALSE) extern EFI_GUID gEfiLegacyBiosProtocolGuid; #endif ================================================ FILE: src/edk2/LegacyRegion2.h ================================================ /** @file The Legacy Region Protocol controls the read, write and boot-lock attributes for the region 0xC0000 to 0xFFFFF. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is defined in UEFI Platform Initialization Specification 1.2 Volume 5: Standards **/ #ifndef __LEGACY_REGION2_H__ #define __LEGACY_REGION2_H__ #include #define EFI_LEGACY_REGION2_PROTOCOL_GUID \ { \ 0x70101eaf, 0x85, 0x440c, {0xb3, 0x56, 0x8e, 0xe3, 0x6f, 0xef, 0x24, 0xf0 } \ } typedef struct _EFI_LEGACY_REGION2_PROTOCOL EFI_LEGACY_REGION2_PROTOCOL; /** Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region. If the On parameter evaluates to TRUE, this function enables memory reads in the address range Start to (Start + Length - 1). If the On parameter evaluates to FALSE, this function disables memory reads in the address range Start to (Start + Length - 1). @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance. @param Start[in] The beginning of the physical address of the region whose attributes should be modified. @param Length[in] The number of bytes of memory whose attributes should be modified. The actual number of bytes modified may be greater than the number specified. @param Granularity[out] The number of bytes in the last region affected. This may be less than the total number of bytes affected if the starting address was not aligned to a region's starting address or if the length was greater than the number of bytes in the first region. @param On[in] Decode / Non-Decode flag. @retval EFI_SUCCESS The region's attributes were successfully modified. @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_REGION2_DECODE)( IN EFI_LEGACY_REGION2_PROTOCOL *This, IN UINT32 Start, IN UINT32 Length, OUT UINT32 *Granularity, IN BOOLEAN *On ); /** Modify the hardware to disallow memory writes in a region. This function changes the attributes of a memory range to not allow writes. @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance. @param Start[in] The beginning of the physical address of the region whose attributes should be modified. @param Length[in] The number of bytes of memory whose attributes should be modified. The actual number of bytes modified may be greater than the number specified. @param Granularity[out] The number of bytes in the last region affected. This may be less than the total number of bytes affected if the starting address was not aligned to a region's starting address or if the length was greater than the number of bytes in the first region. @retval EFI_SUCCESS The region's attributes were successfully modified. @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_REGION2_LOCK)( IN EFI_LEGACY_REGION2_PROTOCOL *This, IN UINT32 Start, IN UINT32 Length, OUT UINT32 *Granularity ); /** Modify the hardware to disallow memory attribute changes in a region. This function makes the attributes of a region read only. Once a region is boot-locked with this function, the read and write attributes of that region cannot be changed until a power cycle has reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect. @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance. @param Start[in] The beginning of the physical address of the region whose attributes should be modified. @param Length[in] The number of bytes of memory whose attributes should be modified. The actual number of bytes modified may be greater than the number specified. @param Granularity[out] The number of bytes in the last region affected. This may be less than the total number of bytes affected if the starting address was not aligned to a region's starting address or if the length was greater than the number of bytes in the first region. @retval EFI_SUCCESS The region's attributes were successfully modified. @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region. @retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in a way that will not affect memory regions outside the legacy memory region. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_REGION2_BOOT_LOCK)( IN EFI_LEGACY_REGION2_PROTOCOL *This, IN UINT32 Start, IN UINT32 Length, OUT UINT32 *Granularity OPTIONAL ); /** Modify the hardware to allow memory writes in a region. This function changes the attributes of a memory range to allow writes. @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance. @param Start[in] The beginning of the physical address of the region whose attributes should be modified. @param Length[in] The number of bytes of memory whose attributes should be modified. The actual number of bytes modified may be greater than the number specified. @param Granularity[out] The number of bytes in the last region affected. This may be less than the total number of bytes affected if the starting address was not aligned to a region's starting address or if the length was greater than the number of bytes in the first region. @retval EFI_SUCCESS The region's attributes were successfully modified. @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_REGION2_UNLOCK)( IN EFI_LEGACY_REGION2_PROTOCOL *This, IN UINT32 Start, IN UINT32 Length, OUT UINT32 *Granularity ); typedef enum { LegacyRegionDecoded, ///< This region is currently set to allow reads. LegacyRegionNotDecoded, ///< This region is currently set to not allow reads. LegacyRegionWriteEnabled, ///< This region is currently set to allow writes. LegacyRegionWriteDisabled, ///< This region is currently set to write protected. LegacyRegionBootLocked, ///< This region's attributes are locked, cannot be modified until ///< after a power cycle. LegacyRegionNotLocked ///< This region's attributes are not locked. } EFI_LEGACY_REGION_ATTRIBUTE; typedef struct { /// /// The beginning of the physical address of this /// region. /// UINT32 Start; /// /// The number of bytes in this region. /// UINT32 Length; /// /// Attribute of the Legacy Region Descriptor that /// describes the capabilities for that memory region. /// EFI_LEGACY_REGION_ATTRIBUTE Attribute; /// /// Describes the byte length programmability /// associated with the Start address and the specified /// Attribute setting. UINT32 Granularity; } EFI_LEGACY_REGION_DESCRIPTOR; /** Get region information for the attributes of the Legacy Region. This function is used to discover the granularity of the attributes for the memory in the legacy region. Each attribute may have a different granularity and the granularity may not be the same for all memory ranges in the legacy region. @param This[in] Indicates the EFI_LEGACY_REGION2_PROTOCOL instance. @param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor buffer. @param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy region information is deposited. This buffer will contain a list of DescriptorCount number of region descriptors. This function will provide the memory for the buffer. @retval EFI_SUCCESS The information structure was returned. @retval EFI_UNSUPPORTED This function is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_REGION_GET_INFO)( IN EFI_LEGACY_REGION2_PROTOCOL *This, OUT UINT32 *DescriptorCount, OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor ); /// /// The EFI_LEGACY_REGION2_PROTOCOL is used to abstract the hardware control of the memory /// attributes of the Option ROM shadowing region, 0xC0000 to 0xFFFFF. /// There are three memory attributes that can be modified through this protocol: read, write and /// boot-lock. These protocols may be set in any combination. /// struct _EFI_LEGACY_REGION2_PROTOCOL { EFI_LEGACY_REGION2_DECODE Decode; EFI_LEGACY_REGION2_LOCK Lock; EFI_LEGACY_REGION2_BOOT_LOCK BootLock; EFI_LEGACY_REGION2_UNLOCK UnLock; EFI_LEGACY_REGION_GET_INFO GetInfo; }; #endif ================================================ FILE: src/edk2/Pci.h ================================================ /** @file Support for the latest PCI standard. Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCI_H_ #define _PCI_H_ #include "PciExpress60.h" #include "PciCodeId.h" #endif ================================================ FILE: src/edk2/Pci22.h ================================================ /** @file Support for PCI 2.2 standard. This file includes the definitions in the following specifications, PCI Local Bus Specification, 2.2 PCI-to-PCI Bridge Architecture Specification, Revision 1.2 PC Card Standard, 8.0 PCI Power Management Interface Specification, Revision 1.2 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2014 - 2015, Hewlett-Packard Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCI22_H_ #define _PCI22_H_ #include "Edk2Compat.h" #define PCI_MAX_BUS 255 #define PCI_MAX_DEVICE 31 #define PCI_MAX_FUNC 7 #pragma pack(1) /// /// Common header region in PCI Configuration Space /// Section 6.1, PCI Local Bus Specification, 2.2 /// typedef struct { UINT16 VendorId; UINT16 DeviceId; UINT16 Command; UINT16 Status; UINT8 RevisionID; UINT8 ClassCode[3]; UINT8 CacheLineSize; UINT8 LatencyTimer; UINT8 HeaderType; UINT8 BIST; } PCI_DEVICE_INDEPENDENT_REGION; /// /// PCI Device header region in PCI Configuration Space /// Section 6.1, PCI Local Bus Specification, 2.2 /// typedef struct { UINT32 Bar[6]; UINT32 CISPtr; UINT16 SubsystemVendorID; UINT16 SubsystemID; UINT32 ExpansionRomBar; UINT8 CapabilityPtr; UINT8 Reserved1[3]; UINT32 Reserved2; UINT8 InterruptLine; UINT8 InterruptPin; UINT8 MinGnt; UINT8 MaxLat; } PCI_DEVICE_HEADER_TYPE_REGION; /// /// PCI Device Configuration Space /// Section 6.1, PCI Local Bus Specification, 2.2 /// typedef struct { PCI_DEVICE_INDEPENDENT_REGION Hdr; PCI_DEVICE_HEADER_TYPE_REGION Device; } PCI_TYPE00; /// /// PCI-PCI Bridge header region in PCI Configuration Space /// Section 3.2, PCI-PCI Bridge Architecture, Version 1.2 /// typedef struct { UINT32 Bar[2]; UINT8 PrimaryBus; UINT8 SecondaryBus; UINT8 SubordinateBus; UINT8 SecondaryLatencyTimer; UINT8 IoBase; UINT8 IoLimit; UINT16 SecondaryStatus; UINT16 MemoryBase; UINT16 MemoryLimit; UINT16 PrefetchableMemoryBase; UINT16 PrefetchableMemoryLimit; UINT32 PrefetchableBaseUpper32; UINT32 PrefetchableLimitUpper32; UINT16 IoBaseUpper16; UINT16 IoLimitUpper16; UINT8 CapabilityPtr; UINT8 Reserved[3]; UINT32 ExpansionRomBAR; UINT8 InterruptLine; UINT8 InterruptPin; UINT16 BridgeControl; } PCI_BRIDGE_CONTROL_REGISTER; /// /// PCI-to-PCI Bridge Configuration Space /// Section 3.2, PCI-PCI Bridge Architecture, Version 1.2 /// typedef struct { PCI_DEVICE_INDEPENDENT_REGION Hdr; PCI_BRIDGE_CONTROL_REGISTER Bridge; } PCI_TYPE01; typedef union { PCI_TYPE00 Device; PCI_TYPE01 Bridge; } PCI_TYPE_GENERIC; /// /// CardBus Controller Configuration Space, /// Section 4.5.1, PC Card Standard. 8.0 /// typedef struct { UINT32 CardBusSocketReg; ///< Cardbus Socket/ExCA Base UINT8 Cap_Ptr; UINT8 Reserved; UINT16 SecondaryStatus; ///< Secondary Status UINT8 PciBusNumber; ///< PCI Bus Number UINT8 CardBusBusNumber; ///< CardBus Bus Number UINT8 SubordinateBusNumber; ///< Subordinate Bus Number UINT8 CardBusLatencyTimer; ///< CardBus Latency Timer UINT32 MemoryBase0; ///< Memory Base Register 0 UINT32 MemoryLimit0; ///< Memory Limit Register 0 UINT32 MemoryBase1; UINT32 MemoryLimit1; UINT32 IoBase0; UINT32 IoLimit0; ///< I/O Base Register 0 UINT32 IoBase1; ///< I/O Limit Register 0 UINT32 IoLimit1; UINT8 InterruptLine; ///< Interrupt Line UINT8 InterruptPin; ///< Interrupt Pin UINT16 BridgeControl; ///< Bridge Control } PCI_CARDBUS_CONTROL_REGISTER; // // Definitions of PCI class bytes and manipulation macros. // #define PCI_CLASS_OLD 0x00 #define PCI_CLASS_OLD_OTHER 0x00 #define PCI_CLASS_OLD_VGA 0x01 #define PCI_CLASS_MASS_STORAGE 0x01 #define PCI_CLASS_MASS_STORAGE_SCSI 0x00 #define PCI_CLASS_MASS_STORAGE_IDE 0x01 #define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02 #define PCI_CLASS_MASS_STORAGE_IPI 0x03 #define PCI_CLASS_MASS_STORAGE_RAID 0x04 #define PCI_CLASS_MASS_STORAGE_OTHER 0x80 #define PCI_CLASS_NETWORK 0x02 #define PCI_CLASS_NETWORK_ETHERNET 0x00 #define PCI_CLASS_NETWORK_TOKENRING 0x01 #define PCI_CLASS_NETWORK_FDDI 0x02 #define PCI_CLASS_NETWORK_ATM 0x03 #define PCI_CLASS_NETWORK_ISDN 0x04 #define PCI_CLASS_NETWORK_OTHER 0x80 #define PCI_CLASS_DISPLAY 0x03 #define PCI_CLASS_DISPLAY_VGA 0x00 #define PCI_IF_VGA_VGA 0x00 #define PCI_IF_VGA_8514 0x01 #define PCI_CLASS_DISPLAY_XGA 0x01 #define PCI_CLASS_DISPLAY_3D 0x02 #define PCI_CLASS_DISPLAY_OTHER 0x80 #define PCI_CLASS_MEDIA 0x04 #define PCI_CLASS_MEDIA_VIDEO 0x00 #define PCI_CLASS_MEDIA_AUDIO 0x01 #define PCI_CLASS_MEDIA_TELEPHONE 0x02 #define PCI_CLASS_MEDIA_OTHER 0x80 #define PCI_CLASS_MEMORY_CONTROLLER 0x05 #define PCI_CLASS_MEMORY_RAM 0x00 #define PCI_CLASS_MEMORY_FLASH 0x01 #define PCI_CLASS_MEMORY_OTHER 0x80 #define PCI_CLASS_BRIDGE 0x06 #define PCI_CLASS_BRIDGE_HOST 0x00 #define PCI_CLASS_BRIDGE_ISA 0x01 #define PCI_CLASS_BRIDGE_EISA 0x02 #define PCI_CLASS_BRIDGE_MCA 0x03 #define PCI_CLASS_BRIDGE_P2P 0x04 #define PCI_IF_BRIDGE_P2P 0x00 #define PCI_IF_BRIDGE_P2P_SUBTRACTIVE 0x01 #define PCI_CLASS_BRIDGE_PCMCIA 0x05 #define PCI_CLASS_BRIDGE_NUBUS 0x06 #define PCI_CLASS_BRIDGE_CARDBUS 0x07 #define PCI_CLASS_BRIDGE_RACEWAY 0x08 #define PCI_CLASS_BRIDGE_OTHER 0x80 #define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80 #define PCI_CLASS_SCC 0x07///< Simple communications controllers #define PCI_SUBCLASS_SERIAL 0x00 #define PCI_IF_GENERIC_XT 0x00 #define PCI_IF_16450 0x01 #define PCI_IF_16550 0x02 #define PCI_IF_16650 0x03 #define PCI_IF_16750 0x04 #define PCI_IF_16850 0x05 #define PCI_IF_16950 0x06 #define PCI_SUBCLASS_PARALLEL 0x01 #define PCI_IF_PARALLEL_PORT 0x00 #define PCI_IF_BI_DIR_PARALLEL_PORT 0x01 #define PCI_IF_ECP_PARALLEL_PORT 0x02 #define PCI_IF_1284_CONTROLLER 0x03 #define PCI_IF_1284_DEVICE 0xFE #define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02 #define PCI_SUBCLASS_MODEM 0x03 #define PCI_IF_GENERIC_MODEM 0x00 #define PCI_IF_16450_MODEM 0x01 #define PCI_IF_16550_MODEM 0x02 #define PCI_IF_16650_MODEM 0x03 #define PCI_IF_16750_MODEM 0x04 #define PCI_SUBCLASS_SCC_OTHER 0x80 #define PCI_CLASS_SYSTEM_PERIPHERAL 0x08 #define PCI_SUBCLASS_PIC 0x00 #define PCI_IF_8259_PIC 0x00 #define PCI_IF_ISA_PIC 0x01 #define PCI_IF_EISA_PIC 0x02 #define PCI_IF_APIC_CONTROLLER 0x10 ///< I/O APIC interrupt controller , 32 byte none-prefetchable memory. #define PCI_IF_APIC_CONTROLLER2 0x20 #define PCI_SUBCLASS_DMA 0x01 #define PCI_IF_8237_DMA 0x00 #define PCI_IF_ISA_DMA 0x01 #define PCI_IF_EISA_DMA 0x02 #define PCI_SUBCLASS_TIMER 0x02 #define PCI_IF_8254_TIMER 0x00 #define PCI_IF_ISA_TIMER 0x01 #define PCI_IF_EISA_TIMER 0x02 #define PCI_SUBCLASS_RTC 0x03 #define PCI_IF_GENERIC_RTC 0x00 #define PCI_IF_ISA_RTC 0x01 #define PCI_SUBCLASS_PNP_CONTROLLER 0x04 ///< HotPlug Controller #define PCI_SUBCLASS_PERIPHERAL_OTHER 0x80 #define PCI_CLASS_INPUT_DEVICE 0x09 #define PCI_SUBCLASS_KEYBOARD 0x00 #define PCI_SUBCLASS_PEN 0x01 #define PCI_SUBCLASS_MOUSE_CONTROLLER 0x02 #define PCI_SUBCLASS_SCAN_CONTROLLER 0x03 #define PCI_SUBCLASS_GAMEPORT 0x04 #define PCI_IF_GAMEPORT 0x00 #define PCI_IF_GAMEPORT1 0x10 #define PCI_SUBCLASS_INPUT_OTHER 0x80 #define PCI_CLASS_DOCKING_STATION 0x0A #define PCI_SUBCLASS_DOCKING_GENERIC 0x00 #define PCI_SUBCLASS_DOCKING_OTHER 0x80 #define PCI_CLASS_PROCESSOR 0x0B #define PCI_SUBCLASS_PROC_386 0x00 #define PCI_SUBCLASS_PROC_486 0x01 #define PCI_SUBCLASS_PROC_PENTIUM 0x02 #define PCI_SUBCLASS_PROC_ALPHA 0x10 #define PCI_SUBCLASS_PROC_POWERPC 0x20 #define PCI_SUBCLASS_PROC_MIPS 0x30 #define PCI_SUBCLASS_PROC_CO_PORC 0x40 ///< Co-Processor #define PCI_CLASS_SERIAL 0x0C #define PCI_CLASS_SERIAL_FIREWIRE 0x00 #define PCI_IF_1394 0x00 #define PCI_IF_1394_OPEN_HCI 0x10 #define PCI_CLASS_SERIAL_ACCESS_BUS 0x01 #define PCI_CLASS_SERIAL_SSA 0x02 #define PCI_CLASS_SERIAL_USB 0x03 #define PCI_IF_UHCI 0x00 #define PCI_IF_OHCI 0x10 #define PCI_IF_USB_OTHER 0x80 #define PCI_IF_USB_DEVICE 0xFE #define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04 #define PCI_CLASS_SERIAL_SMB 0x05 #define PCI_CLASS_WIRELESS 0x0D #define PCI_SUBCLASS_IRDA 0x00 #define PCI_SUBCLASS_IR 0x01 #define PCI_SUBCLASS_RF 0x10 #define PCI_SUBCLASS_WIRELESS_OTHER 0x80 #define PCI_CLASS_INTELLIGENT_IO 0x0E #define PCI_CLASS_SATELLITE 0x0F #define PCI_SUBCLASS_TV 0x01 #define PCI_SUBCLASS_AUDIO 0x02 #define PCI_SUBCLASS_VOICE 0x03 #define PCI_SUBCLASS_DATA 0x04 #define PCI_SECURITY_CONTROLLER 0x10 ///< Encryption and decryption controller #define PCI_SUBCLASS_NET_COMPUT 0x00 #define PCI_SUBCLASS_ENTERTAINMENT 0x10 #define PCI_SUBCLASS_SECURITY_OTHER 0x80 #define PCI_CLASS_DPIO 0x11 #define PCI_SUBCLASS_DPIO 0x00 #define PCI_SUBCLASS_DPIO_OTHER 0x80 /** Macro that checks whether the Base Class code of device matched. @param _p Specified device. @param c Base Class code needs matching. @retval TRUE Base Class code matches the specified device. @retval FALSE Base Class code doesn't match the specified device. **/ #define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c)) /** Macro that checks whether the Base Class code and Sub-Class code of device matched. @param _p Specified device. @param c Base Class code needs matching. @param s Sub-Class code needs matching. @retval TRUE Base Class code and Sub-Class code match the specified device. @retval FALSE Base Class code and Sub-Class code don't match the specified device. **/ #define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s))) /** Macro that checks whether the Base Class code, Sub-Class code and Interface code of device matched. @param _p Specified device. @param c Base Class code needs matching. @param s Sub-Class code needs matching. @param p Interface code needs matching. @retval TRUE Base Class code, Sub-Class code and Interface code match the specified device. @retval FALSE Base Class code, Sub-Class code and Interface code don't match the specified device. **/ #define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p))) /** Macro that checks whether device is a display controller. @param _p Specified device. @retval TRUE Device is a display controller. @retval FALSE Device is not a display controller. **/ #define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY) /** Macro that checks whether device is a VGA-compatible controller. @param _p Specified device. @retval TRUE Device is a VGA-compatible controller. @retval FALSE Device is not a VGA-compatible controller. **/ #define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, PCI_IF_VGA_VGA) /** Macro that checks whether device is an 8514-compatible controller. @param _p Specified device. @retval TRUE Device is an 8514-compatible controller. @retval FALSE Device is not an 8514-compatible controller. **/ #define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, PCI_IF_VGA_8514) /** Macro that checks whether device is built before the Class Code field was defined. @param _p Specified device. @retval TRUE Device is an old device. @retval FALSE Device is not an old device. **/ #define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD) /** Macro that checks whether device is a VGA-compatible device built before the Class Code field was defined. @param _p Specified device. @retval TRUE Device is an old VGA-compatible device. @retval FALSE Device is not an old VGA-compatible device. **/ #define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) /** Macro that checks whether device is an IDE controller. @param _p Specified device. @retval TRUE Device is an IDE controller. @retval FALSE Device is not an IDE controller. **/ #define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE) /** Macro that checks whether device is a SCSI bus controller. @param _p Specified device. @retval TRUE Device is a SCSI bus controller. @retval FALSE Device is not a SCSI bus controller. **/ #define IS_PCI_SCSI(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI) /** Macro that checks whether device is a RAID controller. @param _p Specified device. @retval TRUE Device is a RAID controller. @retval FALSE Device is not a RAID controller. **/ #define IS_PCI_RAID(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID) /** Macro that checks whether device is an ISA bridge. @param _p Specified device. @retval TRUE Device is an ISA bridge. @retval FALSE Device is not an ISA bridge. **/ #define IS_PCI_LPC(_p) IS_CLASS2 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA) /** Macro that checks whether device is a PCI-to-PCI bridge. @param _p Specified device. @retval TRUE Device is a PCI-to-PCI bridge. @retval FALSE Device is not a PCI-to-PCI bridge. **/ #define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, PCI_IF_BRIDGE_P2P) /** Macro that checks whether device is a Subtractive Decode PCI-to-PCI bridge. @param _p Specified device. @retval TRUE Device is a Subtractive Decode PCI-to-PCI bridge. @retval FALSE Device is not a Subtractive Decode PCI-to-PCI bridge. **/ #define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, PCI_IF_BRIDGE_P2P_SUBTRACTIVE) /** Macro that checks whether device is a 16550-compatible serial controller. @param _p Specified device. @retval TRUE Device is a 16550-compatible serial controller. @retval FALSE Device is not a 16550-compatible serial controller. **/ #define IS_PCI_16550_SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550) /** Macro that checks whether device is a Universal Serial Bus controller. @param _p Specified device. @retval TRUE Device is a Universal Serial Bus controller. @retval FALSE Device is not a Universal Serial Bus controller. **/ #define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB) // // the definition of Header Type // #define HEADER_TYPE_DEVICE 0x00 #define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 #define HEADER_TYPE_CARDBUS_BRIDGE 0x02 #define HEADER_TYPE_MULTI_FUNCTION 0x80 // // Mask of Header type // #define HEADER_LAYOUT_CODE 0x7f /** Macro that checks whether device is a PCI-PCI bridge. @param _p Specified device. @retval TRUE Device is a PCI-PCI bridge. @retval FALSE Device is not a PCI-PCI bridge. **/ #define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE)) /** Macro that checks whether device is a CardBus bridge. @param _p Specified device. @retval TRUE Device is a CardBus bridge. @retval FALSE Device is not a CardBus bridge. **/ #define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) /** Macro that checks whether device is a multiple functions device. @param _p Specified device. @retval TRUE Device is a multiple functions device. @retval FALSE Device is not a multiple functions device. **/ #define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) /// /// Rom Base Address in Bridge, defined in PCI-to-PCI Bridge Architecture Specification, /// #define PCI_BRIDGE_ROMBAR 0x38 #define PCI_MAX_BAR 0x0006 #define PCI_MAX_CONFIG_OFFSET 0x0100 #define PCI_VENDOR_ID_OFFSET 0x00 #define PCI_DEVICE_ID_OFFSET 0x02 #define PCI_COMMAND_OFFSET 0x04 #define PCI_PRIMARY_STATUS_OFFSET 0x06 #define PCI_REVISION_ID_OFFSET 0x08 #define PCI_CLASSCODE_OFFSET 0x09 #define PCI_CACHELINE_SIZE_OFFSET 0x0C #define PCI_LATENCY_TIMER_OFFSET 0x0D #define PCI_HEADER_TYPE_OFFSET 0x0E #define PCI_BIST_OFFSET 0x0F #define PCI_BASE_ADDRESSREG_OFFSET 0x10 #define PCI_CARDBUS_CIS_OFFSET 0x28 #define PCI_SVID_OFFSET 0x2C ///< SubSystem Vendor id #define PCI_SUBSYSTEM_VENDOR_ID_OFFSET 0x2C #define PCI_SID_OFFSET 0x2E ///< SubSystem ID #define PCI_SUBSYSTEM_ID_OFFSET 0x2E #define PCI_EXPANSION_ROM_BASE 0x30 #define PCI_CAPBILITY_POINTER_OFFSET 0x34 #define PCI_INT_LINE_OFFSET 0x3C ///< Interrupt Line Register #define PCI_INT_PIN_OFFSET 0x3D ///< Interrupt Pin Register #define PCI_MAXGNT_OFFSET 0x3E ///< Max Grant Register #define PCI_MAXLAT_OFFSET 0x3F ///< Max Latency Register // // defined in PCI-to-PCI Bridge Architecture Specification // #define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18 #define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19 #define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a #define PCI_BRIDGE_SECONDARY_LATENCY_TIMER_OFFSET 0x1b #define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E #define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E /// /// Interrupt Line "Unknown" or "No connection" value defined for x86 based system /// #define PCI_INT_LINE_UNKNOWN 0xFF /// /// PCI Access Data Format /// typedef union { struct { UINT32 Reg : 8; UINT32 Func : 3; UINT32 Dev : 5; UINT32 Bus : 8; UINT32 Reserved : 7; UINT32 Enable : 1; } Bits; UINT32 Uint32; } PCI_CONFIG_ACCESS_CF8; #pragma pack() #define EFI_PCI_COMMAND_IO_SPACE BIT0 ///< 0x0001 #define EFI_PCI_COMMAND_MEMORY_SPACE BIT1 ///< 0x0002 #define EFI_PCI_COMMAND_BUS_MASTER BIT2 ///< 0x0004 #define EFI_PCI_COMMAND_SPECIAL_CYCLE BIT3 ///< 0x0008 #define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE BIT4 ///< 0x0010 #define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP BIT5 ///< 0x0020 #define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND BIT6 ///< 0x0040 #define EFI_PCI_COMMAND_STEPPING_CONTROL BIT7 ///< 0x0080 #define EFI_PCI_COMMAND_SERR BIT8 ///< 0x0100 #define EFI_PCI_COMMAND_FAST_BACK_TO_BACK BIT9 ///< 0x0200 // // defined in PCI-to-PCI Bridge Architecture Specification // #define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE BIT0 ///< 0x0001 #define EFI_PCI_BRIDGE_CONTROL_SERR BIT1 ///< 0x0002 #define EFI_PCI_BRIDGE_CONTROL_ISA BIT2 ///< 0x0004 #define EFI_PCI_BRIDGE_CONTROL_VGA BIT3 ///< 0x0008 #define EFI_PCI_BRIDGE_CONTROL_VGA_16 BIT4 ///< 0x0010 #define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT BIT5 ///< 0x0020 #define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS BIT6 ///< 0x0040 #define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK BIT7 ///< 0x0080 #define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER BIT8 ///< 0x0100 #define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER BIT9 ///< 0x0200 #define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS BIT10 ///< 0x0400 #define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR BIT11 ///< 0x0800 // // Following are the PCI-CARDBUS bridge control bit, defined in PC Card Standard // #define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE BIT7 ///< 0x0080 #define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE BIT8 ///< 0x0100 #define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE BIT9 ///< 0x0200 #define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE BIT10 ///< 0x0400 // // Following are the PCI status control bit // #define EFI_PCI_STATUS_CAPABILITY BIT4 ///< 0x0010 #define EFI_PCI_STATUS_66MZ_CAPABLE BIT5 ///< 0x0020 #define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE BIT7 ///< 0x0080 #define EFI_PCI_MASTER_DATA_PARITY_ERROR BIT8 ///< 0x0100 /// /// defined in PC Card Standard /// #define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14 #pragma pack(1) // // PCI Capability List IDs and records // #define EFI_PCI_CAPABILITY_ID_PMI 0x01 #define EFI_PCI_CAPABILITY_ID_AGP 0x02 #define EFI_PCI_CAPABILITY_ID_VPD 0x03 #define EFI_PCI_CAPABILITY_ID_SLOTID 0x04 #define EFI_PCI_CAPABILITY_ID_MSI 0x05 #define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06 #define EFI_PCI_CAPABILITY_ID_SHPC 0x0C /// /// Capabilities List Header /// Section 6.7, PCI Local Bus Specification, 2.2 /// typedef struct { UINT8 CapabilityID; UINT8 NextItemPtr; } EFI_PCI_CAPABILITY_HDR; /// /// PMC - Power Management Capabilities /// Section 3.2.3, PCI Power Management Interface Specification, Revision 1.2 /// typedef union { struct { UINT16 Version : 3; UINT16 PmeClock : 1; UINT16 Reserved : 1; UINT16 DeviceSpecificInitialization : 1; UINT16 AuxCurrent : 3; UINT16 D1Support : 1; UINT16 D2Support : 1; UINT16 PmeSupport : 5; } Bits; UINT16 Data; } EFI_PCI_PMC; #define EFI_PCI_PMC_D3_COLD_MASK (BIT15) /// /// PMCSR - Power Management Control/Status /// Section 3.2.4, PCI Power Management Interface Specification, Revision 1.2 /// typedef union { struct { UINT16 PowerState : 2; UINT16 ReservedForPciExpress : 1; UINT16 NoSoftReset : 1; UINT16 Reserved : 4; UINT16 PmeEnable : 1; UINT16 DataSelect : 4; UINT16 DataScale : 2; UINT16 PmeStatus : 1; } Bits; UINT16 Data; } EFI_PCI_PMCSR; #define PCI_POWER_STATE_D0 0 #define PCI_POWER_STATE_D1 1 #define PCI_POWER_STATE_D2 2 #define PCI_POWER_STATE_D3_HOT 3 /// /// PMCSR_BSE - PMCSR PCI-to-PCI Bridge Support Extensions /// Section 3.2.5, PCI Power Management Interface Specification, Revision 1.2 /// typedef union { struct { UINT8 Reserved : 6; UINT8 B2B3 : 1; UINT8 BusPowerClockControl : 1; } Bits; UINT8 Uint8; } EFI_PCI_PMCSR_BSE; /// /// Power Management Register Block Definition /// Section 3.2, PCI Power Management Interface Specification, Revision 1.2 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; EFI_PCI_PMC PMC; EFI_PCI_PMCSR PMCSR; EFI_PCI_PMCSR_BSE BridgeExtention; UINT8 Data; } EFI_PCI_CAPABILITY_PMI; /// /// A.G.P Capability /// Section 6.1.4, Accelerated Graphics Port Interface Specification, Revision 1.0 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT8 Rev; UINT8 Reserved; UINT32 Status; UINT32 Command; } EFI_PCI_CAPABILITY_AGP; /// /// VPD Capability Structure /// Appendix I, PCI Local Bus Specification, 2.2 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT16 AddrReg; UINT32 DataReg; } EFI_PCI_CAPABILITY_VPD; /// /// Slot Numbering Capabilities Register /// Section 3.2.6, PCI-to-PCI Bridge Architecture Specification, Revision 1.2 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT8 ExpnsSlotReg; UINT8 ChassisNo; } EFI_PCI_CAPABILITY_SLOTID; /// /// Message Capability Structure for 32-bit Message Address /// Section 6.8.1, PCI Local Bus Specification, 2.2 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT16 MsgCtrlReg; UINT32 MsgAddrReg; UINT16 MsgDataReg; } EFI_PCI_CAPABILITY_MSI32; /// /// Message Capability Structure for 64-bit Message Address /// Section 6.8.1, PCI Local Bus Specification, 2.2 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT16 MsgCtrlReg; UINT32 MsgAddrRegLsdw; UINT32 MsgAddrRegMsdw; UINT16 MsgDataReg; } EFI_PCI_CAPABILITY_MSI64; /// /// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG, /// CompactPCI Hot Swap Specification PICMG 2.1, R1.0 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; /// /// not finished - fields need to go here /// } EFI_PCI_CAPABILITY_HOTPLUG; #define PCI_BAR_IDX0 0x00 #define PCI_BAR_IDX1 0x01 #define PCI_BAR_IDX2 0x02 #define PCI_BAR_IDX3 0x03 #define PCI_BAR_IDX4 0x04 #define PCI_BAR_IDX5 0x05 /// /// EFI PCI Option ROM definitions /// #define EFI_ROOT_BRIDGE_LIST 'eprb' #define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1 ///< defined in UEFI Spec. #define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55 #define PCI_DATA_STRUCTURE_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'R') #define PCI_CODE_TYPE_PCAT_IMAGE 0x00 #define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001 ///< defined in UEFI spec. /// /// Standard PCI Expansion ROM Header /// Section 13.4.2, Unified Extensible Firmware Interface Specification, Version 2.1 /// typedef struct { UINT16 Signature; ///< 0xaa55 UINT8 Reserved[0x16]; UINT16 PcirOffset; } PCI_EXPANSION_ROM_HEADER; /// /// Legacy ROM Header Extensions /// Section 6.3.3.1, PCI Local Bus Specification, 2.2 /// typedef struct { UINT16 Signature; ///< 0xaa55 UINT8 Size512; UINT8 InitEntryPoint[3]; UINT8 Reserved[0x12]; UINT16 PcirOffset; } EFI_LEGACY_EXPANSION_ROM_HEADER; /// /// PCI Data Structure Format /// Section 6.3.1.2, PCI Local Bus Specification, 2.2 /// typedef struct { UINT32 Signature; ///< "PCIR" UINT16 VendorId; UINT16 DeviceId; UINT16 Reserved0; UINT16 Length; UINT8 Revision; UINT8 ClassCode[3]; UINT16 ImageLength; UINT16 CodeRevision; UINT8 CodeType; UINT8 Indicator; UINT16 Reserved1; } PCI_DATA_STRUCTURE; /// /// EFI PCI Expansion ROM Header /// Section 13.4.2, Unified Extensible Firmware Interface Specification, Version 2.1 /// typedef struct { UINT16 Signature; ///< 0xaa55 UINT16 InitializationSize; UINT32 EfiSignature; ///< 0x0EF1 UINT16 EfiSubsystem; UINT16 EfiMachineType; UINT16 CompressionType; UINT8 Reserved[8]; UINT16 EfiImageHeaderOffset; UINT16 PcirOffset; } EFI_PCI_EXPANSION_ROM_HEADER; typedef union { UINT8 *Raw; PCI_EXPANSION_ROM_HEADER *Generic; EFI_PCI_EXPANSION_ROM_HEADER *Efi; EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt; } EFI_PCI_ROM_HEADER; #pragma pack() #endif ================================================ FILE: src/edk2/Pci23.h ================================================ /** @file Support for PCI 2.3 standard. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCI23_H_ #define _PCI23_H_ #include "Pci22.h" /// /// PCI_CLASS_MASS_STORAGE, Base Class 01h. /// ///@{ #define PCI_CLASS_MASS_STORAGE_ATA 0x05 #define PCI_IF_MASS_STORAGE_SINGLE_DMA 0x20 #define PCI_IF_MASS_STORAGE_CHAINED_DMA 0x30 ///@} /// /// PCI_CLASS_NETWORK, Base Class 02h. /// ///@{ #define PCI_CLASS_NETWORK_WORLDFIP 0x05 #define PCI_CLASS_NETWORK_PICMG_MULTI_COMPUTING 0x06 ///@} /// /// PCI_CLASS_BRIDGE, Base Class 06h. /// ///@{ #define PCI_CLASS_BRIDGE_SEMI_TRANSPARENT_P2P 0x09 #define PCI_IF_BRIDGE_SEMI_TRANSPARENT_P2P_PRIMARY 0x40 #define PCI_IF_BRIDGE_SEMI_TRANSPARENT_P2P_SECONDARY 0x80 #define PCI_CLASS_BRIDGE_INFINIBAND_TO_PCI 0x0A ///@} /// /// PCI_CLASS_SCC, Base Class 07h. /// ///@{ #define PCI_SUBCLASS_GPIB 0x04 #define PCI_SUBCLASS_SMART_CARD 0x05 ///@} /// /// PCI_CLASS_SERIAL, Base Class 0Ch. /// ///@{ #define PCI_IF_EHCI 0x20 #define PCI_CLASS_SERIAL_IB 0x06 #define PCI_CLASS_SERIAL_IPMI 0x07 #define PCI_IF_IPMI_SMIC 0x00 #define PCI_IF_IPMI_KCS 0x01 ///< Keyboard Controller Style #define PCI_IF_IPMI_BT 0x02 ///< Block Transfer #define PCI_CLASS_SERIAL_SERCOS 0x08 #define PCI_CLASS_SERIAL_CANBUS 0x09 ///@} /// /// PCI_CLASS_WIRELESS, Base Class 0Dh. /// ///@{ #define PCI_SUBCLASS_BLUETOOTH 0x11 #define PCI_SUBCLASS_BROADBAND 0x12 ///@} /// /// PCI_CLASS_DPIO, Base Class 11h. /// ///@{ #define PCI_SUBCLASS_PERFORMANCE_COUNTERS 0x01 #define PCI_SUBCLASS_COMMUNICATION_SYNCHRONIZATION 0x10 #define PCI_SUBCLASS_MANAGEMENT_CARD 0x20 ///@} /// /// defined in PCI Express Spec. /// #define PCI_EXP_MAX_CONFIG_OFFSET 0x1000 /// /// PCI Capability List IDs and records. /// #define EFI_PCI_CAPABILITY_ID_PCIX 0x07 #define EFI_PCI_CAPABILITY_ID_VENDOR 0x09 #pragma pack(1) /// /// PCI-X Capabilities List, /// Section 7.2, PCI-X Addendum to the PCI Local Bus Specification, Revision 1.0b. /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT16 CommandReg; UINT32 StatusReg; } EFI_PCI_CAPABILITY_PCIX; /// /// PCI-X Bridge Capabilities List, /// Section 8.6.2, PCI-X Addendum to the PCI Local Bus Specification, Revision 1.0b. /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT16 SecStatusReg; UINT32 StatusReg; UINT32 SplitTransCtrlRegUp; UINT32 SplitTransCtrlRegDn; } EFI_PCI_CAPABILITY_PCIX_BRDG; /// /// Vendor Specific Capability Header /// Table H-1: Capability IDs, PCI Local Bus Specification, 2.3 /// typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; UINT8 Length; } EFI_PCI_CAPABILITY_VENDOR_HDR; #pragma pack() #define PCI_CODE_TYPE_EFI_IMAGE 0x03 #endif ================================================ FILE: src/edk2/Pci30.h ================================================ /** @file Support for PCI 3.0 standard. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PCI30_H__ #define __PCI30_H__ #include "Pci23.h" /// /// PCI_CLASS_MASS_STORAGE, Base Class 01h. /// ///@{ #define PCI_CLASS_MASS_STORAGE_SATADPA 0x06 #define PCI_IF_MASS_STORAGE_SATA 0x00 #define PCI_IF_MASS_STORAGE_AHCI 0x01 ///@} /// /// PCI_CLASS_WIRELESS, Base Class 0Dh. /// ///@{ #define PCI_SUBCLASS_ETHERNET_80211A 0x20 #define PCI_SUBCLASS_ETHERNET_80211B 0x21 ///@} /** Macro that checks whether device is a SATA controller. @param _p Specified device. @retval TRUE Device is a SATA controller. @retval FALSE Device is not a SATA controller. **/ #define IS_PCI_SATADPA(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SATADPA) /// /// PCI Capability List IDs and records /// #define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10 #pragma pack(1) /// /// PCI Data Structure Format /// Section 5.1.2, PCI Firmware Specification, Revision 3.0 /// typedef struct { UINT32 Signature; ///< "PCIR" UINT16 VendorId; UINT16 DeviceId; UINT16 DeviceListOffset; UINT16 Length; UINT8 Revision; UINT8 ClassCode[3]; UINT16 ImageLength; UINT16 CodeRevision; UINT8 CodeType; UINT8 Indicator; UINT16 MaxRuntimeImageLength; UINT16 ConfigUtilityCodeHeaderOffset; UINT16 DMTFCLPEntryPointOffset; } PCI_3_0_DATA_STRUCTURE; #pragma pack() #endif ================================================ FILE: src/edk2/PciCodeId.h ================================================ /** @file The file lists the PCI class codes only defined in PCI code and ID assignment specification revision 1.3. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PCI_CODE_ID_H__ #define __PCI_CODE_ID_H__ /// /// PCI_CLASS_MASS_STORAGE, Base Class 01h. /// ///@{ #define PCI_IF_MASS_STORAGE_SCSI_VENDOR_SPECIFIC 0x00 #define PCI_IF_MASS_STORAGE_SCSI_DEVICE_PQI 0x11 #define PCI_IF_MASS_STORAGE_SCSI_CONTROLLER_PQI 0x12 #define PCI_IF_MASS_STORAGE_SCSI_DEVICE_CONTROLLER_PQI 0x13 #define PCI_IF_MASS_STORAGE_SCSI_DEVICE_NVM_EXPRESS 0x21 #define PCI_IF_MASS_STORAGE_SATA_SERIAL_BUS 0x02 #define PCI_CLASS_MASS_STORAGE_SAS 0x07 #define PCI_IF_MASS_STORAGE_SAS 0x00 #define PCI_IF_MASS_STORAGE_SAS_SERIAL_BUS 0x01 #define PCI_CLASS_MASS_STORAGE_SOLID_STATE 0x08 #define PCI_IF_MASS_STORAGE_SOLID_STATE 0x00 #define PCI_IF_MASS_STORAGE_SOLID_STATE_NVMHCI 0x01 #define PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI 0x02 ///@} /// /// PCI_CLASS_NETWORK, Base Class 02h. /// ///@{ #define PCI_CLASS_NETWORK_INFINIBAND 0x07 ///@} /// /// PCI_CLASS_MEDIA, Base Class 04h. /// ///@{ #define PCI_CLASS_MEDIA_MIXED_MODE 0x03 ///@} /// /// PCI_CLASS_BRIDGE, Base Class 06h. /// ///@{ #define PCI_CLASS_BRIDGE_ADVANCED_SWITCHING_TO_PCI 0x0B #define PCI_IF_BRIDGE_ADVANCED_SWITCHING_TO_PCI_CUSTOM 0x00 #define PCI_IF_BRIDGE_ADVANCED_SWITCHING_TO_PCI_ASI_SIG 0x01 ///@} /// /// PCI_CLASS_SYSTEM_PERIPHERAL, Base Class 08h. /// ///@{ #define PCI_IF_HPET 0x03 #define PCI_SUBCLASS_SD_HOST_CONTROLLER 0x05 #define PCI_SUBCLASS_IOMMU 0x06 ///@} /// /// PCI_CLASS_PROCESSOR, Base Class 0Bh. /// ///@{ #define PCI_SUBCLASS_PROC_OTHER 0x80 ///@} /// /// PCI_CLASS_SERIAL, Base Class 0Ch. /// ///@{ #define PCI_IF_XHCI 0x30 #define PCI_CLASS_SERIAL_OTHER 0x80 ///@} /// /// PCI_CLASS_SATELLITE, Base Class 0Fh. /// ///@{ #define PCI_SUBCLASS_SATELLITE_OTHER 0x80 ///@} /// /// PCI_CLASS_PROCESSING_ACCELERATOR, Base Class 12h. /// ///@{ #define PCI_CLASS_PROCESSING_ACCELERATOR 0x12 ///@} #endif ================================================ FILE: src/edk2/PciExpress21.h ================================================ /** @file Support for the latest PCI standard. Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCIEXPRESS21_H_ #define _PCIEXPRESS21_H_ #include "Pci30.h" /** Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an ECAM (Enhanced Configuration Access Mechanism) address. The unused upper bits of Bus, Device, Function and Register are stripped prior to the generation of the address. @param Bus PCI Bus number. Range 0..255. @param Device PCI Device number. Range 0..31. @param Function PCI Function number. Range 0..7. @param Register PCI Register number. Range 0..4095. @return The encode ECAM address. **/ #define PCI_ECAM_ADDRESS(Bus, Device, Function, Offset) \ (((Offset) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20)) #pragma pack(1) /// /// PCI Express Capability Structure /// typedef union { struct { UINT16 Version : 4; UINT16 DevicePortType : 4; UINT16 SlotImplemented : 1; UINT16 InterruptMessageNumber : 5; UINT16 Undefined : 1; UINT16 FlitModeSupported : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_CAPABILITY; #define PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT 0 #define PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT 1 #define PCIE_DEVICE_PORT_TYPE_ROOT_PORT 4 #define PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT 5 #define PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT 6 #define PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE 7 #define PCIE_DEVICE_PORT_TYPE_PCI_TO_PCIE_BRIDGE 8 #define PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT 9 #define PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR 10 typedef union { struct { UINT32 MaxPayloadSize : 3; UINT32 PhantomFunctions : 2; UINT32 ExtendedTagField : 1; UINT32 EndpointL0sAcceptableLatency : 3; UINT32 EndpointL1AcceptableLatency : 3; UINT32 Undefined : 3; UINT32 RoleBasedErrorReporting : 1; UINT32 ErrCorSubclassCapable : 1; UINT32 RxMpsFixed : 1; UINT32 CapturedSlotPowerLimitValue : 8; UINT32 CapturedSlotPowerLimitScale : 2; UINT32 FunctionLevelReset : 1; UINT32 MixedMpsSupported : 1; UINT32 Reserved2 : 2; } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_CAPABILITY; typedef union { struct { UINT16 CorrectableError : 1; UINT16 NonFatalError : 1; UINT16 FatalError : 1; UINT16 UnsupportedRequest : 1; UINT16 RelaxedOrdering : 1; UINT16 MaxPayloadSize : 3; UINT16 ExtendedTagField : 1; UINT16 PhantomFunctions : 1; UINT16 AuxPower : 1; UINT16 NoSnoop : 1; UINT16 MaxReadRequestSize : 3; UINT16 BridgeConfigurationRetryOrFunctionLevelReset : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_DEVICE_CONTROL; #define PCIE_MAX_PAYLOAD_SIZE_128B 0 #define PCIE_MAX_PAYLOAD_SIZE_256B 1 #define PCIE_MAX_PAYLOAD_SIZE_512B 2 #define PCIE_MAX_PAYLOAD_SIZE_1024B 3 #define PCIE_MAX_PAYLOAD_SIZE_2048B 4 #define PCIE_MAX_PAYLOAD_SIZE_4096B 5 #define PCIE_MAX_PAYLOAD_SIZE_RVSD1 6 #define PCIE_MAX_PAYLOAD_SIZE_RVSD2 7 #define PCIE_MAX_READ_REQ_SIZE_128B 0 #define PCIE_MAX_READ_REQ_SIZE_256B 1 #define PCIE_MAX_READ_REQ_SIZE_512B 2 #define PCIE_MAX_READ_REQ_SIZE_1024B 3 #define PCIE_MAX_READ_REQ_SIZE_2048B 4 #define PCIE_MAX_READ_REQ_SIZE_4096B 5 #define PCIE_MAX_READ_REQ_SIZE_RVSD1 6 #define PCIE_MAX_READ_REQ_SIZE_RVSD2 7 typedef union { struct { UINT16 CorrectableError : 1; UINT16 NonFatalError : 1; UINT16 FatalError : 1; UINT16 UnsupportedRequest : 1; UINT16 AuxPower : 1; UINT16 TransactionsPending : 1; UINT16 EmergencyPowerReductionDetected : 1; UINT16 Reserved : 9; } Bits; UINT16 Uint16; } PCI_REG_PCIE_DEVICE_STATUS; typedef union { struct { UINT32 MaxLinkSpeed : 4; UINT32 MaxLinkWidth : 6; UINT32 Aspm : 2; UINT32 L0sExitLatency : 3; UINT32 L1ExitLatency : 3; UINT32 ClockPowerManagement : 1; UINT32 SurpriseDownError : 1; UINT32 DataLinkLayerLinkActive : 1; UINT32 LinkBandwidthNotification : 1; UINT32 AspmOptionalityCompliance : 1; UINT32 Reserved : 1; UINT32 PortNumber : 8; } Bits; UINT32 Uint32; } PCI_REG_PCIE_LINK_CAPABILITY; #define PCIE_LINK_ASPM_L0S BIT0 #define PCIE_LINK_ASPM_L1 BIT1 typedef union { struct { UINT16 AspmControl : 2; UINT16 PtmPropagationDelayB : 1; UINT16 ReadCompletionBoundary : 1; UINT16 LinkDisable : 1; UINT16 RetrainLink : 1; UINT16 CommonClockConfiguration : 1; UINT16 ExtendedSynch : 1; UINT16 ClockPowerManagement : 1; UINT16 HardwareAutonomousWidthDisable : 1; UINT16 LinkBandwidthManagementInterrupt : 1; UINT16 LinkAutonomousBandwidthInterrupt : 1; UINT16 SrisClocking : 1; UINT16 FlitModeDisable : 1; UINT16 DrsSignalingControl : 2; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_CONTROL; typedef union { struct { UINT16 CurrentLinkSpeed : 4; UINT16 NegotiatedLinkWidth : 6; UINT16 Undefined : 1; UINT16 LinkTraining : 1; UINT16 SlotClockConfiguration : 1; UINT16 DataLinkLayerLinkActive : 1; UINT16 LinkBandwidthManagement : 1; UINT16 LinkAutonomousBandwidth : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_STATUS; typedef union { struct { UINT32 AttentionButton : 1; UINT32 PowerController : 1; UINT32 MrlSensor : 1; UINT32 AttentionIndicator : 1; UINT32 PowerIndicator : 1; UINT32 HotPlugSurprise : 1; UINT32 HotPlugCapable : 1; UINT32 SlotPowerLimitValue : 8; UINT32 SlotPowerLimitScale : 2; UINT32 ElectromechanicalInterlock : 1; UINT32 NoCommandCompleted : 1; UINT32 PhysicalSlotNumber : 13; } Bits; UINT32 Uint32; } PCI_REG_PCIE_SLOT_CAPABILITY; typedef union { struct { UINT16 AttentionButtonPressed : 1; UINT16 PowerFaultDetected : 1; UINT16 MrlSensorChanged : 1; UINT16 PresenceDetectChanged : 1; UINT16 CommandCompletedInterrupt : 1; UINT16 HotPlugInterrupt : 1; UINT16 AttentionIndicator : 2; UINT16 PowerIndicator : 2; UINT16 PowerController : 1; UINT16 ElectromechanicalInterlock : 1; UINT16 DataLinkLayerStateChanged : 1; UINT16 AutoSlotPowerLimitDisable : 1; UINT16 InbandPdDisable : 1; UINT16 Reserved : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_SLOT_CONTROL; typedef union { struct { UINT16 AttentionButtonPressed : 1; UINT16 PowerFaultDetected : 1; UINT16 MrlSensorChanged : 1; UINT16 PresenceDetectChanged : 1; UINT16 CommandCompleted : 1; UINT16 MrlSensor : 1; UINT16 PresenceDetect : 1; UINT16 ElectromechanicalInterlock : 1; UINT16 DataLinkLayerStateChanged : 1; UINT16 Reserved : 7; } Bits; UINT16 Uint16; } PCI_REG_PCIE_SLOT_STATUS; typedef union { struct { UINT16 SystemErrorOnCorrectableError : 1; UINT16 SystemErrorOnNonFatalError : 1; UINT16 SystemErrorOnFatalError : 1; UINT16 PmeInterrupt : 1; UINT16 CrsSoftwareVisibility : 1; UINT16 NoNfmSubtree : 1; UINT16 Reserved : 10; } Bits; UINT16 Uint16; } PCI_REG_PCIE_ROOT_CONTROL; typedef union { struct { UINT16 CrsSoftwareVisibility : 1; UINT16 Reserved : 15; } Bits; UINT16 Uint16; } PCI_REG_PCIE_ROOT_CAPABILITY; typedef union { struct { UINT32 PmeRequesterId : 16; UINT32 PmeStatus : 1; UINT32 PmePending : 1; UINT32 Reserved : 14; } Bits; UINT32 Uint32; } PCI_REG_PCIE_ROOT_STATUS; typedef union { struct { UINT32 CompletionTimeoutRanges : 4; UINT32 CompletionTimeoutDisable : 1; UINT32 AriForwarding : 1; UINT32 AtomicOpRouting : 1; UINT32 AtomicOp32Completer : 1; UINT32 AtomicOp64Completer : 1; UINT32 Cas128Completer : 1; UINT32 NoRoEnabledPrPrPassing : 1; UINT32 LtrMechanism : 1; UINT32 TphCompleter : 2; UINT32 Reserved : 2; UINT32 TenBitTagCompleterSupported : 1; UINT32 TenBitTagRequesterSupported : 1; UINT32 Obff : 2; UINT32 ExtendedFmtField : 1; UINT32 EndEndTlpPrefix : 1; UINT32 MaxEndEndTlpPrefixes : 2; UINT32 EmergencyPowerReductionSupported : 2; UINT32 EmergencyPowerReductionInitializationRequired : 1; UINT32 Reserved2 : 1; UINT32 DmwrCompleter : 1; UINT32 DmwrLengths : 2; UINT32 FrsSupported : 1; } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_CAPABILITY2; #define PCIE_COMPLETION_TIMEOUT_NOT_SUPPORTED 0 #define PCIE_COMPLETION_TIMEOUT_RANGE_A_SUPPORTED 1 #define PCIE_COMPLETION_TIMEOUT_RANGE_B_SUPPORTED 2 #define PCIE_COMPLETION_TIMEOUT_RANGE_A_B_SUPPORTED 3 #define PCIE_COMPLETION_TIMEOUT_RANGE_B_C_SUPPORTED 6 #define PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_SUPPORTED 7 #define PCIE_COMPLETION_TIMEOUT_RANGE_B_C_D_SUPPORTED 14 #define PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_D_SUPPORTED 15 #define PCIE_DEVICE_CAPABILITY_OBFF_MESSAGE BIT0 #define PCIE_DEVICE_CAPABILITY_OBFF_WAKE BIT1 typedef union { struct { UINT16 CompletionTimeoutValue : 4; UINT16 CompletionTimeoutDisable : 1; UINT16 AriForwarding : 1; UINT16 AtomicOpRequester : 1; UINT16 AtomicOpEgressBlocking : 1; UINT16 IdoRequest : 1; UINT16 IdoCompletion : 1; UINT16 LtrMechanism : 1; UINT16 EmergencyPowerReductionRequest : 1; UINT16 TenBitTagRequesterEnable : 1; UINT16 Obff : 2; UINT16 EndEndTlpPrefixBlocking : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_DEVICE_CONTROL2; #define PCIE_COMPLETION_TIMEOUT_50US_50MS 0 #define PCIE_COMPLETION_TIMEOUT_50US_100US 1 #define PCIE_COMPLETION_TIMEOUT_1MS_10MS 2 #define PCIE_COMPLETION_TIMEOUT_16MS_55MS 5 #define PCIE_COMPLETION_TIMEOUT_65MS_210MS 6 #define PCIE_COMPLETION_TIMEOUT_260MS_900MS 9 #define PCIE_COMPLETION_TIMEOUT_1S_3_5S 10 #define PCIE_COMPLETION_TIMEOUT_4S_13S 13 #define PCIE_COMPLETION_TIMEOUT_17S_64S 14 #define PCIE_DEVICE_CONTROL_OBFF_DISABLED 0 #define PCIE_DEVICE_CONTROL_OBFF_MESSAGE_A 1 #define PCIE_DEVICE_CONTROL_OBFF_MESSAGE_B 2 #define PCIE_DEVICE_CONTROL_OBFF_WAKE 3 typedef union { struct { UINT32 Reserved : 1; UINT32 LinkSpeedsVector : 7; UINT32 Crosslink : 1; UINT32 LowerSkpOsGeneration : 7; UINT32 LowerSkpOsReception : 7; UINT32 RetimerPresenceDetect : 1; UINT32 TwoRetimersPresenceDetect : 1; UINT32 Reserved2 : 6; UINT32 DrsSupported : 1; } Bits; UINT32 Uint32; } PCI_REG_PCIE_LINK_CAPABILITY2; typedef union { struct { UINT16 TargetLinkSpeed : 4; UINT16 EnterCompliance : 1; UINT16 HardwareAutonomousSpeedDisable : 1; UINT16 SelectableDeemphasis : 1; UINT16 TransmitMargin : 3; UINT16 EnterModifiedCompliance : 1; UINT16 ComplianceSos : 1; UINT16 CompliancePresetDeemphasis : 4; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_CONTROL2; typedef union { struct { UINT16 CurrentDeemphasisLevel : 1; UINT16 EqualizationComplete : 1; UINT16 EqualizationPhase1Successful : 1; UINT16 EqualizationPhase2Successful : 1; UINT16 EqualizationPhase3Successful : 1; UINT16 LinkEqualizationRequest : 1; UINT16 RetimerPresence : 1; UINT16 TwoRetimersPresence : 1; UINT16 CrosslinkResolution : 2; UINT16 FlitModeStatus : 1; UINT16 Reserved : 1; UINT16 DownstreamComponentPresence : 3; UINT16 DRSMessageReceived : 1; } Bits; UINT16 Uint16; } PCI_REG_PCIE_LINK_STATUS2; typedef union { struct { UINT32 InbandPdDisable : 1; UINT32 Reserved : 30; } Bits; UINT32 Uint32; } PCI_REG_PCIE_SLOT_CAPABILITY2; typedef struct { EFI_PCI_CAPABILITY_HDR Hdr; PCI_REG_PCIE_CAPABILITY Capability; PCI_REG_PCIE_DEVICE_CAPABILITY DeviceCapability; PCI_REG_PCIE_DEVICE_CONTROL DeviceControl; PCI_REG_PCIE_DEVICE_STATUS DeviceStatus; PCI_REG_PCIE_LINK_CAPABILITY LinkCapability; PCI_REG_PCIE_LINK_CONTROL LinkControl; PCI_REG_PCIE_LINK_STATUS LinkStatus; PCI_REG_PCIE_SLOT_CAPABILITY SlotCapability; PCI_REG_PCIE_SLOT_CONTROL SlotControl; PCI_REG_PCIE_SLOT_STATUS SlotStatus; PCI_REG_PCIE_ROOT_CONTROL RootControl; PCI_REG_PCIE_ROOT_CAPABILITY RootCapability; PCI_REG_PCIE_ROOT_STATUS RootStatus; PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCapability2; PCI_REG_PCIE_DEVICE_CONTROL2 DeviceControl2; UINT16 DeviceStatus2; PCI_REG_PCIE_LINK_CAPABILITY2 LinkCapability2; PCI_REG_PCIE_LINK_CONTROL2 LinkControl2; PCI_REG_PCIE_LINK_STATUS2 LinkStatus2; PCI_REG_PCIE_SLOT_CAPABILITY2 SlotCapability2; UINT16 SlotControl2; UINT16 SlotStatus2; } PCI_CAPABILITY_PCIEXP; #define EFI_PCIE_CAPABILITY_BASE_OFFSET 0x100 #define EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY 0x10 #define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET 0x24 #define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING 0x20 #define EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET 0x28 #define EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING 0x20 // // for SR-IOV // #define EFI_PCIE_CAPABILITY_ID_ARI 0x0E #define EFI_PCIE_CAPABILITY_ID_ATS 0x0F #define EFI_PCIE_CAPABILITY_ID_SRIOV 0x10 #define EFI_PCIE_CAPABILITY_ID_MRIOV 0x11 #define PCI_EXPRESS_EXTENDED_CAPABILITY_SRIOV_ID 0x0010 #define PCI_EXPRESS_EXTENDED_CAPABILITY_SRIOV_VER1 0x1 typedef struct { UINT32 CapabilityHeader; UINT32 Capability; UINT16 Control; UINT16 Status; UINT16 InitialVFs; UINT16 TotalVFs; UINT16 NumVFs; UINT8 FunctionDependencyLink; UINT8 Reserved0; UINT16 FirstVFOffset; UINT16 VFStride; UINT16 Reserved1; UINT16 VFDeviceID; UINT32 SupportedPageSize; UINT32 SystemPageSize; UINT32 VFBar[6]; UINT32 VFMigrationStateArrayOffset; } SR_IOV_CAPABILITY_REGISTER; #define EFI_PCIE_CAPABILITY_ID_SRIOV_CAPABILITIES 0x04 #define EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL 0x08 #define EFI_PCIE_CAPABILITY_ID_SRIOV_STATUS 0x0A #define EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS 0x0C #define EFI_PCIE_CAPABILITY_ID_SRIOV_TOTALVFS 0x0E #define EFI_PCIE_CAPABILITY_ID_SRIOV_NUMVFS 0x10 #define EFI_PCIE_CAPABILITY_ID_SRIOV_FUNCTION_DEPENDENCY_LINK 0x12 #define EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF 0x14 #define EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE 0x16 #define EFI_PCIE_CAPABILITY_ID_SRIOV_VFDEVICEID 0x1A #define EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE 0x1C #define EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE 0x20 #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0 0x24 #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR1 0x28 #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR2 0x2C #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR3 0x30 #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR4 0x34 #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5 0x38 #define EFI_PCIE_CAPABILITY_ID_SRIOV_VF_MIGRATION_STATE 0x3C typedef struct { UINT32 CapabilityId : 16; UINT32 CapabilityVersion : 4; UINT32 NextCapabilityOffset : 12; } PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER; #define PCI_EXP_EXT_HDR PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER #define PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID 0x0001 #define PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_VER1 0x1 #define PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_VER2 0x2 typedef union { struct { UINT32 Undefined : 1; UINT32 Reserved : 3; UINT32 DataLinkProtocolError : 1; UINT32 SurpriseDownError : 1; UINT32 Reserved2 : 6; UINT32 PoisonedTlp : 1; UINT32 FlowControlProtocolError : 1; UINT32 CompletionTimeout : 1; UINT32 CompleterAbort : 1; UINT32 UnexpectedCompletion : 1; UINT32 ReceiverOverflow : 1; UINT32 MalformedTlp : 1; UINT32 EcrcError : 1; UINT32 UnsupportedRequestError : 1; UINT32 AcsVoilation : 1; UINT32 UncorrectableInternalError : 1; UINT32 McBlockedTlp : 1; UINT32 AtomicOpEgressBlocked : 1; UINT32 TlpPrefixBlockedError : 1; UINT32 Reserved3 : 6; } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_UNCORRECTABLE_ERROR; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_UNCORRECTABLE_ERROR UncorrectableErrorStatus; PCI_EXPRESS_REG_UNCORRECTABLE_ERROR UncorrectableErrorMask; PCI_EXPRESS_REG_UNCORRECTABLE_ERROR UncorrectableErrorSeverity; UINT32 CorrectableErrorStatus; UINT32 CorrectableErrorMask; UINT32 AdvancedErrorCapabilitiesAndControl; UINT32 HeaderLog[4]; UINT32 RootErrorCommand; UINT32 RootErrorStatus; UINT16 ErrorSourceIdentification; UINT16 CorrectableErrorSourceIdentification; UINT32 TlpPrefixLog[4]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING; #define PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID 0x0002 #define PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_MFVC 0x0009 #define PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_VER1 0x1 typedef struct { UINT32 VcResourceCapability : 24; UINT32 PortArbTableOffset : 8; UINT32 VcResourceControl; UINT16 Reserved1; UINT16 VcResourceStatus; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 ExtendedVcCount : 3; UINT32 PortVcCapability1 : 29; UINT32 PortVcCapability2 : 24; UINT32 VcArbTableOffset : 8; UINT16 PortVcControl; UINT16 PortVcStatus; PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC Capability[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY; #define PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID 0x0003 #define PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT64 SerialNumber; } PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER; #define PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID 0x0005 #define PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 ElementSelfDescription; UINT32 Reserved; UINT32 LinkEntry[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION; #define PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(LINK_DECLARATION) (UINT8)(((LINK_DECLARATION->ElementSelfDescription)&0x0000ff00)>>8) #define PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID 0x0006 #define PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 RootComplexLinkCapabilities; UINT16 RootComplexLinkControl; UINT16 RootComplexLinkStatus; } PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL; #define PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID 0x0004 #define PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 DataSelect : 8; UINT32 Reserved : 24; UINT32 Data; UINT32 PowerBudgetCapability : 1; UINT32 Reserved2 : 7; UINT32 Reserved3 : 24; } PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING; #define PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID 0x000D #define PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT16 AcsCapability; UINT16 AcsControl; UINT8 EgressControlVectorArray[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED; #define PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(ACS_EXTENDED) (UINT8)(((ACS_EXTENDED->AcsCapability)&0x00000020)) #define PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(ACS_EXTENDED) (UINT8)(((ACS_EXTENDED->AcsCapability)&0x0000FF00)) #define PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID 0x0007 #define PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 AssociationBitmap; } PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION; #define PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID 0x0008 #define PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_VER1 0x1 typedef PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTI_FUNCTION_VIRTUAL_CHANNEL_CAPABILITY; #define PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID 0x000B #define PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 VendorSpecificHeader; UINT8 VendorSpecific[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC; #define PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(VENDOR) (UINT16)(((VENDOR->VendorSpecificHeader)&0xFFF00000)>>20) #define PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID 0x000A #define PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT16 VendorId; UINT16 DeviceId; UINT32 RcrbCapabilities; UINT32 RcrbControl; UINT32 Reserved; } PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER; #define PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID 0x0012 #define PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT16 MultiCastCapability; UINT16 MulticastControl; UINT64 McBaseAddress; UINT64 McReceiveAddress; UINT64 McBlockAll; UINT64 McBlockUntranslated; UINT64 McOverlayBar; } PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST; #define PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID 0x0015 #define PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_VER1 0x1 typedef union { struct { UINT32 Reserved : 4; UINT32 BarSizeCapability : 28; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY; typedef union { struct { UINT32 BarIndex : 3; UINT32 Reserved : 2; UINT32 ResizableBarNumber : 3; UINT32 BarSize : 6; UINT32 Reserved2 : 2; UINT32 BarSizeCapability : 16; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY ResizableBarCapability; PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL ResizableBarControl; } PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY Capability[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR; #define GET_NUMBER_RESIZABLE_BARS(x) (x->Capability[0].ResizableBarControl.Bits.ResizableBarNumber) #define PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID 0x000E #define PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT16 AriCapability; UINT16 AriControl; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY; #define PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID 0x0016 #define PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 DpaCapability; UINT32 DpaLatencyIndicator; UINT16 DpaStatus; UINT16 DpaControl; UINT8 DpaPowerAllocationArray[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION; #define PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(POWER) (UINT32)(((POWER->DpaCapability)&0x0000000F)) #define PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID 0x0018 #define PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT16 MaxSnoopLatency; UINT16 MaxNoSnoopLatency; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING; #define PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID 0x0017 #define PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 TphRequesterCapability; UINT32 TphRequesterControl; UINT16 TphStTable[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH; #define GET_TPH_TABLE_SIZE(x) ((x->TphRequesterCapability & 0x7FF0000)>>16) * sizeof(UINT16) /// Address Translation Services Extended Capability Structure /// /// Based on section 5.1 of PCI Express Address Translation Services Specification 1.1 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_ATS_ID 0x000F #define PCI_EXPRESS_EXTENDED_CAPABILITY_ATS_VER1 0x1 typedef union { struct { UINT16 InvalidateQueueDepth : 5; UINT16 Reserved : 9; UINT16 GlobalInvalidateSupported : 1; UINT16 Reserved2 : 1; } Bits; UINT16 Uint16; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ATS_CAPABILITY; typedef union { struct { UINT16 EnableATS : 1; UINT16 GlobalInvalidate : 1; UINT16 Reserved : 14; } Bits; UINT16 Uint16; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ATS_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_ATS_CAPABILITY Capability; PCI_EXPRESS_EXTENDED_CAPABILITIES_ATS_CONTROL Control; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ATS; ///@} #pragma pack() #endif ================================================ FILE: src/edk2/PciExpress30.h ================================================ /** @file Support for the PCI Express 3.0 standard. This header file may not define all structures. Please extend as required. Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCIEXPRESS30_H_ #define _PCIEXPRESS30_H_ #include "PciExpress21.h" #pragma pack(1) #define PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID 0x0019 #define PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_VER1 0x1 typedef union { struct { UINT32 PerformEqualization : 1; UINT32 LinkEqualizationRequestInterruptEnable : 1; UINT32 Reserved : 30; } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_LINK_CONTROL3; typedef union { struct { UINT16 DownstreamPortTransmitterPreset : 4; UINT16 DownstreamPortReceiverPresetHint : 3; UINT16 Reserved : 1; UINT16 UpstreamPortTransmitterPreset : 4; UINT16 UpstreamPortReceiverPresetHint : 3; UINT16 Reserved2 : 1; } Bits; UINT16 Uint16; } PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_LINK_CONTROL3 LinkControl3; UINT32 LaneErrorStatus; PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL EqualizationControl[2]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE; /// VF Resizable BAR Extended Capability Structure /// /// Based on section 7.22 of PCI Express Base Specification 3.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_VF_RESIZABLE_BAR_ID 0x0024 #define PCI_EXPRESS_EXTENDED_CAPABILITY_VF_RESIZABLE_BAR_VER1 0x1 typedef union { struct { UINT32 Reserved : 4; UINT32 VfBarSizeCapability : 28; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_CAPABILITY; typedef union { struct { UINT32 VfBarIndex : 3; UINT32 Reserved : 2; UINT32 VfResizableBarNumber : 3; UINT32 VfBarSize : 6; UINT32 Reserved2 : 2; UINT32 VfBarSizeCapability : 16; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_CAPABILITY VfResizableBarCapability; PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_CONTROL VfResizableBarControl; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_ENTRY; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR_ENTRY Capability[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_VF_RESIZABLE_BAR; ///@} #pragma pack() #endif ================================================ FILE: src/edk2/PciExpress31.h ================================================ /** @file Support for the PCI Express 3.1 standard. This header file may not define all structures. Please extend as required. Copyright (c) 2016, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCIEXPRESS31_H_ #define _PCIEXPRESS31_H_ #include "PciExpress30.h" #pragma pack(1) #define PCI_EXPRESS_EXTENDED_CAPABILITY_L1_PM_SUBSTATES_ID 0x001E #define PCI_EXPRESS_EXTENDED_CAPABILITY_L1_PM_SUBSTATES_VER1 0x1 typedef union { struct { UINT32 PciPmL12 : 1; UINT32 PciPmL11 : 1; UINT32 AspmL12 : 1; UINT32 AspmL11 : 1; UINT32 L1PmSubstates : 1; UINT32 Reserved : 3; UINT32 CommonModeRestoreTime : 8; UINT32 TPowerOnScale : 2; UINT32 Reserved2 : 1; UINT32 TPowerOnValue : 5; UINT32 Reserved3 : 8; } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_L1_PM_SUBSTATES_CAPABILITY; typedef union { struct { UINT32 PciPmL12 : 1; UINT32 PciPmL11 : 1; UINT32 AspmL12 : 1; UINT32 AspmL11 : 1; UINT32 Reserved : 4; UINT32 CommonModeRestoreTime : 8; UINT32 LtrL12ThresholdValue : 10; UINT32 Reserved2 : 3; UINT32 LtrL12ThresholdScale : 3; } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_L1_PM_SUBSTATES_CONTROL1; typedef union { struct { UINT32 TPowerOnScale : 2; UINT32 Reserved : 1; UINT32 TPowerOnValue : 5; UINT32 Reserved2 : 24; } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_L1_PM_SUBSTATES_CONTROL2; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_L1_PM_SUBSTATES_CAPABILITY Capability; PCI_EXPRESS_REG_L1_PM_SUBSTATES_CONTROL1 Control1; PCI_EXPRESS_REG_L1_PM_SUBSTATES_CONTROL2 Control2; } PCI_EXPRESS_EXTENDED_CAPABILITIES_L1_PM_SUBSTATES; /// Process Address Space ID Extended Capability Structure /// /// Based on section 7.29 of PCI Express Base Specification 3.1 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_PASID_ID 0x001B #define PCI_EXPRESS_EXTENDED_CAPABILITY_PASID_VER1 0x1 typedef union { struct { UINT16 PasidSupport : 1; UINT16 ExecutePermissionSupport : 1; UINT16 PrivilegedModeSupport : 1; UINT16 Reserved1 : 5; UINT16 MaxPasidWidth : 5; UINT16 Reserved2 : 3; } Bits; UINT16 Uint16; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PASID_CAPABILITY; typedef union { struct { UINT16 PasidEnable : 1; UINT16 ExecutePermissionEnable : 1; UINT16 PrivilegedModeEnable : 1; UINT16 Reserved : 13; } Bits; UINT16 Uint16; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PASID_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_PASID_CAPABILITY Capability; PCI_EXPRESS_EXTENDED_CAPABILITIES_PASID_CONTROL Control; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PASID; ///@} #pragma pack() #endif ================================================ FILE: src/edk2/PciExpress40.h ================================================ /** @file Support for the PCI Express 4.0 standard. This header file may not define all structures. Please extend as required. Copyright (c) 2018, American Megatrends, Inc. All rights reserved.
Copyright (c) 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCIEXPRESS40_H_ #define _PCIEXPRESS40_H_ #include "PciExpress31.h" #pragma pack(1) /// The Physical Layer PCI Express Extended Capability definitions. /// /// Based on section 7.7.5 of PCI Express Base Specification 4.0. ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_16_0_ID 0x0026 #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_16_0_VER1 0x1 // Register offsets from Physical Layer PCI-E Ext Cap Header #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CAPABILITIES_OFFSET 0x04 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CONTROL_OFFSET 0x08 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_STATUS_OFFSET 0x0C #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_LOCAL_DATA_PARITY_STATUS_OFFSET 0x10 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_FIRST_RETIMER_DATA_PARITY_STATUS_OFFSET 0x14 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_SECOND_RETIMER_DATA_PARITY_STATUS_OFFSET 0x18 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_LANE_EQUALIZATION_CONTROL_OFFSET 0x20 typedef union { struct { UINT32 Reserved : 32; // Reserved bit 0:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CAPABILITIES; typedef union { struct { UINT32 Reserved : 32; // Reserved bit 0:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CONTROL; typedef union { struct { UINT32 EqualizationComplete : 1; // bit 0 UINT32 EqualizationPhase1Success : 1; // bit 1 UINT32 EqualizationPhase2Success : 1; // bit 2 UINT32 EqualizationPhase3Success : 1; // bit 3 UINT32 LinkEqualizationRequest : 1; // bit 4 UINT32 Reserved : 27; // Reserved bit 5:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_STATUS; typedef union { struct { UINT8 DownstreamPortTransmitterPreset : 4; // bit 0..3 UINT8 UpstreamPortTransmitterPreset : 4; // bit 4..7 } Bits; UINT8 Uint8; } PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_LANE_EQUALIZATION_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CAPABILITIES Capablities; PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_CONTROL Control; PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_STATUS Status; UINT32 LocalDataParityMismatchStatus; UINT32 FirstRetimerDataParityMismatchStatus; UINT32 SecondRetimerDataParityMismatchStatus; UINT32 Reserved; PCI_EXPRESS_REG_PHYSICAL_LAYER_16_0_LANE_EQUALIZATION_CONTROL LaneEqualizationControl[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PHYSICAL_LAYER_16_0; ///@} /// The Designated Vendor Specific Capability definitions /// /// Based on section 7.9.6 of PCI Express Base Specification 4.0. ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_DESIGNATED_VENDOR_SPECIFIC_ID 0x0023 #define PCI_EXPRESS_EXTENDED_CAPABILITY_DESIGNATED_VENDOR_SPECIFIC_VER1 0x1 typedef union { struct { UINT32 DvsecVendorId : 16; // bit 0..15 UINT32 DvsecRevision : 4; // bit 16..19 UINT32 DvsecLength : 12; // bit 20..31 } Bits; UINT32 Uint32; } PCI_EXPRESS_DESIGNATED_VENDOR_SPECIFIC_HEADER_1; typedef union { struct { UINT16 DvsecId : 16; // bit 0..15 } Bits; UINT16 Uint16; } PCI_EXPRESS_DESIGNATED_VENDOR_SPECIFIC_HEADER_2; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_DESIGNATED_VENDOR_SPECIFIC_HEADER_1 DesignatedVendorSpecificHeader1; PCI_EXPRESS_DESIGNATED_VENDOR_SPECIFIC_HEADER_2 DesignatedVendorSpecificHeader2; UINT8 DesignatedVendorSpecific[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DESIGNATED_VENDOR_SPECIFIC; ///@} /// Data Link Feature Extended Capability Structure /// /// Based on section 7.7.4 of PCI Express Base Specification 4.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_DATA_LINK_FEATURE_ID 0x0025 #define PCI_EXPRESS_EXTENDED_CAPABILITY_DATA_LINK_FEATURE_VER1 0x1 typedef union { struct { UINT32 Reserved1 : 1; UINT32 ScrambleDisableSupported : 1; UINT32 Reserved2 : 30; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_LINK_FEATURE_CAPABILITY; typedef union { struct { UINT32 Reserved1 : 1; UINT32 ScrambleDisable : 1; UINT32 Reserved2 : 30; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_LINK_FEATURE_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_LINK_FEATURE_CAPABILITY Capability; PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_LINK_FEATURE_CONTROL Control; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_LINK_FEATURE; ///@} /// Lane Margining at Receiver Extended Capability Structure /// /// Based on section 7.7.6 of PCI Express Base Specification 4.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_LANE_MARGINING_AT_RECEIVER_ID 0x0027 #define PCI_EXPRESS_EXTENDED_CAPABILITY_LANE_MARGINING_AT_RECEIVER_VER1 0x1 typedef union { struct { UINT8 MaxLaneNumber : 5; UINT8 Reserved : 3; } Bits; UINT8 Uint8; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_CAPABILITY; typedef union { struct { UINT8 LaneNumber : 5; UINT8 RcvErrorCounterSelect : 2; UINT8 LaneMarginStepSelect : 1; } Bits; UINT8 Uint8; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_CONTROL; typedef union { struct { UINT8 MaxLanesReceivingTestPattern : 5; UINT8 Reserved : 3; } Bits; UINT8 Uint8; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_STATUS; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_CAPABILITY Capability; PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_CONTROL Control; PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_STATUS Status; UINT32 ErrorCounter; } PCI_EXPRESS_EXTENDED_CAPABILITIES_LANE_MARGINING_AT_RECEIVER; ///@} /// Page Request Interface Extended Capability Structure /// /// Based on section 10.5.2 of PCI Express Base Specification 4.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_PRI_ID 0x0013 #define PCI_EXPRESS_EXTENDED_CAPABILITY_PRI_VER1 0x1 typedef union { struct { UINT32 PriRequestCapable : 1; UINT32 PriCompletionCapable : 1; UINT32 Page256RequestCapable : 1; UINT32 Page512RequestCapable : 1; UINT32 Page1KRequestCapable : 1; UINT32 Page2KRequestCapable : 1; UINT32 Page4KRequestCapable : 1; UINT32 Page8KRequestCapable : 1; UINT32 Reserved : 24; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_CAPABILITY; typedef union { struct { UINT32 PriEnable : 1; UINT32 PriReset : 1; UINT32 Reserved : 30; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_CONTROL; typedef union { struct { UINT32 OutstandingPageRequest : 1; UINT32 ResponseFailure : 1; UINT32 Stopped : 1; UINT32 PpRqIdParity : 1; UINT32 Reserved : 28; } Bits; UINT32 Uint32; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_STATUS; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_CAPABILITY Capability; PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_CONTROL Control; PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI_STATUS Status; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PRI; ///@} #pragma pack() #endif ================================================ FILE: src/edk2/PciExpress50.h ================================================ /** @file Support for the PCI Express 5.0 standard. This header file may not define all structures. Please extend as required. Copyright (c) 2020, American Megatrends International LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PCIEXPRESS50_H_ #define _PCIEXPRESS50_H_ #include "PciExpress40.h" #pragma pack(1) /// The Physical Layer PCI Express Extended Capability definitions. /// /// Based on section 7.7.6 of PCI Express Base Specification 5.0. ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_32_0_ID 0x002A #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_32_0_VER1 0x1 // Register offsets from Physical Layer PCI-E Ext Cap Header #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CAPABILITIES_OFFSET 0x04 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CONTROL_OFFSET 0x08 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_STATUS_OFFSET 0x0C #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA1_OFFSET 0x10 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA2_OFFSET 0x14 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA1_OFFSET 0x18 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA2_OFFSET 0x1C #define PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_LANE_EQUALIZATION_CONTROL_OFFSET 0x20 typedef union { struct { UINT32 EqualizationByPassToHighestRateSupport : 1; // bit 0 UINT32 NoEqualizationNeededSupport : 1; // bit 1 UINT32 Reserved1 : 6; // Reserved bit 2:7 UINT32 ModifiedTSUsageMode0Support : 1; // bit 8 UINT32 ModifiedTSUsageMode1Support : 1; // bit 9 UINT32 ModifiedTSUsageMode2Support : 1; // bit 10 UINT32 ModifiedTSReservedUsageModes : 5; // bit 11:15 UINT32 Reserved2 : 16; // Reserved bit 16:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CAPABILITIES; typedef union { struct { UINT32 EqualizationByPassToHighestRateDisable : 1; // bit 0 UINT32 NoEqualizationNeededDisable : 1; // bit 1 UINT32 Reserved1 : 6; // Reserved bit 2:7 UINT32 ModifiedTSUsageModeSelected : 3; // bit 8:10 UINT32 Reserved2 : 21; // Reserved bit 11:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CONTROL; typedef union { struct { UINT32 EqualizationComplete : 1; // bit 0 UINT32 EqualizationPhase1Success : 1; // bit 1 UINT32 EqualizationPhase2Success : 1; // bit 2 UINT32 EqualizationPhase3Success : 1; // bit 3 UINT32 LinkEqualizationRequest : 1; // bit 4 UINT32 ModifiedTSRcvd : 1; // bit 5 UINT32 RcvdEnhancedLinkControl : 2; // bit 6:7 UINT32 TransmitterPrecodingOn : 1; // bit 8 UINT32 TransmitterPrecodeRequest : 1; // bit 9 UINT32 NoEqualizationNeededRcvd : 1; // bit 10 UINT32 Reserved : 21; // Reserved bit 11:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_STATUS; typedef union { struct { UINT32 RcvdModifiedTSUsageMode : 3; // bit 0:2 UINT32 RcvdModifiedTSUsageInfo1 : 13; // bit 3:15 UINT32 RcvdModifiedTSVendorId : 16; // bit 16:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA1; typedef union { struct { UINT32 RcvdModifiedTSUsageInfo2 : 24; // bit 0:23 UINT32 AltProtocolNegotiationStatus : 2; // bit 24:25 UINT32 Reserved : 6; // Reserved bit 26:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA2; typedef union { struct { UINT32 TransModifiedTSUsageMode : 3; // bit 0:2 UINT32 TransModifiedTSUsageInfo1 : 13; // bit 3:15 UINT32 TransModifiedTSVendorId : 16; // bit 16:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA1; typedef union { struct { UINT32 TransModifiedTSUsageInfo2 : 24; // bit 0:23 UINT32 AltProtocolNegotiationStatus : 2; // bit 24:25 UINT32 Reserved : 6; // Reserved bit 26:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA2; typedef union { struct { UINT8 DownstreamPortTransmitterPreset : 4; // bit 0..3 UINT8 UpstreamPortTransmitterPreset : 4; // bit 4..7 } Bits; UINT8 Uint8; } PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_LANE_EQUALIZATION_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CAPABILITIES Capablities; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_CONTROL Control; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_STATUS Status; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA1 RcvdModifiedTs1Data; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_RCVD_MODIFIED_TS_DATA2 RcvdModifiedTs2Data; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA1 TransModifiedTs1Data; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_TRANS_MODIFIED_TS_DATA2 TransModifiedTs2Data; PCI_EXPRESS_REG_PHYSICAL_LAYER_32_0_LANE_EQUALIZATION_CONTROL LaneEqualizationControl[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PHYSICAL_LAYER_32_0; ///@} /// Alternate Protocol Negotiation Extended Capability Structure /// /// Based on section 7.9.21 of PCI Express Base Specification 5.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_ALTERNATE_PROTOCOL_ID 0x002B #define PCI_EXPRESS_EXTENDED_CAPABILITY_ALTERNATE_PROTOCOL_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 AltProtocolCapability; UINT32 AltProtocolStatus; UINT32 AltProtocolControl; } PCI_EXPRESS_EXTENDED_CAPABILITIES_ALTERNATE_PROTOCOL; ///@} #pragma pack() #endif ================================================ FILE: src/edk2/PciExpress60.h ================================================ /** @file Support for the PCI Express 6.0 standard. This header file may not define all structures. Please extend as required. Copyright (c) 2024, American Megatrends International LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef PCIEXPRESS60_H_ #define PCIEXPRESS60_H_ #include "PciExpress50.h" /// The Physical Layer PCI Express Extended Capability definitions. /// /// Based on section 7.7.7 of PCI Express Base Specification 6.0. ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_ID 0x0031 #define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_VER1 0x1 // Register offsets from Physical Layer PCI-E Ext Cap Header #define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES_OFFSET 0x04 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL_OFFSET 0x08 #define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS_OFFSET 0x0C #define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL_OFFSET 0x10 #define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_ID 0x002F #define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_VER1 0x1 #define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_3_OFFSET 0x04 #define EFI_PCIE_CAPABILITY_DEVICE_CONTROL_3_OFFSET 0x08 #define EFI_PCIE_CAPABILITY_DEVICE_STATUS_3_OFFSET 0x0C #pragma pack(1) typedef union { struct { UINT32 Reserved : 32; // Reserved bit 0:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES; typedef union { struct { UINT32 Reserved : 32; // Reserved bit 0:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL; typedef union { struct { UINT32 EqualizationComplete : 1; // bit 0 UINT32 EqualizationPhase1Success : 1; // bit 1 UINT32 EqualizationPhase2Success : 1; // bit 2 UINT32 EqualizationPhase3Success : 1; // bit 3 UINT32 LinkEqualizationRequest : 1; // bit 4 UINT32 TransmitterPrecodingOn : 1; // bit 5 UINT32 TransmitterPrecodeRequest : 1; // bit 6 UINT32 NoEqualizationNeededRcvd : 1; // bit 7 UINT32 Reserved : 24; // Reserved bit 8:31 } Bits; UINT32 Uint32; } PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS; typedef union { struct { UINT8 DownstreamPortTransmitterPreset : 4; // bit 0..3 UINT8 UpstreamPortTransmitterPreset : 4; // bit 4..7 } Bits; UINT8 Uint8; } PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES Capablities; PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL Control; PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS Status; PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL LaneEqualizationControl[1]; } PCI_EXPRESS_EXTENDED_CAPABILITIES_PHYSICAL_LAYER_64_0; ///@} typedef union { struct { UINT32 DmwrRequestRouting : 1; // bit 0 UINT32 FourteenBitTagCompleter : 1; // bit 1 UINT32 FourteenBitTagRequester : 1; // bit 2 UINT32 ReceiverL0p : 1; // bit 3 UINT32 PortL0pExitLatencyLatency : 3; // bit 4..6 UINT32 RetimerL0pExit : 3; // bit 7..9 UINT32 Reserved : 22; // bit 10..31 } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_CAPABILITY3; typedef union { struct { UINT32 DmwrRequesterEnable : 1; // bit 0 UINT32 DmwrEgressBlocking : 1; // bit 1 UINT32 FourteenBitTagRequesterEnable : 1; // bit 2 UINT32 L0pEnable : 1; // bit 3 UINT32 TargetLinkWidth : 3; // bit 4..6 UINT32 Reserved : 25; // bit 7..31 } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_CONTROL3; typedef union { struct { UINT32 InitialLinkWidth : 3; // bit 0..2 UINT32 SegmentCaptured : 1; // bit 3 UINT32 RemoteL0pSupported : 1; // bit 4 UINT32 Reserved : 27; // bit 5..31 } Bits; UINT32 Uint32; } PCI_REG_PCIE_DEVICE_STATUS3; typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; PCI_REG_PCIE_DEVICE_CAPABILITY3 Capabilities; PCI_REG_PCIE_DEVICE_CONTROL3 Control; PCI_REG_PCIE_DEVICE_STATUS3 Status; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DEVICE3; /// Flit Logging Extended Capability Structure /// /// Based on section 7.7.8 of PCI Express Base Specification 6.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_FLIT_LOGGING_ID 0x0032 #define PCI_EXPRESS_EXTENDED_CAPABILITY_FLIT_LOGGING_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 FlitLoggingCapabilities; UINT32 FlitLoggingControl; UINT32 FlitLoggingStatus; UINT32 FlitMask; UINT32 FlitErrorData1; UINT32 FlitErrorData2; UINT32 FlitErrorData3; } PCI_EXPRESS_EXTENDED_CAPABILITIES_FLIT_LOGGING; ///@} /// Data Object Exchange Extended Capability Structure /// /// Based on section 7.9.24 of PCI Express Base Specification 6.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_DATA_OBJECT_EXCHANGE_ID 0x002E #define PCI_EXPRESS_EXTENDED_CAPABILITY_DATA_OBJECT_EXCHANGE_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 DoeCapabilities; UINT16 DoeControl; UINT16 DoeStatus; UINT32 UncorrectableErrorMask; UINT32 UncorrectableErrorSeverity; UINT32 CorrectableErrorMask; UINT32 DoeSendObjectControl; } PCI_EXPRESS_EXTENDED_CAPABILITIES_DATA_OBJECT_EXCHANGE; ///@} /// Integrity Data Encryption Extended Capability Structure /// /// Based on section 7.9.26 of PCI Express Base Specification 6.0 ///@{ #define PCI_EXPRESS_EXTENDED_CAPABILITY_INTEGRITY_DATA_ENCRYPTION_ID 0x0030 #define PCI_EXPRESS_EXTENDED_CAPABILITY_INTEGRITY_DATA_ENCRYPTION_VER1 0x1 typedef struct { PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header; UINT32 IdeCapabilities; UINT32 IdeControl; UINT32 IdeStatus; UINT32 IdeSendMcCapabilities; UINT32 IdeSendMcControl; UINT32 IdeSendMcStatus; } PCI_EXPRESS_EXTENDED_CAPABILITIES_INTEGRITY_DATA_ENCRYPTION; ///@} #pragma pack() #endif ================================================ FILE: src/intel_workarounds.c ================================================ #include #include "csmwrap.h" #include "io.h" #define PCI_DEVICE_NUMBER_PCH_P2SB 31 #define PCI_FUNCTION_NUMBER_PCH_P2SB 1 #define SBREG_BAR 0x10 #define SBREG_BARH 0x14 /* PCH sideband parameters vary by CPU generation - detected via CPUID */ struct pch_info { uintptr_t sbreg_bar; uint8_t pid_itss; }; /* Intel CPU model numbers (Family 6) */ #define INTEL_SKYLAKE_L 0x4E #define INTEL_SKYLAKE 0x5E #define INTEL_SKYLAKE_X 0x55 #define INTEL_KABYLAKE_L 0x8E #define INTEL_KABYLAKE 0x9E #define INTEL_COMETLAKE 0xA5 #define INTEL_COMETLAKE_L 0xA6 #define INTEL_ICELAKE_L 0x7E #define INTEL_TIGERLAKE_L 0x8C #define INTEL_TIGERLAKE 0x8D #define INTEL_ALDERLAKE 0x97 #define INTEL_ALDERLAKE_L 0x9A #define INTEL_RAPTORLAKE 0xB7 #define INTEL_RAPTORLAKE_P 0xBA #define INTEL_RAPTORLAKE_S 0xBF #define INTEL_METEORLAKE 0xAC #define INTEL_METEORLAKE_L 0xAA #define INTEL_ARROWLAKE 0xC6 #define INTEL_ARROWLAKE_H 0xC5 #define INTEL_ARROWLAKE_U 0xB5 #define INTEL_LUNARLAKE 0xBD #define INTEL_PANTHERLAKE_L 0xCC static bool get_pch_info(struct pch_info *info) { uint32_t eax, ebx, ecx, edx; asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1), "c"(0)); uint8_t family = (eax >> 8) & 0xF; uint8_t model = (eax >> 4) & 0xF; if (family == 6 || family == 15) model |= ((eax >> 16) & 0xF) << 4; if (family != 6) return false; switch (model) { /* Meteor Lake / Arrow Lake / Panther Lake: SBREG=0xE0000000 */ case INTEL_METEORLAKE: case INTEL_METEORLAKE_L: case INTEL_ARROWLAKE: case INTEL_ARROWLAKE_H: case INTEL_ARROWLAKE_U: case INTEL_LUNARLAKE: info->sbreg_bar = 0xE0000000; info->pid_itss = 0xCA; return true; case INTEL_PANTHERLAKE_L: info->sbreg_bar = 0xE0000000; info->pid_itss = 0x69; return true; /* Alder Lake / Raptor Lake Desktop (S-series, PCH-S): SBREG=0xE0000000 */ case INTEL_ALDERLAKE: case INTEL_RAPTORLAKE: case INTEL_RAPTORLAKE_S: info->sbreg_bar = 0xE0000000; info->pid_itss = 0xC4; return true; /* Alder Lake / Raptor Lake Mobile (P-series, PCH-P): SBREG=0xFD000000 */ case INTEL_ALDERLAKE_L: case INTEL_RAPTORLAKE_P: info->sbreg_bar = 0xFD000000; info->pid_itss = 0xC4; return true; /* Skylake through Tiger Lake: SBREG=0xFD000000 */ case INTEL_SKYLAKE_L: case INTEL_SKYLAKE: case INTEL_SKYLAKE_X: case INTEL_KABYLAKE_L: case INTEL_KABYLAKE: case INTEL_COMETLAKE: case INTEL_COMETLAKE_L: case INTEL_ICELAKE_L: case INTEL_TIGERLAKE_L: case INTEL_TIGERLAKE: info->sbreg_bar = 0xFD000000; info->pid_itss = 0xC4; return true; default: return false; } } #define R_PCH_PCR_ITSS_ITSSPRC 0x3300 #define B_PCH_PCR_ITSS_ITSSPRC_8254CGE (1 << 2) #define PCH_PCR_ADDRESS(Base, Pid, Offset) ((void *)(Base | (UINT32) (((Offset) & 0x0F0000) << 8) | ((UINT8)(Pid) << 16) | (UINT16) ((Offset) & 0xFFFF))) #define R_P2SB_CFG_P2SBC 0xE0 #define B_P2SB_CFG_P2SBC_HIDE (1 << 8) static int pit_8254cge_workaround(void) { struct pch_info pch; uint32_t reg; uintptr_t base; bool p2sb_hide = false; int pch_pci_bus = 0; if (!get_pch_info(&pch)) { printf("Unknown CPU model, skipping PIT workaround\n"); return 0; } reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, 0x0); /* P2SB maybe hidden, try unhide it first */ if ((reg & 0xFFFF) == 0xffff) { reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC); reg &= ~B_P2SB_CFG_P2SBC_HIDE; pciConfigWriteDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC, reg); p2sb_hide = true; } reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, 0x0); if ((reg & 0xFFFF) != 0x8086) { /* P2SB locked hidden - use CPUID-determined SBREG_BAR */ base = pch.sbreg_bar; } else { reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, SBREG_BAR); base = reg & ~0x0F; reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, SBREG_BARH); #ifdef __LP64__ base |= ((uint64_t)reg & 0xFFFFFFFF) << 32; #else if (reg) { printf("Invalid P2SB BARH\n"); goto hide_and_return; } #endif /* Hide P2SB again */ if (p2sb_hide) { reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC); reg |= B_P2SB_CFG_P2SBC_HIDE; pciConfigWriteDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC, reg); } } reg = readl(PCH_PCR_ADDRESS(base, pch.pid_itss, R_PCH_PCR_ITSS_ITSSPRC)); printf("ITSSPRC = %x, ITSSPRC.8254CGE= %x\n", reg, !!(reg & B_PCH_PCR_ITSS_ITSSPRC_8254CGE)); /* Disable 8254CGE */ reg &= ~B_PCH_PCR_ITSS_ITSSPRC_8254CGE; writel(PCH_PCR_ADDRESS(base, pch.pid_itss, R_PCH_PCR_ITSS_ITSSPRC), reg); return 0; #ifndef __LP64__ hide_and_return: if (p2sb_hide) { reg = pciConfigReadDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC); reg |= B_P2SB_CFG_P2SBC_HIDE; pciConfigWriteDWord(pch_pci_bus, PCI_DEVICE_NUMBER_PCH_P2SB, PCI_FUNCTION_NUMBER_PCH_P2SB, R_P2SB_CFG_P2SBC, reg); } return 0; #endif } int apply_intel_platform_workarounds(void) { uint16_t vendor_id; vendor_id = pciConfigReadWord(0, 0, 0, 0x0); if (vendor_id != 0x8086) { return 0; } pit_8254cge_workaround(); return 0; } ================================================ FILE: src/io.h ================================================ #ifndef _IO_H #define _IO_H #include #include #include #define barrier() __asm__ __volatile__("": : :"memory") static inline void clflush(void *addr) { // Cache CPUID.01H:EDX[19] (CLFLUSH support) to avoid repeated CPUID calls static int has_clflush = -1; if (has_clflush == -1) { uint32_t eax, ebx, ecx, edx; asm volatile ("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1) : "memory"); has_clflush = (edx >> 19) & 1; } if (has_clflush) { asm volatile ("clflush (%0)" :: "r"(addr) : "memory"); } else { // Fall back to wbinvd (flushes entire cache, requires ring 0) asm volatile ("wbinvd" ::: "memory"); } } static inline void writel(void *addr, uint32_t val) { barrier(); *(volatile uint32_t *)addr = val; } static inline void writew(void *addr, uint16_t val) { barrier(); *(volatile uint16_t *)addr = val; } static inline void writeb(void *addr, uint8_t val) { barrier(); *(volatile uint8_t *)addr = val; } static inline uint64_t readq(const void *addr) { uint64_t val = *(volatile const uint64_t *)addr; barrier(); return val; } static inline uint32_t readl(const void *addr) { uint32_t val = *(volatile const uint32_t *)addr; barrier(); return val; } static inline uint16_t readw(const void *addr) { uint16_t val = *(volatile const uint16_t *)addr; barrier(); return val; } static inline uint8_t readb(const void *addr) { uint8_t val = *(volatile const uint8_t *)addr; barrier(); return val; } #ifdef __OPTIMIZE__ #define __use_immediate_port(port) \ (__builtin_constant_p(((int)port)) && ((int)port) < 0x100) #else #define __use_immediate_port(port) 0 #endif #define inb(port) \ (__use_immediate_port((int)port) ? __inbc((int)port) : __inb((int)port)) static inline uint8_t __inbc(int port) { uint8_t data; asm volatile("inb %w1,%0" : "=a" (data) : "id" (port) : "memory"); return data; } static inline uint8_t __inb(int port) { uint8_t data; asm volatile("inb %w1,%0" : "=a" (data) : "d" (port) : "memory"); return data; } static inline void insb(int port, void *addr, int cnt) { asm volatile("cld\n\trepne\n\tinsb" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory", "cc"); } #define inw(port) \ (__use_immediate_port((int)port) ? __inwc((int)port) : __inw((int)port)) static inline uint16_t __inwc(int port) { uint16_t data; asm volatile("inw %w1,%0" : "=a" (data) : "id" (port) : "memory"); return data; } static inline uint16_t __inw(int port) { uint16_t data; asm volatile("inw %w1,%0" : "=a" (data) : "d" (port) : "memory"); return data; } static inline void insw(int port, void *addr, int cnt) { asm volatile("cld\n\trepne\n\tinsw" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory", "cc"); } #define inl(port) \ (__use_immediate_port(port) ? __inlc((int)port) : __inl((int)port)) static inline uint32_t __inlc(int port) { uint32_t data; asm volatile("inl %w1,%0" : "=a" (data) : "id" (port) : "memory"); return data; } static inline uint32_t __inl(int port) { uint32_t data; asm volatile("inl %w1,%0" : "=a" (data) : "d" (port) : "memory"); return data; } static inline void insl(int port, void *addr, int cnt) { asm volatile("cld\n\trepne\n\tinsl" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory", "cc"); } #define outb(port, data) \ (__use_immediate_port(port) ? __outbc((int)port, data) : __outb((int)port, data)) static inline void __outbc(int port, uint8_t data) { asm volatile("outb %0,%w1" : : "a" (data), "id" (port) : "memory"); } static inline void __outb(int port, uint8_t data) { asm volatile("outb %0,%w1" : : "a" (data), "d" (port) : "memory"); } static inline void outsb(int port, const void *addr, int cnt) { asm volatile("cld\n\trepne\n\toutsb" : "+S" (addr), "+c" (cnt) : "d" (port) : "cc", "memory"); } #define outw(port, data) \ (__use_immediate_port(port) ? __outwc((int)port, data) : __outw((int)port, data)) static inline void __outwc(int port, uint16_t data) { asm volatile("outw %0,%w1" : : "a" (data), "id" (port) : "memory"); } static inline void __outw(int port, uint16_t data) { asm volatile("outw %0,%w1" : : "a" (data), "d" (port) : "memory"); } static inline void outsw(int port, const void *addr, int cnt) { asm volatile("cld\n\trepne\n\toutsw" : "+S" (addr), "+c" (cnt) : "d" (port) : "cc", "memory"); } #define outl(port, data) \ (__use_immediate_port(port) ? __outlc((int)port, data) : __outl((int)port, data)) static inline void __outlc(int port, uint32_t data) { asm volatile("outl %0,%w1" : : "a" (data), "id" (port) : "memory"); } static inline void __outl(int port, uint32_t data) { asm volatile("outl %0,%w1" : : "a" (data), "d" (port) : "memory"); } static inline void outsl(int port, const void *addr, int cnt) { asm volatile("cld\n\trepne\n\toutsl" : "+S" (addr), "+c" (cnt) : "d" (port) : "cc", "memory"); } #define PCI_CONFIG_ADDRESS 0xcf8 #define PCI_CONFIG_DATA 0xcfc static inline void pciSetAddress(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset) { uint32_t address; /* Address bits (inclusive): * 31 Enable bit (must be 1 for it to work) * 30 - 24 Reserved * 23 - 16 Bus number * 15 - 11 Slot number * 10 - 8 Function number (for multifunction devices) * 7 - 2 Register number (offset / 4) * 1 - 0 Must always be 00 */ address = 0x80000000 | ((unsigned long) (bus & 0xff) << 16) | ((unsigned long) (slot & 0x1f) << 11) | ((unsigned long) (function & 0x7) << 8) | ((unsigned long) offset & 0xfc); /* Full DWORD write to port must be used for PCI to detect new address. */ outl(PCI_CONFIG_ADDRESS, address); } static inline uint8_t pciConfigReadByte(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset) { pciSetAddress(bus, slot, function, offset); /* The PCI registers are little endian, * so the last byte of DWORD is read * when offset is 0. */ return (inb(PCI_CONFIG_DATA + (offset & 3))); } static inline uint16_t pciConfigReadWord(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset) { pciSetAddress(bus, slot, function, offset); /* The PCI registers are little endian, * so the last word of DWORD is read * when offset is 0. */ return (inw(PCI_CONFIG_DATA + (offset & 2))); } static inline uint32_t pciConfigReadDWord(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset) { pciSetAddress(bus, slot, function, offset); return (inl(PCI_CONFIG_DATA)); } static inline void pciConfigWriteByte(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset, uint8_t data) { pciSetAddress(bus, slot, function, offset); /* The PCI registers are little endian, * so the last byte of DWORD is written * when offset is 0. */ outb(PCI_CONFIG_DATA + (offset & 3), data); } static inline void pciConfigWriteWord(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset, uint16_t data) { pciSetAddress(bus, slot, function, offset); /* The PCI registers are little endian, * so the last word of DWORD is written * when offset is 0. */ outw(PCI_CONFIG_DATA + (offset & 2), data); } static inline void pciConfigWriteDWord(unsigned int bus, unsigned int slot, unsigned int function, unsigned int offset, uint32_t data) { pciSetAddress(bus, slot, function, offset); outl(PCI_CONFIG_DATA, data); } static inline uint64_t rdmsr(uint32_t index) { uint32_t edx, eax; asm volatile ("rdmsr" : "=a"(eax), "=d"(edx) : "c"(index) : "memory"); return ((uint64_t)edx << 32) | eax; } static inline void wrmsr(uint32_t index, uint64_t val) { asm volatile ("wrmsr" :: "a"((uint32_t)val), "d"((uint32_t)(val >> 32)), "c"(index) : "memory"); } static inline uint64_t rdtsc(void) { uint32_t edx, eax; asm volatile ("rdtsc" : "=a" (eax), "=d" (edx) :: "memory"); return ((uint64_t)edx << 32) | eax; } #endif ================================================ FILE: src/iommu.c ================================================ #include #include #include "csmwrap.h" #include "io.h" #include "iommu.h" #include #include /* * IOMMU Disabling for Legacy OS Handoff * * Disables Intel VT-d and AMD-Vi IOMMUs before legacy OS boot. * This is necessary because UEFI-configured IOMMU translation tables * become stale after PCI BAR relocation. */ /* * Intel VT-d DMAR Table Structures * Reference: Intel VT-d Architecture Specification */ #define ACPI_DMAR_SIGNATURE "DMAR" #define DMAR_TYPE_DRHD 0 /* DMA Remapping Hardware Unit Definition */ struct dmar_header { uint16_t type; uint16_t length; } __attribute__((packed)); struct dmar_drhd { struct dmar_header header; uint8_t flags; uint8_t reserved; uint16_t segment; uint64_t register_base; } __attribute__((packed)); /* * Intel VT-d Register Offsets */ #define VTD_GCMD_REG 0x18 #define VTD_GSTS_REG 0x1C #define VTD_GCMD_TE (1U << 31) #define VTD_GCMD_IRE (1U << 25) #define VTD_GCMD_QIE (1U << 26) #define VTD_GSTS_TES (1U << 31) #define VTD_GSTS_IRES (1U << 25) #define VTD_GSTS_QIES (1U << 26) /* * Mask to clear one-shot command bits when reading GSTS to write to GCMD. * One-shot bits (30, 29, 27, 24) trigger hardware operations when set: * - Bit 30: SRTP (Set Root Table Pointer) * - Bit 29: SFL (Set Fault Log) * - Bit 27: WBF (Write Buffer Flush) * - Bit 24: SIRTP (Set Interrupt Remap Table Pointer) * Reference: EDK2 IntelSiliconPkg/VTd and Intel VT-d Specification */ #define VTD_GSTS_ONESHOT_MASK 0x96FFFFFF /* * AMD IOMMU (AMD-Vi) IVRS Table Structures * Reference: AMD I/O Virtualization Technology (IOMMU) Specification */ #define ACPI_IVRS_SIGNATURE "IVRS" #define IVRS_TYPE_IVHD_10 0x10 #define IVRS_TYPE_IVHD_11 0x11 #define IVRS_TYPE_IVHD_40 0x40 struct acpi_ivrs { struct acpi_sdt_hdr hdr; uint32_t iv_info; uint64_t reserved; } __attribute__((packed)); struct ivrs_header { uint8_t type; uint8_t flags; uint16_t length; uint16_t device_id; uint16_t capability_offset; uint64_t iommu_base; } __attribute__((packed)); /* * AMD IOMMU Register Offsets * * The control register is 64-bit at offset 0x18, but every bit we touch lives * in the low 32 bits, so we read/write the low half only and leave the upper * half untouched. */ #define AMD_IOMMU_CTRL_REG 0x18 #define AMD_IOMMU_CTRL_EN (1ULL << 0) #define AMD_IOMMU_CTRL_EVT_LOG (1ULL << 2) #define AMD_IOMMU_CTRL_EVT_INT (1ULL << 3) #define AMD_IOMMU_CTRL_CMDBUF (1ULL << 12) #define AMD_IOMMU_CTRL_PPR_LOG (1ULL << 13) #define AMD_IOMMU_CTRL_PPR_INT (1ULL << 14) #define AMD_IOMMU_CTRL_PPR (1ULL << 15) #define AMD_IOMMU_CTRL_GA_LOG (1ULL << 28) #define AMD_IOMMU_CTRL_GA_INT (1ULL << 29) #define AMD_IOMMU_STATUS_REG 0x2020 #define AMD_IOMMU_STATUS_EVTLOG_RUN (1ULL << 3) #define AMD_IOMMU_STATUS_CMDBUF_RUN (1ULL << 4) #define AMD_IOMMU_STATUS_PPRLOG_RUN (1ULL << 7) #define AMD_IOMMU_STATUS_GALOG_RUN (1ULL << 8) /* * Disable a single Intel VT-d IOMMU unit */ static bool vtd_disable_unit(uint64_t reg_base) { void *base = (void *)(uintptr_t)reg_base; uint32_t gsts, gcmd; gsts = readl(base + VTD_GSTS_REG); printf(" VT-d unit at 0x%llx: GSTS=0x%08x (TE=%d, IRE=%d, QIE=%d)\n", reg_base, gsts, !!(gsts & VTD_GSTS_TES), !!(gsts & VTD_GSTS_IRES), !!(gsts & VTD_GSTS_QIES)); if (!(gsts & (VTD_GSTS_TES | VTD_GSTS_IRES | VTD_GSTS_QIES))) { printf(" Already fully disabled\n"); return true; } /* Disable translation (TE) */ if (gsts & VTD_GSTS_TES) { gcmd = gsts & VTD_GSTS_ONESHOT_MASK; gcmd &= ~VTD_GCMD_TE; writel(base + VTD_GCMD_REG, gcmd); while ((gsts = readl(base + VTD_GSTS_REG)) & VTD_GSTS_TES) asm volatile("pause"); printf(" Translation disabled\n"); } /* Disable interrupt remapping (IRE) */ if (gsts & VTD_GSTS_IRES) { gcmd = gsts & VTD_GSTS_ONESHOT_MASK; gcmd &= ~(VTD_GCMD_TE | VTD_GCMD_IRE); writel(base + VTD_GCMD_REG, gcmd); while ((gsts = readl(base + VTD_GSTS_REG)) & VTD_GSTS_IRES) asm volatile("pause"); printf(" Interrupt remapping disabled\n"); } /* Disable queued invalidation (QIE) - must be after TE and IRE */ if (gsts & VTD_GSTS_QIES) { gcmd = gsts & VTD_GSTS_ONESHOT_MASK; gcmd &= ~(VTD_GCMD_TE | VTD_GCMD_IRE | VTD_GCMD_QIE); writel(base + VTD_GCMD_REG, gcmd); while ((gsts = readl(base + VTD_GSTS_REG)) & VTD_GSTS_QIES) asm volatile("pause"); printf(" Queued invalidation disabled\n"); } return true; } /* * Parse DMAR table and disable all Intel VT-d IOMMUs */ static int vtd_disable_all(void) { uacpi_table tbl; uacpi_status status; struct acpi_dmar *dmar; uint8_t *ptr, *end; int disabled = 0; status = uacpi_table_find_by_signature(ACPI_DMAR_SIGNATURE, &tbl); if (status != UACPI_STATUS_OK) { return 0; /* No DMAR table, no Intel VT-d */ } dmar = (struct acpi_dmar *)tbl.hdr; printf("DMAR: found table, host_address_width=%d, flags=0x%02x\n", dmar->haw, dmar->flags); ptr = (uint8_t *)dmar + sizeof(struct acpi_dmar); end = (uint8_t *)dmar + dmar->hdr.length; while (ptr + sizeof(struct dmar_header) <= end) { struct dmar_header *hdr = (struct dmar_header *)ptr; if (hdr->length < sizeof(struct dmar_header) || ptr + hdr->length > end) { printf("DMAR: invalid structure length\n"); break; } if (hdr->type == DMAR_TYPE_DRHD) { struct dmar_drhd *drhd = (struct dmar_drhd *)ptr; printf("DMAR: DRHD segment=%d flags=0x%02x base=0x%llx\n", drhd->segment, drhd->flags, drhd->register_base); if (vtd_disable_unit(drhd->register_base)) { disabled++; } } ptr += hdr->length; } uacpi_table_unref(&tbl); return disabled; } /* * Disable a single AMD IOMMU unit */ static bool amd_iommu_disable_unit(uint64_t iommu_base) { void *base = (void *)(uintptr_t)iommu_base; uint32_t ctrl; ctrl = readl(base + AMD_IOMMU_CTRL_REG); printf(" AMD IOMMU at 0x%llx: CTRL=0x%08x (En=%d)\n", iommu_base, ctrl, !!(ctrl & AMD_IOMMU_CTRL_EN)); if (!(ctrl & AMD_IOMMU_CTRL_EN)) { printf(" IOMMU already disabled\n"); return true; } /* Disable command buffer, logs and their interrupts before clearing the * master enable. Clearing IommuEn while sub-features are still live can * leave queued descriptors and in-flight DMA in an undefined state. */ ctrl &= ~(AMD_IOMMU_CTRL_CMDBUF | AMD_IOMMU_CTRL_EVT_LOG | AMD_IOMMU_CTRL_EVT_INT | AMD_IOMMU_CTRL_GA_LOG | AMD_IOMMU_CTRL_GA_INT | AMD_IOMMU_CTRL_PPR_LOG | AMD_IOMMU_CTRL_PPR_INT | AMD_IOMMU_CTRL_PPR); writel(base + AMD_IOMMU_CTRL_REG, ctrl); /* The *Run bits are level-sensitive and only drop to 0 once the engine * has actually drained, so wait for them before continuing. */ const uint32_t run_mask = AMD_IOMMU_STATUS_CMDBUF_RUN | AMD_IOMMU_STATUS_EVTLOG_RUN | AMD_IOMMU_STATUS_PPRLOG_RUN | AMD_IOMMU_STATUS_GALOG_RUN; while (readl(base + AMD_IOMMU_STATUS_REG) & run_mask) asm volatile("pause"); ctrl &= ~AMD_IOMMU_CTRL_EN; writel(base + AMD_IOMMU_CTRL_REG, ctrl); printf(" IOMMU disabled successfully\n"); return true; } /* * Parse IVRS table and disable all AMD IOMMUs */ static int amd_iommu_disable_all(void) { uacpi_table tbl; uacpi_status status; struct acpi_ivrs *ivrs; uint8_t *ptr, *end; int disabled = 0; status = uacpi_table_find_by_signature(ACPI_IVRS_SIGNATURE, &tbl); if (status != UACPI_STATUS_OK) { return 0; /* No IVRS table, no AMD IOMMU */ } ivrs = (struct acpi_ivrs *)tbl.hdr; printf("IVRS: found table, iv_info=0x%08x\n", ivrs->iv_info); ptr = (uint8_t *)ivrs + sizeof(struct acpi_ivrs); end = (uint8_t *)ivrs + ivrs->hdr.length; while (ptr + sizeof(struct ivrs_header) <= end) { struct ivrs_header *hdr = (struct ivrs_header *)ptr; if (hdr->length < sizeof(struct ivrs_header) || ptr + hdr->length > end) { printf("IVRS: invalid block length\n"); break; } if (hdr->type == IVRS_TYPE_IVHD_10 || hdr->type == IVRS_TYPE_IVHD_11 || hdr->type == IVRS_TYPE_IVHD_40) { printf("IVRS: IVHD type=0x%02x device_id=0x%04x base=0x%llx\n", hdr->type, hdr->device_id, hdr->iommu_base); if (amd_iommu_disable_unit(hdr->iommu_base)) { disabled++; } } ptr += hdr->length; } uacpi_table_unref(&tbl); return disabled; } /* * Main entry point: disable all IOMMUs */ bool iommu_disable(void) { int vtd_count = 0; int amd_count = 0; printf("Disabling IOMMUs for legacy OS compatibility...\n"); vtd_count = vtd_disable_all(); if (vtd_count > 0) { printf("Disabled %d Intel VT-d IOMMU unit(s)\n", vtd_count); } amd_count = amd_iommu_disable_all(); if (amd_count > 0) { printf("Disabled %d AMD IOMMU unit(s)\n", amd_count); } if (vtd_count == 0 && amd_count == 0) { printf("No IOMMUs found or all already disabled\n"); return false; } return true; } ================================================ FILE: src/iommu.h ================================================ #ifndef IOMMU_H #define IOMMU_H #include /* * Disable all IOMMUs (Intel VT-d and AMD-Vi) to allow legacy OS booting. * * This is called after ExitBootServices but before CSM initialization. * UEFI may have configured IOMMU translation tables, but after PCI BAR * relocation, those tables reference stale addresses. Disabling the IOMMU * prevents DMA failures in the legacy OS. * * Returns true if IOMMUs were found and disabled, false otherwise. */ bool iommu_disable(void); #endif ================================================ FILE: src/libc.c ================================================ #include #include #include #ifdef memcpy # undef memcpy #endif void *memcpy(void *restrict dest, const void *restrict src, size_t n) { uint8_t *restrict pdest = (uint8_t *restrict)dest; const uint8_t *restrict psrc = (const uint8_t *restrict)src; for (size_t i = 0; i < n; i++) { pdest[i] = psrc[i]; } return dest; } #ifdef memset # undef memset #endif void *memset(void *s, int c, size_t n) { uint8_t *p = (uint8_t *)s; for (size_t i = 0; i < n; i++) { p[i] = (uint8_t)c; } return s; } #ifdef memmove # undef memmove #endif void *memmove(void *dest, const void *src, size_t n) { uint8_t *pdest = (uint8_t *)dest; const uint8_t *psrc = (const uint8_t *)src; if ((uintptr_t)src > (uintptr_t)dest) { for (size_t i = 0; i < n; i++) { pdest[i] = psrc[i]; } } else if ((uintptr_t)src < (uintptr_t)dest) { for (size_t i = n; i > 0; i--) { pdest[i-1] = psrc[i-1]; } } return dest; } #ifdef memcmp # undef memcmp #endif int memcmp(const void *s1, const void *s2, size_t n) { const uint8_t *p1 = (const uint8_t *)s1; const uint8_t *p2 = (const uint8_t *)s2; for (size_t i = 0; i < n; i++) { if (p1[i] != p2[i]) { return p1[i] < p2[i] ? -1 : 1; } } return 0; } ================================================ FILE: src/libc.h ================================================ #ifndef LIBC_H #define LIBC_H #include void *memcpy(void *restrict dest, const void *restrict src, size_t n); void *memset(void *s, int c, size_t n); void *memmove(void *dest, const void *src, size_t n); int memcmp(const void *s1, const void *s2, size_t n); /* Access builtin version by default. */ #define memcpy __builtin_memcpy #define memset __builtin_memset #define memmove __builtin_memmove #define memcmp __builtin_memcmp #endif ================================================ FILE: src/mptable.c ================================================ /* * MP Table Generation from ACPI * * Generates Intel MultiProcessor Specification tables from ACPI MADT * for legacy BIOS compatibility. The helper core reserved for BIOS proxy * is excluded from the generated tables. */ #include #include #include "csmwrap.h" #include "config.h" #include "mptable.h" #include "bios_proxy.h" #include "io.h" #include #include #include #include #include #include /* MP Table Signatures */ #define MPTABLE_SIGNATURE 0x5f504d5f /* "_MP_" */ #define MPCONFIG_SIGNATURE 0x504d4350 /* "PCMP" */ /* IA32_APIC_BASE physical-address bits [51:12]. */ #define APIC_BASE_ADDR_MASK 0xFFFFFFFFFFFFF000ULL /* MP Table Entry Types */ #define MPT_TYPE_CPU 0 #define MPT_TYPE_BUS 1 #define MPT_TYPE_IOAPIC 2 #define MPT_TYPE_INTSRC 3 #define MPT_TYPE_LOCAL_INT 4 /* Interrupt types for mpt_intsrc.irqtype */ #define MP_INT_TYPE_INT 0 /* Vectored interrupt */ #define MP_INT_TYPE_NMI 1 /* Non-maskable interrupt */ #define MP_INT_TYPE_SMI 2 /* System management interrupt */ #define MP_INT_TYPE_EXTINT 3 /* External interrupt (8259) */ /* Interrupt flags (polarity and trigger mode) */ #define MP_IRQFLAG_CONFORM 0x0000 /* Conforms to bus specification */ #define MP_IRQFLAG_ACTIVE_HIGH 0x0001 /* Active high polarity */ #define MP_IRQFLAG_ACTIVE_LOW 0x0003 /* Active low polarity */ #define MP_IRQFLAG_EDGE 0x0004 /* Edge triggered */ #define MP_IRQFLAG_LEVEL 0x000C /* Level triggered */ /* Maximum entries */ #define MAX_CPUS 256 #define MAX_IOAPICS 8 #define MAX_OVERRIDES 24 #define MAX_BUS_ENTRIES 256 #define MAX_PCI_BUSES 32 /* Discovered PCI bus information */ struct pci_bus_info { uacpi_namespace_node *node; /* ACPI namespace node for the bus/bridge */ uint8_t bus_num; /* PCI bus number (from _BBN or _ADR) */ uint8_t mp_bus_id; /* MP table bus ID (assigned sequentially) */ bool is_secondary; /* True if this is a secondary bus behind a bridge */ }; static struct { struct pci_bus_info buses[MAX_PCI_BUSES]; size_t count; } discovered_pci_buses; /* Forward declaration for recursive walk */ static void discover_secondary_buses(uacpi_namespace_node *parent, uint8_t parent_bus); /* Check if a PCI device exists by reading vendor ID via legacy PIO */ static bool pci_device_exists(uint8_t bus, uint8_t dev, uint8_t func) { uint32_t addr = 0x80000000 | (bus << 16) | (dev << 11) | (func << 8); outl(0xCF8, addr); uint16_t vendor = inw(0xCFC); return vendor != 0xFFFF; } #pragma pack(1) struct mptable_floating { uint32_t signature; /* "_MP_" */ uint32_t physaddr; /* Physical address of MP config table */ uint8_t length; /* Length in 16-byte units (1) */ uint8_t spec_rev; /* MP spec revision (4 = 1.4) */ uint8_t checksum; /* Checksum */ uint8_t feature1; /* Feature byte 1 (0 = config table present) */ uint8_t feature2; /* Feature byte 2 */ uint8_t reserved[3]; }; struct mptable_config { uint32_t signature; /* "PCMP" */ uint16_t length; /* Base table length */ uint8_t spec; /* MP spec revision */ uint8_t checksum; /* Checksum */ char oemid[8]; /* OEM ID */ char productid[12]; /* Product ID */ uint32_t oemptr; /* OEM table pointer */ uint16_t oemsize; /* OEM table size */ uint16_t entrycount; /* Number of entries */ uint32_t lapic; /* Local APIC address */ uint16_t exttable_length; uint8_t exttable_checksum; uint8_t reserved; }; struct mpt_cpu { uint8_t type; /* MPT_TYPE_CPU (0) */ uint8_t apicid; /* Local APIC ID */ uint8_t apicver; /* Local APIC version */ uint8_t cpuflag; /* CPU flags: bit 0=enabled, bit 1=BSP */ uint32_t cpusignature; /* CPU signature (from CPUID) */ uint32_t featureflag; /* CPU feature flags (from CPUID) */ uint32_t reserved[2]; }; struct mpt_bus { uint8_t type; /* MPT_TYPE_BUS (1) */ uint8_t busid; /* Bus ID */ char bustype[6]; /* Bus type string: "PCI " or "ISA " */ }; struct mpt_ioapic { uint8_t type; /* MPT_TYPE_IOAPIC (2) */ uint8_t apicid; /* I/O APIC ID */ uint8_t apicver; /* I/O APIC version */ uint8_t flags; /* Flags: bit 0=enabled */ uint32_t apicaddr; /* I/O APIC base address */ }; struct mpt_intsrc { uint8_t type; /* MPT_TYPE_INTSRC (3) or MPT_TYPE_LOCAL_INT (4) */ uint8_t irqtype; /* Interrupt type */ uint16_t irqflag; /* Polarity and trigger mode */ uint8_t srcbus; /* Source bus ID */ uint8_t srcbusirq; /* Source bus IRQ */ uint8_t dstapic; /* Destination I/O APIC ID */ uint8_t dstirq; /* Destination I/O APIC input */ }; #pragma pack() /* Forward declaration */ static uint8_t get_ioapic_input_count(uint32_t ioapic_addr); /* Parsed MADT data */ struct madt_data { struct { uint32_t apic_id; uint8_t enabled; uint8_t is_bsp; } cpus[MAX_CPUS]; size_t cpu_count; struct { uint8_t id; uint32_t address; uint32_t gsi_base; uint8_t input_count; /* Number of interrupt inputs (from hardware) */ } ioapics[MAX_IOAPICS]; size_t ioapic_count; struct { uint8_t source_irq; uint32_t gsi; uint16_t flags; } overrides[MAX_OVERRIDES]; size_t override_count; /* Local APIC NMI - we assume all CPUs use the same LINT for NMI */ uint8_t nmi_lint; /* Which LINT pin receives NMI (0 or 1) */ uint16_t nmi_flags; uint8_t has_nmi_info; }; /* Compute checksum (sum of all bytes must be 0) */ static uint8_t compute_checksum(void *data, size_t len) { uint8_t sum = 0; uint8_t *p = (uint8_t *)data; for (size_t i = 0; i < len; i++) { sum += p[i]; } return sum; } /* Read BSP APIC ID from the running CPU's LAPIC ID register. */ static uint32_t get_bsp_apic_id(void) { uint64_t apic_base = rdmsr(0x1b); if (apic_base & (1 << 10)) return (uint32_t)rdmsr(0x802); /* x2APIC: IA32_X2APIC_APICID */ uintptr_t lapic_addr = (uintptr_t)(apic_base & APIC_BASE_ADDR_MASK); volatile uint32_t *id_reg = (volatile uint32_t *)(lapic_addr + 0x20); return (*id_reg) >> 24; } /* Get CPU signature and features from CPUID */ static void get_cpu_info(uint32_t *signature, uint32_t *features) { uint32_t eax, ebx, ecx, edx; __asm__ volatile ("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); *signature = eax; *features = edx; } /* Get Local APIC version */ static uint8_t get_lapic_version(void) { uint64_t apic_base = rdmsr(0x1b); if (apic_base & (1 << 10)) /* x2APIC mode: use MSR 0x803 */ return rdmsr(0x803) & 0xFF; uintptr_t lapic_addr = (uintptr_t)(apic_base & APIC_BASE_ADDR_MASK); volatile uint32_t *ver_reg = (volatile uint32_t *)(lapic_addr + 0x30); return (*ver_reg) & 0xFF; } /* Convert ACPI MADT flags to MP table flags */ static uint16_t madt_flags_to_mp(uint16_t madt_flags) { uint16_t mp_flags = 0; /* Polarity */ switch (madt_flags & ACPI_MADT_POLARITY_MASK) { case ACPI_MADT_POLARITY_ACTIVE_HIGH: mp_flags |= MP_IRQFLAG_ACTIVE_HIGH; break; case ACPI_MADT_POLARITY_ACTIVE_LOW: mp_flags |= MP_IRQFLAG_ACTIVE_LOW; break; default: /* Conforming - use bus default */ mp_flags |= MP_IRQFLAG_CONFORM; break; } /* Trigger mode */ switch (madt_flags & ACPI_MADT_TRIGGERING_MASK) { case ACPI_MADT_TRIGGERING_EDGE: mp_flags |= MP_IRQFLAG_EDGE; break; case ACPI_MADT_TRIGGERING_LEVEL: mp_flags |= MP_IRQFLAG_LEVEL; break; default: /* Conforming - use bus default */ break; } return mp_flags; } /* Parse MADT and extract relevant information */ static bool parse_madt(struct madt_data *data, int helper_apic_id) { struct uacpi_table madt_table; memset(data, 0, sizeof(*data)); data->nmi_lint = 1; /* Default: LINT1 for NMI */ if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK) { printf("mptable: MADT not found\n"); return false; } struct acpi_madt *madt = (struct acpi_madt *)madt_table.virt_addr; uint8_t *entry = (uint8_t *)(madt + 1); uint8_t *end = (uint8_t *)madt + madt->hdr.length; uint32_t bsp_id = get_bsp_apic_id(); while (entry < end) { struct acpi_entry_hdr *hdr = (struct acpi_entry_hdr *)entry; if (hdr->length < 2) break; switch (hdr->type) { case ACPI_MADT_ENTRY_TYPE_LAPIC: { struct acpi_madt_lapic *lapic = (struct acpi_madt_lapic *)entry; /* Skip helper core */ if ((int)lapic->id == helper_apic_id) { entry += hdr->length; continue; } /* Apply user allow/block list (BSP is always kept) */ if (lapic->id != bsp_id && !config_cpu_in_filter(lapic->id)) { entry += hdr->length; continue; } if (data->cpu_count < MAX_CPUS && (lapic->flags & ACPI_PIC_ENABLED)) { data->cpus[data->cpu_count].apic_id = lapic->id; data->cpus[data->cpu_count].enabled = 1; data->cpus[data->cpu_count].is_bsp = (lapic->id == bsp_id) ? 1 : 0; data->cpu_count++; } break; } case ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC: { struct acpi_madt_x2apic *x2apic = (struct acpi_madt_x2apic *)entry; /* Skip helper core */ if ((int)x2apic->id == helper_apic_id) { entry += hdr->length; continue; } /* MP table only supports 8-bit APIC IDs */ if (x2apic->id > 255) { entry += hdr->length; continue; } /* Apply user allow/block list (BSP is always kept) */ if (x2apic->id != bsp_id && !config_cpu_in_filter(x2apic->id)) { entry += hdr->length; continue; } if (data->cpu_count < MAX_CPUS && (x2apic->flags & ACPI_PIC_ENABLED)) { data->cpus[data->cpu_count].apic_id = x2apic->id; data->cpus[data->cpu_count].enabled = 1; data->cpus[data->cpu_count].is_bsp = (x2apic->id == bsp_id) ? 1 : 0; data->cpu_count++; } break; } case ACPI_MADT_ENTRY_TYPE_IOAPIC: { struct acpi_madt_ioapic *ioapic = (struct acpi_madt_ioapic *)entry; if (data->ioapic_count < MAX_IOAPICS) { data->ioapics[data->ioapic_count].id = ioapic->id; data->ioapics[data->ioapic_count].address = ioapic->address; data->ioapics[data->ioapic_count].gsi_base = ioapic->gsi_base; /* Read actual input count from hardware */ data->ioapics[data->ioapic_count].input_count = get_ioapic_input_count(ioapic->address); data->ioapic_count++; } break; } case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: { struct acpi_madt_interrupt_source_override *iso = (struct acpi_madt_interrupt_source_override *)entry; if (data->override_count < MAX_OVERRIDES) { data->overrides[data->override_count].source_irq = iso->source; data->overrides[data->override_count].gsi = iso->gsi; data->overrides[data->override_count].flags = iso->flags; data->override_count++; } break; } case ACPI_MADT_ENTRY_TYPE_LAPIC_NMI: { struct acpi_madt_lapic_nmi *nmi = (struct acpi_madt_lapic_nmi *)entry; /* Use the first NMI entry we find (usually applies to all CPUs) */ if (!data->has_nmi_info) { data->nmi_lint = nmi->lint & 1; data->nmi_flags = nmi->flags; data->has_nmi_info = 1; } break; } default: break; } entry += hdr->length; } uacpi_table_unref(&madt_table); /* Compute total GSI count */ uint32_t total_gsis = 0; for (size_t i = 0; i < data->ioapic_count; i++) { total_gsis += data->ioapics[i].input_count; } printf("mptable: %zu CPUs, %zu I/O APIC(s) (%u GSIs), %zu overrides\n", data->cpu_count, data->ioapic_count, total_gsis, data->override_count); return data->cpu_count > 0 && data->ioapic_count > 0; } /* Find which I/O APIC handles a given GSI */ static int find_ioapic_for_gsi(struct madt_data *data, uint32_t gsi, uint8_t *dstirq) { for (size_t i = 0; i < data->ioapic_count; i++) { /* Use actual input count read from hardware */ if (gsi >= data->ioapics[i].gsi_base && gsi < data->ioapics[i].gsi_base + data->ioapics[i].input_count) { *dstirq = gsi - data->ioapics[i].gsi_base; return data->ioapics[i].id; } } return -1; } /* Read I/O APIC register */ static uint32_t ioapic_read(uint32_t ioapic_addr, uint8_t reg) { volatile uint32_t *ioregsel = (volatile uint32_t *)(uintptr_t)ioapic_addr; volatile uint32_t *iowin = (volatile uint32_t *)(uintptr_t)(ioapic_addr + 0x10); *ioregsel = reg; return *iowin; } /* Get I/O APIC version from its registers */ static uint8_t get_ioapic_version(uint32_t ioapic_addr) { return ioapic_read(ioapic_addr, 0x01) & 0xFF; } /* Get I/O APIC input count from its registers */ static uint8_t get_ioapic_input_count(uint32_t ioapic_addr) { /* IOAPICVER register (0x01): bits [23:16] = max redirection entry */ uint32_t ver = ioapic_read(ioapic_addr, 0x01); uint8_t max_redir = (ver >> 16) & 0xFF; return max_redir + 1; /* Input count = max redirection entry + 1 */ } /* Context for IRQ resource iteration */ struct irq_find_ctx { int32_t gsi; /* Output: found GSI, or -1 if not found */ uint16_t flags; /* Output: ACPI interrupt flags */ }; /* Convert uACPI resource flags to ACPI MADT interrupt flags format */ static uint16_t uacpi_flags_to_madt(uint8_t triggering, uint8_t polarity) { uint16_t flags = 0; flags |= polarity ? ACPI_MADT_POLARITY_ACTIVE_LOW : ACPI_MADT_POLARITY_ACTIVE_HIGH; flags |= triggering ? ACPI_MADT_TRIGGERING_EDGE : ACPI_MADT_TRIGGERING_LEVEL; return flags; } /* Callback to find IRQ in resource list */ static uacpi_iteration_decision find_irq_callback(void *user, uacpi_resource *resource) { struct irq_find_ctx *ctx = (struct irq_find_ctx *)user; if (resource->type == UACPI_RESOURCE_TYPE_IRQ) { if (resource->irq.num_irqs > 0) { ctx->gsi = resource->irq.irqs[0]; ctx->flags = uacpi_flags_to_madt(resource->irq.triggering, resource->irq.polarity); return UACPI_ITERATION_DECISION_BREAK; } } else if (resource->type == UACPI_RESOURCE_TYPE_EXTENDED_IRQ) { if (resource->extended_irq.num_irqs > 0) { ctx->gsi = resource->extended_irq.irqs[0]; ctx->flags = uacpi_flags_to_madt(resource->extended_irq.triggering, resource->extended_irq.polarity); return UACPI_ITERATION_DECISION_BREAK; } } return UACPI_ITERATION_DECISION_CONTINUE; } /* Get GSI from a PCI interrupt link device by evaluating _CRS */ static int32_t get_link_device_gsi(uacpi_namespace_node *link, uint16_t *out_flags) { struct irq_find_ctx ctx = { .gsi = -1, .flags = 0 }; uacpi_status status = uacpi_for_each_device_resource( link, "_CRS", find_irq_callback, &ctx); if (status != UACPI_STATUS_OK && status != UACPI_STATUS_NOT_FOUND) { return -1; } if (out_flags && ctx.gsi >= 0) { *out_flags = ctx.flags; } return ctx.gsi; } /* Callback for discovering PCI root bridges */ static uacpi_iteration_decision discover_pci_bus_callback( void *user, uacpi_namespace_node *node, uacpi_u32 depth) { (void)user; (void)depth; if (discovered_pci_buses.count >= MAX_PCI_BUSES) { printf("mptable: too many PCI buses, skipping additional bridges\n"); return UACPI_ITERATION_DECISION_CONTINUE; } /* Get bus number from _BBN (Base Bus Number), defaults to 0 if not present */ uacpi_u64 bus_num = 0; uacpi_eval_integer(node, "_BBN", UACPI_NULL, &bus_num); /* Check if we already have this bus number (some systems have duplicate entries) */ for (size_t i = 0; i < discovered_pci_buses.count; i++) { if (discovered_pci_buses.buses[i].bus_num == (uint8_t)bus_num) { return UACPI_ITERATION_DECISION_CONTINUE; } } discovered_pci_buses.buses[discovered_pci_buses.count].node = node; discovered_pci_buses.buses[discovered_pci_buses.count].bus_num = (uint8_t)bus_num; /* mp_bus_id will be assigned later when creating bus entries */ discovered_pci_buses.count++; return UACPI_ITERATION_DECISION_CONTINUE; } /* Callback for finding secondary buses with _PRT under a bridge */ static uacpi_iteration_decision discover_secondary_callback( void *user, uacpi_namespace_node *node, uacpi_u32 node_depth) { (void)node_depth; uint8_t parent_bus = *(uint8_t *)user; if (discovered_pci_buses.count >= MAX_PCI_BUSES) { return UACPI_ITERATION_DECISION_CONTINUE; } /* Check if this node has a _PRT method (indicates it routes interrupts for a bus) */ uacpi_namespace_node *prt_node = UACPI_NULL; uacpi_status st = uacpi_namespace_node_find(node, "_PRT", &prt_node); if (st != UACPI_STATUS_OK || !prt_node) { return UACPI_ITERATION_DECISION_CONTINUE; } /* Get _ADR to check if this is a PCI device */ uacpi_u64 adr = 0; if (uacpi_eval_integer(node, "_ADR", UACPI_NULL, &adr) != UACPI_STATUS_OK) { return UACPI_ITERATION_DECISION_CONTINUE; } /* _ADR format: high word = device, low word = function */ uint8_t dev = (adr >> 16) & 0x1F; uint8_t func = adr & 0x7; /* Verify device actually exists in PCI config space */ if (!pci_device_exists(parent_bus, dev, func)) { return UACPI_ITERATION_DECISION_CONTINUE; } /* This is a PCI bridge with its own _PRT - add as secondary bus */ discovered_pci_buses.buses[discovered_pci_buses.count].node = node; /* Secondary bus number isn't directly available, but we can use a placeholder * since what matters for interrupt routing is the MP bus ID mapping */ discovered_pci_buses.buses[discovered_pci_buses.count].bus_num = 0xFF; /* Unknown */ discovered_pci_buses.buses[discovered_pci_buses.count].is_secondary = true; discovered_pci_buses.count++; return UACPI_ITERATION_DECISION_CONTINUE; } /* Walk namespace under a root bridge to find secondary buses */ static void discover_secondary_buses(uacpi_namespace_node *root_bridge, uint8_t parent_bus) { /* Walk children looking for bridges with _PRT */ uacpi_namespace_for_each_child( root_bridge, discover_secondary_callback, /* descending callback */ UACPI_NULL, /* ascending callback (not needed) */ UACPI_OBJECT_DEVICE_BIT, /* type mask - only devices */ 3, /* Max depth - look 3 levels deep for nested bridges */ &parent_bus /* user data */ ); } /* Discover all PCI root bridges via ACPI */ static void discover_pci_buses(void) { discovered_pci_buses.count = 0; uacpi_namespace_node *sb_node = uacpi_namespace_get_predefined(UACPI_PREDEFINED_NAMESPACE_SB); if (!sb_node) { printf("mptable: _SB not found, cannot discover PCI buses\n"); return; } /* Search for PCI and PCIe root bridges */ const uacpi_char *hids[] = { "PNP0A03", "PNP0A08", UACPI_NULL }; uacpi_find_devices_at(sb_node, hids, discover_pci_bus_callback, UACPI_NULL); size_t root_count = discovered_pci_buses.count; /* Walk each root bridge to find secondary buses with their own _PRT */ for (size_t i = 0; i < root_count; i++) { discover_secondary_buses( discovered_pci_buses.buses[i].node, discovered_pci_buses.buses[i].bus_num ); } size_t secondary_count = discovered_pci_buses.count - root_count; if (secondary_count > 0) { printf("mptable: discovered %zu root + %zu secondary PCI buses\n", root_count, secondary_count); } else { printf("mptable: discovered %zu PCI root bridge(s)\n", root_count); } } /* Build the MP table */ bool mptable_init(struct csmwrap_priv *priv) { struct madt_data madt; int helper_apic_id = bios_proxy_get_helper_apic_id(); printf("mptable: building MP table (excluding helper core APIC ID %d)\n", helper_apic_id); /* MP spec 1.4 fields are 8-bit; an unrepresentable BSP makes the whole * table malformed (no BSP marker, misrouted local interrupts). */ uint32_t bsp_id = get_bsp_apic_id(); if (bsp_id > 255) { printf("mptable: BSP APIC ID %u exceeds 8-bit limit, skipping MP table\n", bsp_id); return false; } /* config->lapic is a 32-bit field. */ uint64_t lapic_phys_base = rdmsr(0x1b) & APIC_BASE_ADDR_MASK; if (lapic_phys_base > 0xFFFFFFFF) { printf("mptable: LAPIC base 0x%llx exceeds 32-bit MP table field, skipping MP table\n", (unsigned long long)lapic_phys_base); return false; } if (!parse_madt(&madt, helper_apic_id)) { printf("mptable: failed to parse MADT, skipping MP table\n"); return false; } /* Discover PCI root bridges via ACPI */ discover_pci_buses(); /* Get CPU info from CPUID */ uint32_t cpu_signature, cpu_features; get_cpu_info(&cpu_signature, &cpu_features); uint8_t lapic_version = get_lapic_version(); /* Ensure at least one PCI bus for backwards compatibility */ size_t pci_bus_count = discovered_pci_buses.count > 0 ? discovered_pci_buses.count : 1; /* * Calculate table size: * - Config header * - CPU entries * - Bus entries (N PCI buses + 1 ISA) * - I/O APIC entries * - ISA interrupt entries (16) * - PCI interrupt entries (up to 128 per bus * N buses) * - Local interrupt entries (2: ExtINT + NMI) */ size_t table_size = sizeof(struct mptable_config) + madt.cpu_count * sizeof(struct mpt_cpu) + (pci_bus_count + 1) * sizeof(struct mpt_bus) + madt.ioapic_count * sizeof(struct mpt_ioapic) + (16 + 128 * pci_bus_count + 2) * sizeof(struct mpt_intsrc); /* Allocate table anywhere below 4GB - SeaBIOS will relocate it to F-segment */ size_t total_size = sizeof(struct mptable_floating) + table_size; EFI_PHYSICAL_ADDRESS table_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiLoaderCode, (total_size + 4095) / 4096, &table_addr ); if (EFI_ERROR(status)) { printf("mptable: failed to allocate memory\n"); return false; } /* Pass address to SeaBIOS via boot table */ priv->low_stub->boot_table.MpTable = (uint32_t)table_addr; memset((void *)(uintptr_t)table_addr, 0, total_size); /* Build config table first, then floating pointer */ struct mptable_config *config = (struct mptable_config *)(uintptr_t)(table_addr + sizeof(struct mptable_floating)); uint8_t *entry_ptr = (uint8_t *)(config + 1); uint8_t *entry_end = (uint8_t *)(uintptr_t)(table_addr + total_size); uint16_t entry_count = 0; /* Config header */ config->signature = MPCONFIG_SIGNATURE; config->spec = 4; /* MP spec 1.4 */ memcpy(config->oemid, "CSMWRAP ", 8); memcpy(config->productid, "MP TABLE ", 12); config->lapic = (uint32_t)lapic_phys_base; /* CPU entries */ for (size_t i = 0; i < madt.cpu_count; i++) { struct mpt_cpu *cpu = (struct mpt_cpu *)entry_ptr; cpu->type = MPT_TYPE_CPU; cpu->apicid = madt.cpus[i].apic_id; cpu->apicver = lapic_version; cpu->cpuflag = madt.cpus[i].enabled ? 0x01 : 0x00; if (madt.cpus[i].is_bsp) cpu->cpuflag |= 0x02; cpu->cpusignature = cpu_signature; cpu->featureflag = cpu_features; entry_ptr += sizeof(struct mpt_cpu); entry_count++; } /* Bus entries: PCI buses */ uint8_t next_bus_id = 0; if (discovered_pci_buses.count > 0) { /* Create bus entries for all discovered PCI buses */ for (size_t i = 0; i < discovered_pci_buses.count; i++) { struct mpt_bus *pci_bus = (struct mpt_bus *)entry_ptr; pci_bus->type = MPT_TYPE_BUS; pci_bus->busid = next_bus_id; memcpy(pci_bus->bustype, "PCI ", 6); entry_ptr += sizeof(struct mpt_bus); entry_count++; /* Store the MP bus ID for _PRT processing later */ discovered_pci_buses.buses[i].mp_bus_id = next_bus_id; next_bus_id++; } } else { /* Fallback: create at least one PCI bus entry */ struct mpt_bus *pci_bus = (struct mpt_bus *)entry_ptr; pci_bus->type = MPT_TYPE_BUS; pci_bus->busid = next_bus_id; memcpy(pci_bus->bustype, "PCI ", 6); entry_ptr += sizeof(struct mpt_bus); entry_count++; next_bus_id++; } /* Bus entries: ISA bus (always last) */ uint8_t isa_bus_id = next_bus_id; struct mpt_bus *isa_bus = (struct mpt_bus *)entry_ptr; isa_bus->type = MPT_TYPE_BUS; isa_bus->busid = isa_bus_id; memcpy(isa_bus->bustype, "ISA ", 6); entry_ptr += sizeof(struct mpt_bus); entry_count++; /* I/O APIC entries */ for (size_t i = 0; i < madt.ioapic_count; i++) { struct mpt_ioapic *ioapic = (struct mpt_ioapic *)entry_ptr; ioapic->type = MPT_TYPE_IOAPIC; ioapic->apicid = madt.ioapics[i].id; ioapic->apicver = get_ioapic_version(madt.ioapics[i].address); ioapic->flags = 0x01; /* Enabled */ ioapic->apicaddr = madt.ioapics[i].address; entry_ptr += sizeof(struct mpt_ioapic); entry_count++; } /* ISA interrupt entries (IRQ 0-15) */ for (int irq = 0; irq < 16; irq++) { uint32_t gsi = irq; /* Default: identity mapping */ uint16_t flags = MP_IRQFLAG_CONFORM; /* Default: conforms to bus spec */ /* Check for override */ for (size_t j = 0; j < madt.override_count; j++) { if (madt.overrides[j].source_irq == irq) { gsi = madt.overrides[j].gsi; flags = madt_flags_to_mp(madt.overrides[j].flags); break; } } uint8_t dstirq; int ioapic_id = find_ioapic_for_gsi(&madt, gsi, &dstirq); if (ioapic_id < 0) continue; struct mpt_intsrc *intsrc = (struct mpt_intsrc *)entry_ptr; intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = MP_INT_TYPE_INT; intsrc->irqflag = flags; intsrc->srcbus = isa_bus_id; intsrc->srcbusirq = irq; intsrc->dstapic = ioapic_id; intsrc->dstirq = dstirq; entry_ptr += sizeof(struct mpt_intsrc); entry_count++; } /* PCI interrupt entries - from ACPI _PRT (PCI Routing Table) */ /* Process _PRT for each discovered PCI root bridge */ for (size_t bus_idx = 0; bus_idx < discovered_pci_buses.count; bus_idx++) { struct pci_bus_info *bus_info = &discovered_pci_buses.buses[bus_idx]; uacpi_pci_routing_table *prt = NULL; uacpi_status prt_status = uacpi_get_pci_routing_table(bus_info->node, &prt); if (prt_status != UACPI_STATUS_OK || !prt) continue; for (size_t i = 0; i < prt->num_entries; i++) { if (entry_ptr + sizeof(struct mpt_intsrc) > entry_end) { printf("mptable: table full, truncating PCI interrupt entries\n"); goto prt_done; } uacpi_pci_routing_table_entry *e = &prt->entries[i]; int32_t gsi; uint16_t acpi_flags = 0; if (e->source == NULL) { /* Static routing: index is the GSI directly */ gsi = e->index; } else { /* Dynamic routing: evaluate link device's _CRS */ gsi = get_link_device_gsi(e->source, &acpi_flags); if (gsi < 0) continue; } /* Find which I/O APIC handles this GSI */ uint8_t dstirq; int ioapic_id = find_ioapic_for_gsi(&madt, gsi, &dstirq); if (ioapic_id < 0) continue; /* _PRT address format: high word = device, low word = function (0xFFFF = any) */ uint8_t dev = (e->address >> 16) & 0x1F; /* Convert ACPI flags to MP flags, default to PCI standard if not specified */ uint16_t mp_flags; if (acpi_flags) { mp_flags = madt_flags_to_mp(acpi_flags); } else { mp_flags = MP_IRQFLAG_ACTIVE_LOW | MP_IRQFLAG_LEVEL; /* PCI default */ } struct mpt_intsrc *intsrc = (struct mpt_intsrc *)entry_ptr; intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = MP_INT_TYPE_INT; intsrc->irqflag = mp_flags; intsrc->srcbus = bus_info->mp_bus_id; /* Use the correct MP bus ID */ intsrc->srcbusirq = (dev << 2) | e->pin; /* MP spec: (dev << 2) | pin */ intsrc->dstapic = ioapic_id; intsrc->dstirq = dstirq; entry_ptr += sizeof(struct mpt_intsrc); entry_count++; } uacpi_free_pci_routing_table(prt); } prt_done: /* Local interrupt entries */ /* ExtINT on the LINT pin opposite NMI, BSP only (8259 wired to BSP). */ uint8_t bsp_apic_id = (uint8_t)bsp_id; /* range-checked at function entry */ uint8_t extint_lint = madt.nmi_lint ^ 1; struct mpt_intsrc *extint = (struct mpt_intsrc *)entry_ptr; extint->type = MPT_TYPE_LOCAL_INT; extint->irqtype = MP_INT_TYPE_EXTINT; extint->irqflag = MP_IRQFLAG_CONFORM; extint->srcbus = isa_bus_id; extint->srcbusirq = 0; extint->dstapic = bsp_apic_id; extint->dstirq = extint_lint; entry_ptr += sizeof(struct mpt_intsrc); entry_count++; /* NMI on LINT1 (or whatever MADT specified) */ struct mpt_intsrc *nmi = (struct mpt_intsrc *)entry_ptr; nmi->type = MPT_TYPE_LOCAL_INT; nmi->irqtype = MP_INT_TYPE_NMI; nmi->irqflag = madt.has_nmi_info ? madt_flags_to_mp(madt.nmi_flags) : MP_IRQFLAG_CONFORM; nmi->srcbus = isa_bus_id; nmi->srcbusirq = 0; nmi->dstapic = 0xFF; /* All local APICs */ nmi->dstirq = madt.nmi_lint; entry_ptr += sizeof(struct mpt_intsrc); entry_count++; /* Finalize config table */ config->entrycount = entry_count; config->length = (uint16_t)((uintptr_t)entry_ptr - (uintptr_t)config); config->checksum = 0; config->checksum = -compute_checksum(config, config->length); /* Build floating pointer structure */ struct mptable_floating *floating = (struct mptable_floating *)(uintptr_t)table_addr; floating->signature = MPTABLE_SIGNATURE; floating->physaddr = (uint32_t)(uintptr_t)config; floating->length = 1; /* 16 bytes */ floating->spec_rev = 4; /* MP spec 1.4 */ floating->feature1 = 0; /* Config table present */ floating->feature2 = 0; floating->checksum = 0; floating->checksum = -compute_checksum(floating, sizeof(*floating)); printf("mptable: built at 0x%lx, %u entries, %u bytes\n", (unsigned long)table_addr, entry_count, config->length); return true; } ================================================ FILE: src/mptable.h ================================================ /* * MP Table Generation from ACPI * * Generates Intel MultiProcessor Specification tables from ACPI MADT * for legacy BIOS compatibility. */ #ifndef _MPTABLE_H #define _MPTABLE_H #include #include struct csmwrap_priv; /* * Initialize and build MP tables from ACPI MADT. * * @param priv CSMWrap private data structure * @return true on success, false on failure */ bool mptable_init(struct csmwrap_priv *priv); #endif /* _MPTABLE_H */ ================================================ FILE: src/oprom.c ================================================ #include #include #include #include #include #include #include #include /* Option ROM alignment - must match SeaBIOS OPTION_ROM_ALIGN (2048) */ #define OPTION_ROM_ALIGN 2048 EFI_STATUS GetPciLegacyRom( IN UINT16 Csm16Revision, IN UINT16 VendorId, IN UINT16 DeviceId, IN OUT VOID **Rom, IN OUT UINTN *ImageSize, OUT UINTN *MaxRuntimeImageLength, OPTIONAL OUT UINT8 *OpRomRevision, OPTIONAL OUT VOID **ConfigUtilityCodeHeader OPTIONAL ) { BOOLEAN Match; UINT16 *DeviceIdList; EFI_PCI_ROM_HEADER RomHeader; PCI_3_0_DATA_STRUCTURE *Pcir; VOID *BackupImage; VOID *BestImage; if (*ImageSize < sizeof(EFI_PCI_ROM_HEADER)) { return EFI_NOT_FOUND; } BestImage = NULL; BackupImage = NULL; RomHeader.Raw = *Rom; while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) { if (RomHeader.Generic->PcirOffset == 0 || (RomHeader.Generic->PcirOffset & 3) != 0 || *ImageSize < RomHeader.Raw - (UINT8 *)*Rom + RomHeader.Generic->PcirOffset + sizeof(PCI_DATA_STRUCTURE)) { break; } Pcir = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset); if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { break; } if (((UINTN)RomHeader.Raw - (UINTN)*Rom) + Pcir->ImageLength * 512 > *ImageSize) { break; } if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { Match = FALSE; if (Pcir->VendorId == VendorId) { if (Pcir->DeviceId == DeviceId) { Match = TRUE; } else if ((Pcir->Revision >= 3) && (Pcir->DeviceListOffset != 0)) { DeviceIdList = (UINT16 *)(((UINT8 *)Pcir) + Pcir->DeviceListOffset); while (*DeviceIdList != 0) { if (*DeviceIdList == DeviceId) { Match = TRUE; break; } DeviceIdList++; } } } if (Match) { if (Csm16Revision >= 0x0300) { if (Pcir->Revision >= 3) { BestImage = RomHeader.Raw; break; } else { BackupImage = RomHeader.Raw; } } else { if (Pcir->Revision >= 3) { BackupImage = RomHeader.Raw; } else { BestImage = RomHeader.Raw; break; } } } } if ((Pcir->Indicator & 0x80) == 0x80) { break; } else { RomHeader.Raw += 512 * Pcir->ImageLength; } } if (BestImage == NULL) { if (BackupImage == NULL) { return EFI_NOT_FOUND; } BestImage = BackupImage; } RomHeader.Raw = BestImage; Pcir = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset); *Rom = BestImage; *ImageSize = Pcir->ImageLength * 512; if (MaxRuntimeImageLength != NULL) { if (Pcir->Revision < 3) { *MaxRuntimeImageLength = 0; } else { *MaxRuntimeImageLength = Pcir->MaxRuntimeImageLength * 512; } } if (OpRomRevision != NULL) { if (Pcir->Length >= 0x1C) { *OpRomRevision = Pcir->Revision; } else { *OpRomRevision = 0; } } if (ConfigUtilityCodeHeader != NULL) { if ((Pcir->Revision < 3) || (Pcir->ConfigUtilityCodeHeaderOffset == 0)) { *ConfigUtilityCodeHeader = NULL; } else { *ConfigUtilityCodeHeader = RomHeader.Raw + Pcir->ConfigUtilityCodeHeaderOffset; } } return EFI_SUCCESS; } void oprom_enumerate(struct csmwrap_priv *priv, struct pci_oprom_list *list) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; list->count = 0; Status = gBS->LocateHandleBuffer(ByProtocol, &PciIoGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR(Status)) return; for (UINTN i = 0; i < HandleCount && list->count < MAX_PCI_OPROMS; i++) { EFI_PCI_IO_PROTOCOL *PciIo; Status = gBS->HandleProtocol(HandleBuffer[i], &PciIoGuid, (VOID **)&PciIo); if (EFI_ERROR(Status)) continue; /* Skip devices without option ROMs */ if (!PciIo->RomImage || !PciIo->RomSize) continue; /* Read PCI config header */ PCI_TYPE00 PciConfig; Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, 0, sizeof(PciConfig) / sizeof(UINT32), &PciConfig); if (EFI_ERROR(Status)) continue; /* Skip VGA devices - handled separately by the video path */ if (PciConfig.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) continue; /* Skip the VGA device explicitly by BDF too, in case class doesn't match */ UINTN Seg, Bus, Device, Function; PciIo->GetLocation(PciIo, &Seg, &Bus, &Device, &Function); uint8_t devfn = (uint8_t)((Device << 3) | Function); if ((uint8_t)Bus == priv->vga_pci_bus && devfn == priv->vga_pci_devfn) continue; /* Try to extract an x86 PC-AT legacy ROM image */ VOID *RomImage = PciIo->RomImage; UINTN RomSize = (UINTN)PciIo->RomSize; Status = GetPciLegacyRom(0x0300, PciConfig.Hdr.VendorId, PciConfig.Hdr.DeviceId, &RomImage, &RomSize, NULL, NULL, NULL); if (EFI_ERROR(Status)) continue; struct pci_oprom_info *entry = &list->entries[list->count]; entry->bus = (uint8_t)Bus; entry->devfn = devfn; entry->vendor_id = PciConfig.Hdr.VendorId; entry->device_id = PciConfig.Hdr.DeviceId; entry->class_code = PciConfig.Hdr.ClassCode[2]; entry->rom_image = RomImage; entry->rom_size = RomSize; list->count++; printf("OpROM: %02x:%02x.%x %04x:%04x class %02x (%u bytes)\n", (uint8_t)Bus, (uint8_t)Device, (uint8_t)Function, PciConfig.Hdr.VendorId, PciConfig.Hdr.DeviceId, PciConfig.Hdr.ClassCode[2], (unsigned)RomSize); } gBS->FreePool(HandleBuffer); if (list->count > 0) printf("Found %zu non-VGA option ROM(s)\n", list->count); else printf("No non-VGA option ROMs found\n"); } void oprom_dispatch_all(struct csmwrap_priv *priv, struct pci_oprom_list *list) { if (list->count == 0) return; /* * ROM placement watermark. With a VBIOS, non-VGA ROMs start just past it. * With no VBIOS (e.g. headless system), skip the canonical VGA region so * non-VGA ROMs never land at 0xC0000 where firmware expects a VGA OpROM. */ uintptr_t rom_watermark = VGABIOS_END; if (vbios_loc != NULL) rom_watermark = ALIGN_UP(VGABIOS_START + vbios_size, OPTION_ROM_ALIGN); for (size_t i = 0; i < list->count; i++) { struct pci_oprom_info *info = &list->entries[i]; uintptr_t rom_size_aligned = ALIGN_UP(info->rom_size, OPTION_ROM_ALIGN); /* Check available space (must not collide with SeaBIOS CSM binary) */ if (rom_watermark + rom_size_aligned > priv->csm_bin_base) { printf("OpROM: no space for %04x:%04x (need 0x%x, have 0x%x)\n", info->vendor_id, info->device_id, (unsigned)rom_size_aligned, (unsigned)(priv->csm_bin_base - rom_watermark)); continue; } /* Copy ROM image to shadow RAM */ memcpy((void *)rom_watermark, info->rom_image, info->rom_size); /* Zero-pad to alignment boundary */ if (info->rom_size < rom_size_aligned) memset((void *)(rom_watermark + info->rom_size), 0, rom_size_aligned - info->rom_size); /* Fill the dispatch table */ EFI_DISPATCH_OPROM_TABLE *table = &priv->low_stub->oprom_table; memset(table, 0, sizeof(*table)); table->OpromSegment = (UINT16)(rom_watermark >> 4); table->PciBus = info->bus; table->PciDeviceFunction = info->devfn; table->NumberBbsEntries = (UINT8)priv->low_stub->bbs_entry_count; table->BbsTablePointer = (UINT32)(uintptr_t)priv->low_stub->bbs_entries; printf("OpROM: dispatching %04x:%04x at seg %04x (%u bytes)\n", info->vendor_id, info->device_id, table->OpromSegment, (unsigned)info->rom_size); pci_enable_for_oprom(info->bus, info->devfn); EFI_IA32_REGISTER_SET Regs; memset(&Regs, 0, sizeof(Regs)); Regs.X.AX = Legacy16DispatchOprom; Regs.X.ES = EFI_SEGMENT(table); Regs.X.BX = EFI_OFFSET(table); LegacyBiosFarCall86(priv->csm_efi_table->Compatibility16CallSegment, priv->csm_efi_table->Compatibility16CallOffset, &Regs, NULL, 0); printf("OpROM: dispatch returned AX=%04x BX=%04x\n", Regs.X.AX, Regs.X.BX); rom_watermark += rom_size_aligned; } } ================================================ FILE: src/oprom.h ================================================ #ifndef OPROM_H #define OPROM_H #include #include #include #include #define MAX_PCI_OPROMS 16 struct pci_oprom_info { uint8_t bus; uint8_t devfn; /* (device << 3) | function */ uint16_t vendor_id; uint16_t device_id; uint8_t class_code; /* PCI base class */ void *rom_image; /* Pointer to x86 PC-AT ROM image */ size_t rom_size; /* Size of the x86 image in bytes */ }; struct pci_oprom_list { size_t count; struct pci_oprom_info entries[MAX_PCI_OPROMS]; }; /* * Enumerate all PCI devices with legacy x86 option ROMs (excluding VGA). * Must be called before ExitBootServices (requires EFI_PCI_IO_PROTOCOL). */ void oprom_enumerate(struct csmwrap_priv *priv, struct pci_oprom_list *list); /* * Dispatch all enumerated option ROMs via Legacy16DispatchOprom. * Must be called after Legacy16InitializeYourself and after the VGA oprom * dispatch, but before Legacy16UpdateBbs. */ void oprom_dispatch_all(struct csmwrap_priv *priv, struct pci_oprom_list *list); /* * Extract the x86 PC-AT legacy ROM image from a PCI ROM bundle. * The ROM bundle may contain multiple images (x86, EFI, OpenFirmware). * On success, *Rom and *ImageSize are updated to point to the x86 image. */ EFI_STATUS GetPciLegacyRom( UINT16 Csm16Revision, UINT16 VendorId, UINT16 DeviceId, VOID **Rom, UINTN *ImageSize, UINTN *MaxRuntimeImageLength, UINT8 *OpRomRevision, VOID **ConfigUtilityCodeHeader ); #endif ================================================ FILE: src/pci.c ================================================ #define FLANTERM_IN_FLANTERM #include #include #include #include #include #include extern struct flanterm_context *flanterm_ctx; #include #include #include #include #include #include // ECAM (Enhanced Configuration Access Mechanism) support // ECAM maps PCI config space to memory: base + (bus << 20) + (dev << 15) + (func << 12) + offset #define ECAM_MAX_REGIONS 16 struct ecam_region { uint64_t base; // MMIO base address uint16_t segment; // PCI segment uint8_t start_bus; // First bus number covered uint8_t end_bus; // Last bus number covered }; static struct ecam_region ecam_regions[ECAM_MAX_REGIONS]; static size_t ecam_region_count = 0; // Find ECAM region for a given segment and bus static struct ecam_region *find_ecam_region(uint16_t segment, uint8_t bus) { for (size_t i = 0; i < ecam_region_count; i++) { struct ecam_region *region = &ecam_regions[i]; if (region->segment == segment && bus >= region->start_bus && bus <= region->end_bus) { return region; } } return NULL; } // Calculate ECAM address for a given PCI address and offset // Note: Per ACPI spec, the MCFG base address always corresponds to bus 0, // regardless of what start_bus is. The start_bus is only for validation. static inline void *ecam_address(struct ecam_region *region, struct pci_address *address, uint32_t offset) { uint64_t addr = region->base; addr += (uint64_t)(address->bus) << 20; addr += (uint64_t)(address->slot) << 15; addr += (uint64_t)(address->function) << 12; addr += offset; return (void *)(uintptr_t)addr; } static uint32_t pci_read_pio(struct pci_address *address, uint32_t offset, uint32_t size) { // CF8/CFC has no segment field and only ever reaches segment 0; refuse // any other segment so we don't silently access a same-B:D.F device on // segment 0 instead. if (address->segment != 0 || offset >= 0x100) { return 0xFFFFFFFF; } switch (size) { case 1: return pciConfigReadByte(address->bus, address->slot, address->function, offset); case 2: return pciConfigReadWord(address->bus, address->slot, address->function, offset); default: return pciConfigReadDWord(address->bus, address->slot, address->function, offset); } } static void pci_write_pio(struct pci_address *address, uint32_t offset, uint32_t size, uint32_t value) { if (address->segment != 0 || offset >= 0x100) { return; } switch (size) { case 1: pciConfigWriteByte(address->bus, address->slot, address->function, offset, value); break; case 2: pciConfigWriteWord(address->bus, address->slot, address->function, offset, value); break; default: pciConfigWriteDWord(address->bus, address->slot, address->function, offset, value); break; } } static uint32_t pci_read_ecam(struct pci_address *address, uint32_t offset, uint32_t size) { struct ecam_region *region = find_ecam_region(address->segment, address->bus); if (region == NULL) { // Fall back to PIO if no ECAM region covers this bus. return pci_read_pio(address, offset, size); } void *addr = ecam_address(region, address, offset); switch (size) { case 1: return readb(addr); case 2: return readw(addr); default: return readl(addr); } } static void pci_write_ecam(struct pci_address *address, uint32_t offset, uint32_t size, uint32_t value) { struct ecam_region *region = find_ecam_region(address->segment, address->bus); if (region == NULL) { // Fall back to PIO if no ECAM region covers this bus. pci_write_pio(address, offset, size, value); return; } void *addr = ecam_address(region, address, offset); switch (size) { case 1: writeb(addr, value); break; case 2: writew(addr, value); break; default: writel(addr, value); break; } } typedef uint32_t(*pci_read_t)(struct pci_address *address, uint32_t offset, uint32_t size); typedef void (*pci_write_t)(struct pci_address *address, uint32_t offset, uint32_t size, uint32_t value); static pci_read_t pci_read = pci_read_pio; static pci_write_t pci_write = pci_write_pio; uint32_t pci_read_config_space(struct pci_address *address, uint32_t offset, uint32_t size) { return pci_read(address, offset & ~(size - 1), size); } void pci_write_config_space(struct pci_address *address, uint32_t offset, uint32_t size, uint32_t value) { pci_write(address, offset & ~(size - 1), size, value); } void pci_enable_for_oprom(uint8_t bus, uint8_t devfn) { struct pci_address address = { .segment = 0, .bus = bus, .slot = devfn >> 3, .function = devfn & 0x7, }; uint16_t cmd = pci_read16(&address, 0x04); pci_write16(&address, 0x04, cmd | (1 << 0) | (1 << 1) | (1 << 2)); } // Parse MCFG table and populate ECAM regions static bool parse_mcfg_table(void) { uacpi_table tbl; uacpi_status status; status = uacpi_table_find_by_signature(ACPI_MCFG_SIGNATURE, &tbl); if (status != UACPI_STATUS_OK) { printf("MCFG table not found, using legacy PIO for config access\n"); return false; } struct acpi_mcfg *mcfg = (struct acpi_mcfg *)tbl.hdr; // Calculate number of entries: (table_length - header_size) / entry_size size_t entries_size = mcfg->hdr.length - sizeof(struct acpi_mcfg); size_t num_entries = entries_size / sizeof(struct acpi_mcfg_allocation); printf("MCFG: found %zu ECAM region(s)\n", num_entries); for (size_t i = 0; i < num_entries && ecam_region_count < ECAM_MAX_REGIONS; i++) { struct acpi_mcfg_allocation *alloc = &mcfg->entries[i]; ecam_regions[ecam_region_count].base = alloc->address; ecam_regions[ecam_region_count].segment = alloc->segment; ecam_regions[ecam_region_count].start_bus = alloc->start_bus; ecam_regions[ecam_region_count].end_bus = alloc->end_bus; printf(" ECAM region %zu: base=0x%llx segment=%u buses=%u-%u\n", ecam_region_count, alloc->address, alloc->segment, alloc->start_bus, alloc->end_bus); ecam_region_count++; } if (ecam_region_count > 0) { // Switch to ECAM access (with PIO fallback built into the functions) pci_read = pci_read_ecam; pci_write = pci_write_ecam; printf("ECAM: enabled memory-mapped config access\n"); return true; } return false; } // ============================================================================ // PCIe Resizable BAR Support // ============================================================================ #define PCI_EXT_CAP_ID_REBAR 0x15 // Resizable BAR capability ID // Find a PCIe extended capability by ID // Returns the offset in config space, or 0 if not found static uint16_t pci_find_ext_capability(struct pci_address *address, uint16_t cap_id) { // Extended capabilities start at offset 0x100 uint16_t offset = 0x100; // Walk the extended capability list for (int i = 0; i < 48 && offset != 0; i++) { // Max 48 iterations to prevent infinite loop uint32_t header = pci_read32(address, offset); // Check for invalid header (all 1s or all 0s) if (header == 0xFFFFFFFF || header == 0) { return 0; } uint16_t id = header & 0xFFFF; uint16_t next = (header >> 20) & 0xFFC; // Next pointer is bits [31:20], 4-byte aligned if (id == cap_id) { return offset; } offset = next; } return 0; } // Patch the Supported Sizes bitmap for cards that ship a malformed REBAR // capability. The bitmap is post-shift: bit N means size 2^(N+20) bytes. static uint32_t pci_rebar_apply_quirks(uint16_t vendor, uint16_t device, uint16_t subsystem_vendor, uint8_t revision, uint8_t bar, uint32_t supported_sizes) { // Sapphire Radeon RX 5600 XT Pulse (1002:731f, ssvid 1da2, rev C1) // advertises only the 256/512/1024 MB bits for BAR 0, while the silicon // actually decodes up to 8 GB. Mirrors Linux's quirk in // drivers/pci/rebar.c, including the subsystem vendor and revision // restrictions that keep it from misfiring on other 5600 XT boards. if (vendor == 0x1002 && device == 0x731f && subsystem_vendor == 0x1da2 && revision == 0xC1 && bar == 0 && supported_sizes == 0x700) { return 0x3f00; } return supported_sizes; } // Try to resize a BAR to fit within max_size bytes // Returns the new size if successful, or 0 if resize not possible static uint64_t pci_try_resize_bar(struct pci_address *address, uint8_t bar_index, uint64_t max_size) { uint16_t rebar_offset = pci_find_ext_capability(address, PCI_EXT_CAP_ID_REBAR); if (rebar_offset == 0) { return 0; // No Resizable BAR capability } // Read number of resizable BARs from first control register uint32_t ctrl0 = pci_read32(address, rebar_offset + 0x08); uint8_t num_bars = (ctrl0 >> 5) & 0x7; if (num_bars == 0) { return 0; } // Search for the entry corresponding to our BAR for (uint8_t i = 0; i < num_bars; i++) { uint16_t entry_offset = rebar_offset + 0x04 + (i * 8); uint32_t cap = pci_read32(address, entry_offset); uint32_t ctrl = pci_read32(address, entry_offset + 4); uint8_t this_bar = ctrl & 0x7; // BAR index in bits [2:0] if (this_bar != bar_index) { continue; } // Found the entry for our BAR // Supported sizes are in cap bits [31:4], each bit N represents size 2^(N+20) uint32_t supported_sizes = (cap >> 4) & 0x0FFFFFFF; uint16_t vendor = pci_read16(address, 0x00); uint16_t device = pci_read16(address, 0x02); uint16_t subsystem_vendor = pci_read16(address, 0x2c); uint8_t revision = pci_read8(address, 0x08); supported_sizes = pci_rebar_apply_quirks(vendor, device, subsystem_vendor, revision, bar_index, supported_sizes); // Find the largest size that fits within max_size // Sizes: bit 0 = 1MB (2^20), bit 1 = 2MB (2^21), etc. int best_size_bit = -1; for (int bit = 27; bit >= 0; bit--) { // Check from largest to smallest if (!(supported_sizes & (1 << bit))) { continue; } uint64_t size = 1ULL << (bit + 20); if (size <= max_size) { best_size_bit = bit; break; } } if (best_size_bit < 0) { return 0; } uint64_t new_size = 1ULL << (best_size_bit + 20); // Save original BAR(s) - PCIe spec: contents are unspecified after resize uint32_t bar_offset = 0x10 + bar_index * 4; uint32_t orig_bar_lo = pci_read32(address, bar_offset); bool bar_is_64 = (orig_bar_lo & 0x6) == 0x4; uint32_t orig_bar_hi = bar_is_64 ? pci_read32(address, bar_offset + 4) : 0; // Disable memory decode before resizing uint16_t cmd = pci_read16(address, 0x04); pci_write16(address, 0x04, cmd & ~0x06); // Clear memory space + bus master // Read-modify-write only the BAR Size field (bits [12:8]); other // bits include RsvdP that must be preserved per PCIe spec. uint32_t new_ctrl = (ctrl & ~0x1F00) | ((best_size_bit & 0x1F) << 8); pci_write32(address, entry_offset + 4, new_ctrl); // Restore BAR address clobbered by resize pci_write32(address, bar_offset, orig_bar_lo); if (bar_is_64) { pci_write32(address, bar_offset + 4, orig_bar_hi); } // Re-enable memory decode pci_write16(address, 0x04, cmd); return new_size; } return 0; } #define ROOT_BUSES_MAX 64 static struct pci_bus *root_buses[ROOT_BUSES_MAX]; static size_t root_bus_count = 0; #define BUS_STRUCT_POOL_COUNT 128 static struct pci_bus *bus_struct_pool = NULL; static size_t bus_struct_pool_ptr = 0; static struct pci_bus *allocate_bus(void) { if (bus_struct_pool_ptr == BUS_STRUCT_POOL_COUNT) { return NULL; } return &bus_struct_pool[bus_struct_pool_ptr++]; } #define DEVICE_STRUCT_POOL_COUNT 1024 static struct pci_device *device_struct_pool = NULL; static size_t device_struct_pool_ptr = 0; static struct pci_device *allocate_device(void) { if (device_struct_pool_ptr == DEVICE_STRUCT_POOL_COUNT) { return NULL; } return &device_struct_pool[device_struct_pool_ptr++]; } #define BAR_STRUCT_POOL_COUNT 2048 static struct pci_bar *bar_struct_pool = NULL; static size_t bar_struct_pool_ptr = 0; static struct pci_bar *allocate_bar(void) { if (bar_struct_pool_ptr == BAR_STRUCT_POOL_COUNT) { return NULL; } return &bar_struct_pool[bar_struct_pool_ptr++]; } static bool add_root_bus(struct pci_bus *bus) { if (root_bus_count == ROOT_BUSES_MAX) { return false; } root_buses[root_bus_count++] = bus; return true; } static struct pci_range *add_range(struct pci_bus *bus, uint64_t base, uint64_t length, bool prefetchable) { // For root buses, filter out ranges above 4GB (can't be used by legacy BIOS) // For secondary buses, keep >4GB ranges so we can create bridge window pseudo-BARs // (the bridge windows will be relocated to <4GB, updating the range) if (bus->root) { if (base + length > 0x100000000) { if (base >= 0x100000000) { return NULL; } length -= (base + length) - 0x100000000; } } // Low memory ranges are special if (base < 0x100000) { return NULL; } if (bus->range_count == PCI_MAX_RANGES_PER_BUS) { return NULL; } bus->ranges[bus->range_count].base = base; bus->ranges[bus->range_count].length = length; bus->ranges[bus->range_count].prefetchable = prefetchable; bus->range_count++; return &bus->ranges[bus->range_count - 1]; } // Tombstone the range in place rather than shifting later entries down, // since bridge pseudo-BARs cache raw pointers into bus->ranges[]. static bool drop_range(struct pci_bus *bus, struct pci_range *range) { (void)bus; range->length = 0; return true; } static bool add_device(struct pci_bus *bus, struct pci_device *device) { if (bus->device_count == PCI_MAX_DEVICES_PER_BUS) { return false; } bus->devices[bus->device_count++] = device; return true; } static bool add_bar(struct pci_bus *bus, struct pci_bar *bar) { // Non-bridge BARs >4GB are hopeless if (bar->range == NULL && bar->length >= 0x100000000) { return true; } // Likewise for BARs originally below 1MiB if (bar->base < 0x100000) { return true; } if (bus->bar_count == PCI_MAX_BARS_PER_BUS) { return false; } bus->bars[bus->bar_count++] = bar; return true; } static bool drop_bar(struct pci_bus *bus, struct pci_bar *bar) { for (size_t i = 0; i < bus->bar_count; i++) { if (bus->bars[i] != bar) { continue; } if (i + 1 < bus->bar_count) { memmove(&bus->bars[i], &bus->bars[i + 1], (bus->bar_count - i - 1) * sizeof(struct pci_bar *)); } bus->bar_count--; break; } return true; } // Check if firmware placed this address within a prefetchable range. // This is used to determine if a non-prefetchable BAR can safely be // relocated to a prefetchable range (firmware already deemed it safe). static bool is_address_in_prefetchable_range(struct pci_bus *bus, uint64_t address) { for (size_t i = 0; i < bus->range_count; i++) { struct pci_range *range = &bus->ranges[i]; if (range->length == 0) { continue; } if (address >= range->base && address < range->base + range->length) { return range->prefetchable; } } return false; } static int compare_bars(const void *a, const void *b) { const struct pci_bar *bar_a = *(const struct pci_bar **)a; const struct pci_bar *bar_b = *(const struct pci_bar **)b; // Sort by length descending (largest first) if (bar_a->length > bar_b->length) return -1; if (bar_a->length < bar_b->length) return 1; return 0; } static void sort_bars(struct pci_bus *bus) { qsort(bus->bars, bus->bar_count, sizeof(struct pci_bar *), compare_bars); for (size_t i = 0; i < bus->bar_count; i++) { if (bus->bars[i]->range == NULL) { continue; } struct pci_bar *bar = bus->bars[i]; struct pci_device *device = bar->device; struct pci_bus *bridge_bus = device->bridge_bus; sort_bars(bridge_bus); } } static void reallocate_bars(struct pci_bus *bus); static bool fb_relocated = false; static void reallocate_single_bar(struct pci_bus *bus, struct pci_bar *bar) { bool tried_all_prefetchable = false; again: for (size_t i = 0; i < bus->range_count; i++) { struct pci_range *range = &bus->ranges[i]; if (range->length == 0) { continue; } if (tried_all_prefetchable == false && bar->prefetchable != range->prefetchable) { continue; } // Skip ranges above 4GB - they can't be used by legacy BIOS // (Bridge window pseudo-BARs will relocate these ranges to <4GB first) if (range->base >= 0x100000000ULL) { continue; } // BARs must be naturally aligned to their size. // Compute alignment on the absolute address since the range base // (from ACPI for root buses) may not be aligned to large BAR sizes. // For bridge windows, align to largest child BAR, not window size. uint64_t alignment = bar->length; if (bar->bar_number == 0xff && bar->device->bridge_bus != NULL) { // Find largest child BAR with matching prefetchability uint64_t largest_child = 0x100000; // 1MB minimum for bridge windows struct pci_bus *child_bus = bar->device->bridge_bus; for (size_t j = 0; j < child_bus->bar_count; j++) { struct pci_bar *child = child_bus->bars[j]; if (child->prefetchable == bar->prefetchable && child->length > largest_child) { largest_child = child->length; } } alignment = largest_child; } uint64_t current_absolute = range->base + range->reloc_ptr; uint64_t aligned_absolute = ALIGN_UP(current_absolute, alignment); if (aligned_absolute + bar->length > range->base + range->length) { continue; } uint64_t orig_base = bar->base; bar->base = aligned_absolute; range->reloc_ptr = (aligned_absolute - range->base) + bar->length; struct pci_device *device = bar->device; struct pci_address address; address.segment = device->root_bus->segment; address.bus = device->root_bus->bus; address.slot = device->slot; address.function = device->function; printf("reallocating BAR %u of device %04x:%02x:%02x.%02x from 0x%llx to 0x%llx\n", bar->bar_number, bus->segment, bus->bus, bar->device->slot, bar->device->function, orig_base, bar->base); // Track the framebuffer via the actual device BAR, not bridge window // pseudo-BARs: a window's relocation only preserves the FB offset if // the BAR layout within the window is unchanged, which compaction // does not guarantee. The fb_relocated flag still guards against a // post-adjustment FBA falling within another regular BAR's old range. if (!fb_relocated && bar->bar_number != 0xff && priv.cb_fb.physical_address >= orig_base && priv.cb_fb.physical_address < orig_base + bar->length) { printf("BAR contains the EFI framebuffer. Modifying cb_fb.physical_address accordingly...\n"); printf(" 0x%llx => ", priv.cb_fb.physical_address); priv.cb_fb.physical_address -= orig_base; priv.cb_fb.physical_address += bar->base; printf("0x%llx\n", priv.cb_fb.physical_address); fb_relocated = true; } // Disable memory decode while updating BAR to prevent device from // responding to partially-updated or stale addresses uint16_t cmd = pci_read16(&address, 0x04); pci_write16(&address, 0x04, cmd & ~(1 << 1)); if (bar->bar_number != 0xff) { uint64_t new_base = bar->base | (pci_read32(&address, 0x10 + bar->bar_number * 4) & 0xf); pci_write32(&address, 0x10 + bar->bar_number * 4, new_base); if (bar->is_64) { pci_write32(&address, 0x10 + bar->bar_number * 4 + 4, new_base >> 32); } } else { // Bridge window - need to update BOTH base AND limit registers // Limit is an absolute address: base + length - 1 uint8_t base_reg = bar->prefetchable ? 0x24 : 0x20; uint8_t limit_reg = bar->prefetchable ? 0x26 : 0x22; // Calculate new limit address uint64_t new_limit = bar->base + bar->length - 1; // Write base register (preserve type bits in low nibble) pci_write16(&address, base_reg, ((bar->base >> 16) & 0xfff0) | (pci_read16(&address, base_reg) & 0xf)); // Write limit register (preserve type bits in low nibble) pci_write16(&address, limit_reg, ((new_limit >> 16) & 0xfff0) | (pci_read16(&address, limit_reg) & 0xf)); if (bar->prefetchable && bar->is_64) { pci_write32(&address, 0x28, bar->base >> 32); pci_write32(&address, 0x2c, new_limit >> 32); } bar->range->base = bar->base; bar->device->reallocated_windows++; // Count total bridge window bars for this device int total_bridge_windows = 0; for (size_t j = 0; j < bus->bar_count; j++) { if (bus->bars[j]->device == bar->device && bus->bars[j]->bar_number == 0xff) { total_bridge_windows++; } } // Re-enable memory decode BEFORE recursing - child devices need the bridge to forward transactions cmd |= (1 << 0) | (1 << 1) | (1 << 2); pci_write16(&address, 0x04, cmd); // Only recurse once all bridge windows for this device are done if (bar->device->reallocated_windows == total_bridge_windows) { reallocate_bars(bar->device->bridge_bus); } return; } // Restore the device's original command register; we only cleared // MEM_EN above, so writing the saved value back puts I/O space and // bus master back to whatever the firmware had set them to. // Devices with associated option ROMs are force-enabled separately // via pci_enable_for_oprom before dispatch. pci_write16(&address, 0x04, cmd); return; } // Allow fallback to mismatched prefetchability if: // 1. BAR is prefetchable (can always use non-prefetchable range safely), or // 2. Firmware originally placed this non-prefetchable BAR in a prefetchable range // (trusting that firmware knew this device is safe in prefetchable memory) if ((bar->prefetchable || bar->firmware_in_prefetchable) && tried_all_prefetchable == false) { tried_all_prefetchable = true; goto again; } printf("failed to reallocate BAR %u for device %04x:%02x:%02x.%02x\n", bar->bar_number, bus->segment, bus->bus, bar->device->slot, bar->device->function); // Even if this bridge window failed, we still need to track it for recursion purposes. // Otherwise, if one window fails, we'll never recurse into the secondary bus. if (bar->bar_number == 0xff && bar->device->bridge_bus != NULL) { bar->device->reallocated_windows++; int total_bridge_windows = 0; for (size_t j = 0; j < bus->bar_count; j++) { if (bus->bars[j]->device == bar->device && bus->bars[j]->bar_number == 0xff) { total_bridge_windows++; } } if (bar->device->reallocated_windows == total_bridge_windows) { reallocate_bars(bar->device->bridge_bus); } } } static void reallocate_bars(struct pci_bus *bus) { for (size_t i = 0; i < bus->bar_count; i++) { reallocate_single_bar(bus, bus->bars[i]); } } static bool scan_bars(struct pci_device *device) { uint8_t max_bars = device->type == PCI_DEVICE_BRIDGE ? 2 : 6; struct pci_address address; address.segment = device->root_bus->segment; address.bus = device->root_bus->bus; address.slot = device->slot; address.function = device->function; if (device->type == PCI_DEVICE_BRIDGE) { // Non-prefetchable memory window. Bits [3:0] of the 16-bit base and // limit registers are reserved-zero, so we can use them as-is. uint64_t non_prefetchable_base = (uint64_t)pci_read16(&address, 0x20) << 16; uint64_t non_prefetchable_limit = ((uint64_t)pci_read16(&address, 0x22) << 16) | 0xfffff; // A window is enabled iff limit >= base; otherwise it is closed // (firmware convention is base = 0xFFF0, limit = 0x0000). if (non_prefetchable_limit >= non_prefetchable_base) { uint64_t non_prefetchable_length = non_prefetchable_limit - non_prefetchable_base + 1; struct pci_range *range = add_range(device->bridge_bus, non_prefetchable_base, non_prefetchable_length, false); if (range == NULL) { // Range not usable (above 4G, below 1M, or pool exhausted) - skip goto no_non_prefetch_range; } struct pci_bar *bar = allocate_bar(); if (bar == NULL) { printf("allocate_bar() failed for bridge non-prefetchable window\n"); goto no_non_prefetch_range; } bar->range = range; bar->base = non_prefetchable_base; bar->length = non_prefetchable_length; bar->bar_number = 0xff; bar->device = device; bar->prefetchable = false; bar->is_64 = false; // Check if firmware placed this non-prefetchable window in a prefetchable region bar->firmware_in_prefetchable = is_address_in_prefetchable_range(device->root_bus, non_prefetchable_base); if (!add_bar(device->root_bus, bar)) { printf("add_bar() failed for bridge non-prefetchable window\n"); goto no_non_prefetch_range; } } no_non_prefetch_range:; // Prefetchable memory window. Bits [3:0] of base/limit indicate // 32-bit (0x0) vs 64-bit (0x1) decoding; mask them off before use. uint16_t prefetchable_base_reg = pci_read16(&address, 0x24); uint16_t prefetchable_limit_reg = pci_read16(&address, 0x26); bool is_64 = (prefetchable_base_reg & 0xf) == 0x1; uint64_t prefetchable_base = (uint64_t)(prefetchable_base_reg & 0xfff0) << 16; uint64_t prefetchable_limit = ((uint64_t)(prefetchable_limit_reg & 0xfff0) << 16) | 0xfffff; // For 64-bit windows, fold in the upper-32 registers before doing // the limit-vs-base test: a window that crosses 4 GB legitimately // has lower-16 limit < lower-16 base. if (is_64) { prefetchable_base |= (uint64_t)pci_read32(&address, 0x28) << 32; prefetchable_limit |= (uint64_t)pci_read32(&address, 0x2c) << 32; } if (prefetchable_limit >= prefetchable_base) { uint64_t prefetchable_length = prefetchable_limit - prefetchable_base + 1; struct pci_range *range = add_range(device->bridge_bus, prefetchable_base, prefetchable_length, true); if (range == NULL) { // Range not usable (above 4G, below 1M, or pool exhausted) - skip goto no_prefetch_range; } struct pci_bar *bar = allocate_bar(); if (bar == NULL) { printf("allocate_bar() failed for bridge prefetchable window\n"); goto no_prefetch_range; } bar->range = range; bar->base = prefetchable_base; bar->length = prefetchable_length; bar->bar_number = 0xff; bar->device = device; bar->prefetchable = true; bar->is_64 = is_64; // Check if firmware placed this window in a prefetchable region (should always be true for prefetchable windows) bar->firmware_in_prefetchable = is_address_in_prefetchable_range(device->root_bus, prefetchable_base); if (!add_bar(device->root_bus, bar)) { printf("add_bar() failed for bridge prefetchable window\n"); goto no_prefetch_range; } } no_prefetch_range:; } for (uint8_t bar = 0; bar < max_bars; ) { uint32_t bar_offset = 0x10 + bar * 4; uint32_t bar_value = pci_read32(&address, bar_offset); // Memory bar layout is as follows: // - bit 0: always 0 // - bit 1-2: bar type (0 is 32-bit, 1 is reserved, 2 is 64-bit) // - bit 3: prefetchable // - bit 4-31: base address bool is_64bit = false; bool prefetchable = false; if ((bar_value & (1 << 0)) != 0) { bar += 1; continue; } // Check the bar type to figure out whether it's a 64-bit bar is_64bit = (bar_value & 0x6) == 0x4; prefetchable = (bar_value & (1 << 3)) != 0; // Mask out the flag bits to get the bar address uint64_t base = bar_value & 0xFFFFFFF0; // If the bar is 64-bit then read the next bar's base address // and OR that into our current bar's base address - 64-bit bars // are made up of two consecutive bars to form a 64-bit address if (bar != max_bars - 1 && is_64bit) { uint32_t next_bar = pci_read32(&address, bar_offset + 0x4); base |= (uint64_t)next_bar << 32; } // Disable bus master, memory and IO decoding to prevent the device // from mistakenly responding to our PCI config space accesses uint8_t cmd = pci_read8(&address, 0x4); uint8_t new_cmd = cmd; new_cmd &= ~(1 << 0); // IO space decoding new_cmd &= ~(1 << 1); // Memory space decoding new_cmd &= ~(1 << 2); // Bus master pci_write8(&address, 0x4, new_cmd); // Discover the bar length pci_write32(&address, bar_offset, 0xFFFFFFFF); uint32_t response = pci_read32(&address, bar_offset); pci_write32(&address, bar_offset, bar_value); uint64_t length = response & 0xFFFFFFF0; if (bar != max_bars - 1 && is_64bit) { uint32_t next_bar = pci_read32(&address, bar_offset + 0x4); pci_write32(&address, bar_offset + 0x4, 0xFFFFFFFF); uint32_t response_hi = pci_read32(&address, bar_offset + 0x4); pci_write32(&address, bar_offset + 0x4, next_bar); length |= (uint64_t)response_hi << 32; } else { length |= 0xffffffff00000000; } length = ~length + 1; // Restore command register pci_write8(&address, 0x4, cmd); // Skip unimplemented BARs. For 64-bit BARs, lower-half response==0 // is legitimate when size >= 4GB (size bits live in the upper half). if (length == 0 || (!is_64bit && response == 0)) { goto next_bar; } // If BAR is larger than the classic 256MB limit, try to resize it // 256MB was the standard GPU framebuffer BAR size before Resizable BAR if (length > 256 * 1024 * 1024) { uint64_t max_resize = 256 * 1024 * 1024; // 256 MB - classic pre-ReBAR size uint64_t new_length = pci_try_resize_bar(&address, bar, max_resize); if (new_length > 0 && new_length < length) { printf("Resized BAR%d from %llu MB to %llu MB\n", bar, length / (1024 * 1024), new_length / (1024 * 1024)); length = new_length; } else { printf("BAR%d too large (%llu MB) and resize failed, skipping\n", bar, length / (1024 * 1024)); goto next_bar; } } if (base != 0) { struct pci_bar *bar_info = allocate_bar(); if (bar_info == NULL) { printf("allocate_bar() failed for device %04x:%02x:%02x.%02x BAR%d\n", device->root_bus->segment, device->root_bus->bus, device->slot, device->function, bar); goto next_bar; } bar_info->device = device; bar_info->bar_number = bar; bar_info->base = base; bar_info->length = length; bar_info->prefetchable = prefetchable; bar_info->is_64 = is_64bit; // Check if firmware placed this BAR in a prefetchable region bar_info->firmware_in_prefetchable = is_address_in_prefetchable_range(device->root_bus, base); if (!add_bar(device->root_bus, bar_info)) { printf("add_bar() failure\n"); } if (prefetchable) { device->root_bus->required_prefetchable_size += length; } else { device->root_bus->required_non_prefetchable_size += length; } } next_bar: if (is_64bit) { bar += 2; } else { bar += 1; } } return true; } static bool scan_bus(struct pci_bus *bus); static bool scan_function(struct pci_bus *bus, struct pci_address *address) { uint8_t subclass = pci_read8(address, 0xA); uint8_t class = pci_read8(address, 0xB); struct pci_device *device = allocate_device(); if (device == NULL) { printf("allocate_device() failed for %04x:%02x:%02x.%02x\n", address->segment, address->bus, address->slot, address->function); return false; } device->root_bus = bus; device->slot = address->slot; device->function = address->function; struct pci_bus *bridge_bus = NULL; if (class == 0x6 && subclass == 0x4) { bridge_bus = allocate_bus(); if (bridge_bus == NULL) { printf("allocate_bus() failed for bridge %04x:%02x:%02x.%02x\n", address->segment, address->bus, address->slot, address->function); // Continue without scanning behind this bridge goto not_a_bridge; } uint8_t secondary_bus = pci_read8(address, 0x19); bridge_bus->segment = address->segment; bridge_bus->bus = secondary_bus; if (!scan_bus(bridge_bus)) { printf("scan_bus() failure\n"); } // Propagate required sizes from child bus to parent bus // This ensures nested bridge windows are sized correctly bus->required_prefetchable_size += bridge_bus->required_prefetchable_size; bus->required_non_prefetchable_size += bridge_bus->required_non_prefetchable_size; device->type = PCI_DEVICE_BRIDGE; device->bridge_bus = bridge_bus; } else { not_a_bridge: device->type = PCI_DEVICE_REGULAR; device->bridge_bus = NULL; } if (!scan_bars(device)) { printf("scan_bars() failure\n"); } if (bridge_bus != NULL && bridge_bus->range_count == 0) { device->bridge_bus = NULL; } if (!add_device(bus, device)) { printf("add_device() failure\n"); } return true; } static bool scan_slot(struct pci_bus *bus, struct pci_address *address) { uint16_t vendor_id = pci_read16(address, 0x0); // No device on this slot, return if (vendor_id == 0xFFFF) { return true; } if (!scan_function(bus, address)) { printf("scan_function() failure\n"); } // Check if device is multi-function uint8_t header_type = pci_read8(address, 0xE); if (!(header_type & 0x80)) { return true; } for (uint8_t func = 1; func < 8; func++) { struct pci_address func_addr = *address; func_addr.function = func; vendor_id = pci_read16(&func_addr, 0x0); if (vendor_id == 0xFFFF){ continue; } if (!scan_function(bus, &func_addr)) { printf("scan_function() failure\n"); } } return true; } static bool scan_bus(struct pci_bus *bus) { for (uint8_t slot = 0; slot < 32; slot++) { struct pci_address address; address.segment = bus->segment; address.bus = bus->bus; address.slot = slot; address.function = 0; if (!scan_slot(bus, &address)) { printf("scan_slot() failure\n"); } } return true; } static void pretty_print_bus(struct pci_bus *bus, int indent) { printf("%-*s%s, segment=%d, bus=%d, range_count=%zu, device_count=%zu, bar_count=%zu\n", (int)(indent * 2), "", bus->root ? "root bus" : "bridge bus", bus->segment, bus->bus, bus->range_count, bus->device_count, bus->bar_count); printf("%-*srequired prefetchable size=0x%llx\n", (int)(indent * 2), "", bus->required_prefetchable_size); printf("%-*srequired non-prefetchable size=0x%llx\n", (int)(indent * 2), "", bus->required_non_prefetchable_size); for (size_t i = 0; i < bus->range_count; i++) { struct pci_range *range = &bus->ranges[i]; if (range->length == 0) { continue; } printf("%-*srange %zu: base=0x%llx, length=0x%llx [%llx-%llx] (%sprefetchable)\n", (int)((indent + 1) * 2), "", i, range->base, range->length, range->base, range->base + range->length - 1, range->prefetchable ? "" : "non-"); } for (size_t i = 0; i < bus->device_count; i++) { struct pci_device *device = bus->devices[i]; struct pci_address address; address.segment = device->root_bus->segment; address.bus = device->root_bus->bus; address.slot = device->slot; address.function = device->function; uint16_t vendor = pci_read16(&address, 0x0); uint16_t product = pci_read16(&address, 0x2); uint8_t subclass = pci_read8(&address, 0xA); uint8_t class = pci_read8(&address, 0xB); printf("%-*sdevice %zu: type=%s, address=%04x:%02x:%02x.%02x, vendor=%04x, product=%04x, subclass=%d, class=%d\n", (int)((indent + 1) * 2), "", i, device->type == PCI_DEVICE_BRIDGE ? "bridge" : "device", bus->segment, bus->bus, device->slot, device->function, vendor, product, subclass, class); if (device->bridge_bus != NULL) { pretty_print_bus(device->bridge_bus, indent + 2); } } for (size_t j = 0; j < bus->bar_count; j++) { struct pci_bar *bar = bus->bars[j]; printf("%-*sbar%d: device_address=%04x:%02x:%02x.%02x, base=0x%llx, length=0x%llx\n", (int)((indent + 1) * 2), "", bar->bar_number, bus->segment, bus->bus, bar->device->slot, bar->device->function, bar->base, bar->length); printf("%-*s\t [%llx-%llx] (%sprefetchable, %s-bit)\n", (int)((indent + 1) * 2), "", bar->base, bar->base + bar->length - 1, bar->prefetchable ? "" : "non-", bar->is_64 ? "64" : "32"); } } static uacpi_iteration_decision uacpi_discover_root_bus(void *user, uacpi_namespace_node *node, uacpi_u32 node_depth) { (void)node_depth; uacpi_resources *resources = NULL; uacpi_iteration_decision decision = UACPI_ITERATION_DECISION_CONTINUE; uacpi_status status = UACPI_STATUS_OK; status = uacpi_get_current_resources(node, &resources); if (status != UACPI_STATUS_OK) { printf("Failed to get node resources: %s\n", uacpi_status_to_string(status)); goto cleanup; } struct pci_bus *root_bus = allocate_bus(); if (root_bus == NULL) { printf("allocate_bus() failure\n"); goto cleanup; } uint64_t segment = 0, bus_number = 0; uacpi_eval_simple_integer(node, "_SEG", &segment); uacpi_eval_simple_integer(node, "_BBN", &bus_number); root_bus->root = true; root_bus->segment = segment; root_bus->bus = bus_number; uacpi_resource *res = resources->entries; while ((void *)res < (void *)resources->entries + resources->length) { if (res->type == UACPI_RESOURCE_TYPE_END_TAG) { break; } switch (res->type) { case UACPI_RESOURCE_TYPE_IO: case UACPI_RESOURCE_TYPE_FIXED_IO: // We don't care about IO regions break; case UACPI_RESOURCE_TYPE_ADDRESS16: if (res->address16.common.type != UACPI_RANGE_MEMORY || res->address16.address_length < 0x1000) break; if (!add_range(root_bus, res->address16.minimum, res->address16.address_length, res->address16.common.attribute.memory.caching != UACPI_NON_CACHEABLE)) { printf("add_range() failure\n"); } break; case UACPI_RESOURCE_TYPE_ADDRESS32: if (res->address32.common.type != UACPI_RANGE_MEMORY || res->address32.address_length < 0x1000) break; if (!add_range(root_bus, res->address32.minimum, res->address32.address_length, res->address32.common.attribute.memory.caching != UACPI_NON_CACHEABLE)) { printf("add_range() failure\n"); } break; case UACPI_RESOURCE_TYPE_ADDRESS64: if (res->address64.common.type != UACPI_RANGE_MEMORY || res->address64.address_length < 0x1000) break; if (!add_range(root_bus, res->address64.minimum, res->address64.address_length, res->address64.common.attribute.memory.caching != UACPI_NON_CACHEABLE)) { printf("add_range() failure\n"); } break; default: printf("Unknown PCI root bus resource type %u\n", res->type); break; } res = UACPI_NEXT_RESOURCE(res); } if (!add_root_bus(root_bus)) { goto cleanup; } goto out; cleanup: decision = UACPI_ITERATION_DECISION_BREAK; out: if (resources != NULL) { uacpi_free_resources(resources); } *(uacpi_status *)user = status; return decision; } static bool uacpi_discover_root_bridges(void) { uacpi_status status; uacpi_status iter_status = UACPI_STATUS_OK; status = uacpi_find_devices_at( uacpi_namespace_get_predefined(UACPI_PREDEFINED_NAMESPACE_SB), (const char *[]){"PNP0A03", "PNP0A08", NULL}, uacpi_discover_root_bus, &iter_status); if (iter_status != UACPI_STATUS_OK) { status = iter_status; } if (status != UACPI_STATUS_OK) { printf("uACPI find devices failed: %s\n", uacpi_status_to_string(status)); return false; } return true; } size_t pci_get_extra_root_buses(uint8_t *out, size_t cap) { size_t written = 0; for (size_t i = 0; i < root_bus_count; i++) { struct pci_bus *bus = root_buses[i]; // SeaBIOS only enumerates segment 0 in real-mode CSM; segment != 0 // roots can't be reached via legacy CF8/CFC anyway. if (bus->segment != 0) continue; if (bus->bus == 0) continue; if (written >= cap) return 0; out[written++] = bus->bus; } return written; } bool pci_early_initialize(void) { if (gBS->AllocatePool(EfiLoaderData, sizeof(struct pci_bus) * BUS_STRUCT_POOL_COUNT, (void *)&bus_struct_pool) != EFI_SUCCESS) { return false; } memset(bus_struct_pool, 0, sizeof(struct pci_bus) * BUS_STRUCT_POOL_COUNT); if (gBS->AllocatePool(EfiLoaderData, sizeof(struct pci_device) * DEVICE_STRUCT_POOL_COUNT, (void *)&device_struct_pool) != EFI_SUCCESS) { return false; } memset(device_struct_pool, 0, sizeof(struct pci_device) * DEVICE_STRUCT_POOL_COUNT); if (gBS->AllocatePool(EfiLoaderData, sizeof(struct pci_bar) * BAR_STRUCT_POOL_COUNT, (void *)&bar_struct_pool) != EFI_SUCCESS) { return false; } memset(bar_struct_pool, 0, sizeof(struct pci_bar) * BAR_STRUCT_POOL_COUNT); if (!acpi_namespace_init()) { return false; } // Parse MCFG table to enable ECAM config access (optional, falls back to PIO) parse_mcfg_table(); if (!uacpi_discover_root_bridges()) { return false; } printf("discovered %zu root buses\n", root_bus_count); return true; } // Check if any BAR on this bus or its child buses is above 4GB static bool has_bars_above_4g(struct pci_bus *bus) { // Check BARs on this bus for (size_t i = 0; i < bus->bar_count; i++) { if (bus->bars[i]->base >= 0x100000000ULL) { return true; } } // Recursively check child buses (bridges) for (size_t i = 0; i < bus->device_count; i++) { struct pci_device *device = bus->devices[i]; if (device->bridge_bus != NULL) { if (has_bars_above_4g(device->bridge_bus)) { return true; } } } return false; } static bool resize_bridge_windows(struct pci_bus *bus) { // First, recursively resize all child bridge windows (bottom-up order). // This ensures that when we size this level's windows, child windows // have already been resized and we can use their actual sizes. for (size_t i = 0; i < bus->bar_count; i++) { if (bus->bars[i]->range == NULL) { continue; } struct pci_device *device = bus->bars[i]->device; if (device->bridge_bus != NULL) { resize_bridge_windows(device->bridge_bus); } } // Now resize this level's bridge windows again: for (size_t i = 0; i < bus->bar_count; i++) { if (bus->bars[i]->range == NULL) { continue; } struct pci_bar *bar = bus->bars[i]; struct pci_device *device = bar->device; struct pci_range *range = bar->range; struct pci_bus *bridge_bus = device->bridge_bus; // Compute required size: sum of regular BARs + sum of (already resized) child bridge windows uint64_t new_size = 0; for (size_t j = 0; j < bridge_bus->bar_count; j++) { struct pci_bar *child_bar = bridge_bus->bars[j]; if (child_bar->prefetchable != range->prefetchable) { continue; } new_size += child_bar->length; } struct pci_address address; address.segment = device->root_bus->segment; address.bus = device->root_bus->bus; address.slot = device->slot; address.function = device->function; // Read from correct registers based on window type uint8_t base_reg = range->prefetchable ? 0x24 : 0x20; uint8_t limit_reg = range->prefetchable ? 0x26 : 0x22; uint64_t raw_base = pci_read16(&address, base_reg); uint64_t raw_limit = pci_read16(&address, limit_reg); // Only prefetchable windows have the 64-bit type field (bits 0-3) bool is_64 = range->prefetchable && ((raw_base & 0xf) == 0x1); printf("new_size=%llx\n", new_size); if (new_size == 0) { printf("dropping %sprefetchable window of bridge device %04x:%02x:%02x.%02x\n", range->prefetchable ? "" : "non-", bus->segment, bus->bus, device->slot, device->function); pci_write16(&address, base_reg, 0x10 | (raw_base & 0xf)); pci_write16(&address, limit_reg, raw_limit & 0xf); if (is_64) { pci_write32(&address, 0x28, 0); pci_write32(&address, 0x2c, 0); } drop_range(bridge_bus, range); drop_bar(bus, bar); goto again; } // Round up window size to 1MB (bridge window granularity). // The window will be aligned to largest child BAR during relocation, // so children will naturally land on aligned addresses. new_size = ALIGN_UP(new_size, 0x100000); printf("resizing %sprefetchable window of bridge device %04x:%02x:%02x.%02x from %llx to %llx\n", range->prefetchable ? "" : "non-", bus->segment, bus->bus, device->slot, device->function, bar->length, new_size); uint64_t new_limit = range->base + new_size - 1; pci_write16(&address, limit_reg, ((new_limit >> 16) & 0xfff0) | (raw_limit & 0x000f)); if (is_64) { pci_write32(&address, 0x2c, new_limit >> 32); } range->length = new_size; bar->length = new_size; } return true; } bool pci_late_initialize(void) { for (size_t i = 0; i < root_bus_count; i++) { if (!scan_bus(root_buses[i])) { printf("scan_bus() failure\n"); } } // Save and disable Flanterm during relocation. // When we relocate bridge windows, the address range the bridge forwards changes, // so accessing the framebuffer at the old address will fail even before we // relocate the VGA BAR itself. Disabling Flanterm prevents crashes during this phase. uint64_t old_fb_addr = priv.cb_fb.physical_address; struct flanterm_context *saved_flanterm_ctx = flanterm_ctx; flanterm_ctx = NULL; for (size_t i = 0; i < root_bus_count; i++) { struct pci_bus *bus = root_buses[i]; // Check if this root bus needs relocation if (!has_bars_above_4g(bus)) { printf("Root bus %u: all BARs below 4GB, skipping relocation\n", bus->bus); continue; } printf("Root bus %u: found BARs above 4GB, performing relocation...\n", bus->bus); pretty_print_bus(bus, 0); printf("---------------\n"); resize_bridge_windows(bus); sort_bars(bus); reallocate_bars(bus); printf("---------------\n"); pretty_print_bus(bus, 0); } // Update Flanterm's framebuffer pointer if it was relocated if (saved_flanterm_ctx != NULL && priv.cb_fb.physical_address != old_fb_addr) { ((struct flanterm_fb_context *)saved_flanterm_ctx)->framebuffer = (void *)(uintptr_t)priv.cb_fb.physical_address; } // Re-enable Flanterm flanterm_ctx = saved_flanterm_ctx; if (priv.cb_fb.physical_address >= 0x100000000ULL) { panic("Framebuffer at 0x%llx is above 4GB and could not be relocated\n", priv.cb_fb.physical_address); } return true; } ================================================ FILE: src/pci.h ================================================ #ifndef PCI_H #define PCI_H #include #include #include struct pci_address { uint16_t segment; uint8_t bus; uint8_t slot; uint8_t function; }; struct pci_range { uint64_t base; uint64_t length; uint64_t reloc_ptr; bool prefetchable; }; enum pci_device_type { PCI_DEVICE_REGULAR, PCI_DEVICE_BRIDGE, }; struct pci_device { // Type of the device enum pci_device_type type; // The root bus that this device is on struct pci_bus *root_bus; // A bus if a device is a bridge. struct pci_bus *bridge_bus; // Address of the device on the bus uint8_t slot; uint8_t function; int reallocated_windows; }; struct pci_bar { // The PCI device that this bar belongs to struct pci_device *device; // The bar number in context of the device uint8_t bar_number; bool is_64; bool prefetchable; // If true, firmware originally placed this BAR in a prefetchable region. // This allows non-prefetchable BARs to be relocated to prefetchable ranges // if the firmware deemed it safe for this particular device. bool firmware_in_prefetchable; // Base address and size of the bar uint64_t base; uint64_t length; // Range associated with bridge window pseudo-BARs. struct pci_range *range; }; #define PCI_MAX_RANGES_PER_BUS 32 #define PCI_MAX_DEVICES_PER_BUS 256 #define PCI_MAX_BARS_PER_BUS 512 struct pci_bus { bool root; uint32_t segment; uint8_t bus; // Sorted list of address ranges this root bus decodes size_t range_count; struct pci_range ranges[PCI_MAX_RANGES_PER_BUS]; // List of devices associated with this root bus size_t device_count; struct pci_device *devices[PCI_MAX_DEVICES_PER_BUS]; // Sorted list of allocated bars associated with this root bus size_t bar_count; struct pci_bar *bars[PCI_MAX_BARS_PER_BUS]; uint64_t required_prefetchable_size; uint64_t required_non_prefetchable_size; }; #define pci_read8(address, offset) ((uint8_t)pci_read_config_space((address), (offset), 1)) #define pci_read16(address, offset) ((uint16_t)pci_read_config_space((address), (offset), 2)) #define pci_read32(address, offset) pci_read_config_space((address), (offset), 4) #define pci_write8(address, offset, value) pci_write_config_space((address), (offset), 1, (value)) #define pci_write16(address, offset, value) pci_write_config_space((address), (offset), 2, (value)) #define pci_write32(address, offset, value) pci_write_config_space((address), (offset), 4, (value)) // Read `size` bytes (1, 2 or 4) from PCI config space. The access goes through // at the requested width so that dword-only RMW does not silently clobber // RW1C bits sharing the same dword (e.g. Status next to Command). uint32_t pci_read_config_space(struct pci_address *address, uint32_t offset, uint32_t size); // Write `size` bytes (1, 2 or 4) to PCI config space. void pci_write_config_space(struct pci_address *address, uint32_t offset, uint32_t size, uint32_t value); // Discover PCI root buses and devices behind them. bool pci_early_initialize(void); bool pci_late_initialize(void); // Force I/O space, memory space, and bus master enable on a device whose // option ROM is about to be dispatched. Legacy oproms expect their device // fully usable; UEFI may have left bus master off (or even MEM/IO off if // the device was inactive in UEFI). void pci_enable_for_oprom(uint8_t bus, uint8_t devfn); // Copy the bus numbers of every discovered root bus other than bus 0 into // `out` (capacity `cap` bytes). Returns the number of entries written; if // the buffer is too small, returns 0 without writing anything. size_t pci_get_extra_root_buses(uint8_t *out, size_t cap); #endif ================================================ FILE: src/pir.c ================================================ /* * $PIR (PCI IRQ Routing) Table Generation * * Synthesizes a PCI BIOS Specification 2.1 $PIR table from ACPI _PRT * (PCI Routing Table) and _PRS (Possible Resource Settings) evaluations, * allocates it below 4 GiB, and points the CSM's IrqRoutingTablePointer at * it. SeaBIOS picks up the pointer in handle_csm_0002 and serves it back to * legacy callers via INT 1Ah AX=B406h ("Get PCI IRQ Routing Options"). */ #include #include #include "csmwrap.h" #include "pir.h" #include "io.h" #include #include #include #include #include #include #define PIR_SIGNATURE 0x52495024 /* "$PIR" */ #define PIR_VERSION 0x0100 /* * Per-pin "any free legacy IRQ" bitmap used when the actual routing isn't * representable in 8259 IRQ space (e.g. a static GSI >= 16, or a link * device with no _PRS). Bits 3,4,5,7,9,10,11,12,14,15 - the IRQs * traditionally available for PCI assignment on a PC/AT. */ #define LEGACY_PCI_IRQ_BITMAP 0xDEB8 #define MAX_PIR_SLOTS 256 #define MAX_PCI_BUSES 32 #define MAX_LINK_DEVICES 32 #pragma pack(1) struct pir_link_info { uint8_t link; uint16_t bitmap; }; struct pir_slot { uint8_t bus; uint8_t dev; /* PCI device number << 3 */ struct pir_link_info pins[4]; /* INTA, INTB, INTC, INTD */ uint8_t slot_nr; uint8_t reserved; }; struct pir_header { uint32_t signature; uint16_t version; uint16_t size; uint8_t router_bus; uint8_t router_devfunc; uint16_t exclusive_irqs; uint32_t compatible_devid; uint32_t miniport_data; uint8_t reserved[11]; uint8_t checksum; }; #pragma pack() struct pci_bus_info { uacpi_namespace_node *node; uint8_t bus_num; }; static struct { struct pci_bus_info buses[MAX_PCI_BUSES]; size_t count; } pir_buses; static struct pir_slot slots[MAX_PIR_SLOTS]; static size_t slot_count; struct link_device_entry { uacpi_namespace_node *node; uint8_t link_id; uint16_t bitmap; }; static struct { struct link_device_entry entries[MAX_LINK_DEVICES]; size_t count; } pir_link_devices; /* Read PCI vendor ID via legacy PIO; matches the helper in mptable.c. */ static bool pci_device_exists(uint8_t bus, uint8_t dev, uint8_t func) { uint32_t addr = 0x80000000 | (bus << 16) | (dev << 11) | (func << 8); outl(0xCF8, addr); uint16_t vendor = inw(0xCFC); return vendor != 0xFFFF; } /* Callback for root bridge discovery (PNP0A03 / PNP0A08). */ static uacpi_iteration_decision discover_root_bus_callback( void *user, uacpi_namespace_node *node, uacpi_u32 depth) { (void)user; (void)depth; if (pir_buses.count >= MAX_PCI_BUSES) return UACPI_ITERATION_DECISION_CONTINUE; uacpi_u64 bus_num = 0; uacpi_eval_integer(node, "_BBN", UACPI_NULL, &bus_num); /* Skip duplicates (some firmware lists the same bus more than once). */ for (size_t i = 0; i < pir_buses.count; i++) { if (pir_buses.buses[i].bus_num == (uint8_t)bus_num) return UACPI_ITERATION_DECISION_CONTINUE; } pir_buses.buses[pir_buses.count].node = node; pir_buses.buses[pir_buses.count].bus_num = (uint8_t)bus_num; pir_buses.count++; return UACPI_ITERATION_DECISION_CONTINUE; } /* Callback for secondary buses with their own _PRT under a root bridge. */ static uacpi_iteration_decision discover_secondary_callback( void *user, uacpi_namespace_node *node, uacpi_u32 node_depth) { (void)node_depth; uint8_t parent_bus = *(uint8_t *)user; if (pir_buses.count >= MAX_PCI_BUSES) return UACPI_ITERATION_DECISION_CONTINUE; /* Only interested in nodes with their own _PRT (i.e. PCI-PCI bridges). */ uacpi_namespace_node *prt_node = UACPI_NULL; uacpi_status st = uacpi_namespace_node_find(node, "_PRT", &prt_node); if (st != UACPI_STATUS_OK || !prt_node) return UACPI_ITERATION_DECISION_CONTINUE; uacpi_u64 adr = 0; if (uacpi_eval_integer(node, "_ADR", UACPI_NULL, &adr) != UACPI_STATUS_OK) return UACPI_ITERATION_DECISION_CONTINUE; uint8_t dev = (adr >> 16) & 0x1F; uint8_t func = adr & 0x7; if (!pci_device_exists(parent_bus, dev, func)) return UACPI_ITERATION_DECISION_CONTINUE; /* Read secondary bus number from PCI bridge config (offset 0x19). */ uint8_t secondary_bus = pciConfigReadByte(parent_bus, dev, func, 0x19); pir_buses.buses[pir_buses.count].node = node; pir_buses.buses[pir_buses.count].bus_num = secondary_bus; pir_buses.count++; return UACPI_ITERATION_DECISION_CONTINUE; } static void discover_secondary_buses(uacpi_namespace_node *root_bridge, uint8_t parent_bus) { uacpi_namespace_for_each_child( root_bridge, discover_secondary_callback, UACPI_NULL, UACPI_OBJECT_DEVICE_BIT, 3, &parent_bus); } static void discover_pci_buses(void) { pir_buses.count = 0; uacpi_namespace_node *sb_node = uacpi_namespace_get_predefined(UACPI_PREDEFINED_NAMESPACE_SB); if (!sb_node) { printf("pir: _SB not found, cannot discover PCI buses\n"); return; } const uacpi_char *hids[] = { "PNP0A03", "PNP0A08", UACPI_NULL }; uacpi_find_devices_at(sb_node, hids, discover_root_bus_callback, UACPI_NULL); size_t root_count = pir_buses.count; for (size_t i = 0; i < root_count; i++) { discover_secondary_buses(pir_buses.buses[i].node, pir_buses.buses[i].bus_num); } } /* Find the first PCI ISA bridge (class 0x06, subclass 0x01) to use as * router. Falls back to (0, 0, 0) - the host bridge - if none found. */ static bool find_isa_bridge(uint8_t *out_bus, uint8_t *out_devfn) { for (size_t b = 0; b < pir_buses.count; b++) { uint8_t bus = pir_buses.buses[b].bus_num; for (uint8_t dev = 0; dev < 32; dev++) { for (uint8_t func = 0; func < 8; func++) { if (!pci_device_exists(bus, dev, func)) { if (func == 0) break; continue; } uint8_t class_code = pciConfigReadByte(bus, dev, func, 0x0B); uint8_t subclass = pciConfigReadByte(bus, dev, func, 0x0A); if (class_code == 0x06 && subclass == 0x01) { *out_bus = bus; *out_devfn = (uint8_t)((dev << 3) | func); return true; } if (func == 0) { uint8_t header = pciConfigReadByte(bus, dev, func, 0x0E); if (!(header & 0x80)) break; } } } } return false; } /* Get an existing slot for (bus, dev) or create a new one. dev is already * shifted left by 3 to match the $PIR encoding. */ static struct pir_slot *get_or_create_slot(uint8_t bus, uint8_t dev_shifted) { for (size_t i = 0; i < slot_count; i++) { if (slots[i].bus == bus && slots[i].dev == dev_shifted) return &slots[i]; } if (slot_count >= MAX_PIR_SLOTS) return NULL; struct pir_slot *s = &slots[slot_count++]; memset(s, 0, sizeof(*s)); s->bus = bus; s->dev = dev_shifted; return s; } /* Accumulate possible IRQs (< 16) into a 16-bit bitmap from a link * device's _PRS. */ struct prs_ctx { uint16_t bitmap; }; static uacpi_iteration_decision link_prs_callback(void *user, uacpi_resource *resource) { struct prs_ctx *ctx = user; if (resource->type == UACPI_RESOURCE_TYPE_IRQ) { for (uint8_t i = 0; i < resource->irq.num_irqs; i++) { if (resource->irq.irqs[i] < 16) ctx->bitmap |= (uint16_t)(1u << resource->irq.irqs[i]); } } else if (resource->type == UACPI_RESOURCE_TYPE_EXTENDED_IRQ) { for (uint8_t i = 0; i < resource->extended_irq.num_irqs; i++) { if (resource->extended_irq.irqs[i] < 16) ctx->bitmap |= (uint16_t)(1u << resource->extended_irq.irqs[i]); } } return UACPI_ITERATION_DECISION_CONTINUE; } /* Look up an existing link device or assign a new link ID and evaluate _PRS * for its possible-IRQ bitmap. Link IDs start at 0x80 to leave the lower * range for static-GSI link IDs. */ static uint8_t get_link_id(uacpi_namespace_node *link, uint16_t *bitmap_out) { for (size_t i = 0; i < pir_link_devices.count; i++) { if (pir_link_devices.entries[i].node == link) { *bitmap_out = pir_link_devices.entries[i].bitmap; return pir_link_devices.entries[i].link_id; } } if (pir_link_devices.count >= MAX_LINK_DEVICES) { *bitmap_out = LEGACY_PCI_IRQ_BITMAP; return 0; } struct prs_ctx ctx = { .bitmap = 0 }; uacpi_for_each_device_resource(link, "_PRS", link_prs_callback, &ctx); if (ctx.bitmap == 0) ctx.bitmap = LEGACY_PCI_IRQ_BITMAP; uint8_t link_id = (uint8_t)(0x80 + pir_link_devices.count); pir_link_devices.entries[pir_link_devices.count].node = link; pir_link_devices.entries[pir_link_devices.count].link_id = link_id; pir_link_devices.entries[pir_link_devices.count].bitmap = ctx.bitmap; pir_link_devices.count++; *bitmap_out = ctx.bitmap; return link_id; } bool pir_init(struct csmwrap_priv *priv) { printf("pir: building $PIR table\n"); slot_count = 0; pir_link_devices.count = 0; discover_pci_buses(); if (pir_buses.count == 0) { printf("pir: no PCI buses discovered, skipping $PIR\n"); return false; } uint8_t router_bus = 0, router_devfunc = 0; if (!find_isa_bridge(&router_bus, &router_devfunc)) { printf("pir: no ISA bridge found, using host bridge as router\n"); } /* Walk _PRT for each bus; group entries by (bus, dev) into slots. */ for (size_t bi = 0; bi < pir_buses.count; bi++) { struct pci_bus_info *binfo = &pir_buses.buses[bi]; uacpi_pci_routing_table *prt = NULL; if (uacpi_get_pci_routing_table(binfo->node, &prt) != UACPI_STATUS_OK || !prt) continue; for (size_t i = 0; i < prt->num_entries; i++) { uacpi_pci_routing_table_entry *e = &prt->entries[i]; uint8_t dev = (uint8_t)((e->address >> 16) & 0x1F); uint8_t pin = (uint8_t)e->pin; if (pin > 3) continue; struct pir_slot *slot = get_or_create_slot(binfo->bus_num, (uint8_t)(dev << 3)); if (!slot) { printf("pir: too many slots, truncating\n"); uacpi_free_pci_routing_table(prt); goto prt_done; } uint8_t link; uint16_t bitmap; if (e->source == NULL) { /* Static GSI: link ID = GSI (truncated to 8 bits, fine for * the typical < 256 GSI range), bitmap reflects the actual * IRQ when representable. */ link = (uint8_t)e->index; bitmap = (e->index < 16) ? (uint16_t)(1u << e->index) : LEGACY_PCI_IRQ_BITMAP; } else { link = get_link_id(e->source, &bitmap); } slot->pins[pin].link = link; slot->pins[pin].bitmap = bitmap; } uacpi_free_pci_routing_table(prt); } prt_done: if (slot_count == 0) { printf("pir: no _PRT entries found, skipping $PIR\n"); return false; } size_t table_size = sizeof(struct pir_header) + slot_count * sizeof(struct pir_slot); /* Allocate below 4 GiB - IrqRoutingTablePointer is 32 bits. * EfiRuntimeServicesData becomes E820 RESERVED so the OS won't reclaim * it; SeaBIOS dereferences PirAddr on demand from INT 1Ah callers. */ EFI_PHYSICAL_ADDRESS table_addr = 0xFFFFFFFF; EFI_STATUS status = gBS->AllocatePages( AllocateMaxAddress, EfiRuntimeServicesData, (table_size + 4095) / 4096, &table_addr); if (EFI_ERROR(status)) { printf("pir: failed to allocate memory for $PIR\n"); return false; } memset((void *)(uintptr_t)table_addr, 0, table_size); struct pir_header *hdr = (struct pir_header *)(uintptr_t)table_addr; hdr->signature = PIR_SIGNATURE; hdr->version = PIR_VERSION; hdr->size = (uint16_t)table_size; hdr->router_bus = router_bus; hdr->router_devfunc = router_devfunc; hdr->exclusive_irqs = 0; hdr->compatible_devid = 0; hdr->miniport_data = 0; struct pir_slot *out_slots = (struct pir_slot *)(hdr + 1); memcpy(out_slots, slots, slot_count * sizeof(struct pir_slot)); /* Checksum: sum of all bytes (including checksum field) must be 0. */ uint8_t sum = 0; uint8_t *bytes = (uint8_t *)hdr; for (size_t i = 0; i < table_size; i++) sum += bytes[i]; hdr->checksum = (uint8_t)(-sum); priv->csm_efi_table->IrqRoutingTablePointer = (uint32_t)table_addr; priv->csm_efi_table->IrqRoutingTableLength = (uint32_t)table_size; printf("pir: $PIR built at 0x%lx, %zu slots, %zu bytes " "(router %02x:%02x.%x, %zu link device(s))\n", (unsigned long)table_addr, slot_count, table_size, router_bus, router_devfunc >> 3, router_devfunc & 7, pir_link_devices.count); return true; } ================================================ FILE: src/pir.h ================================================ #ifndef _PIR_H #define _PIR_H #include #include "csmwrap.h" /* * Build a $PIR (PCI IRQ Routing) table from ACPI _PRT and _PRS evaluations, * allocate it below 4 GiB, and write the address/length into the CSM's * EFI_COMPATIBILITY16_TABLE so SeaBIOS can hand it out via INT 1Ah AX=B406h. * * Must be called before ExitBootServices (uses gBS->AllocatePages and uACPI). * Returns true on success, false if no _PRT entries were found or allocation * failed - in which case the field stays zero and SeaBIOS reports the * function as unsupported. */ bool pir_init(struct csmwrap_priv *priv); #endif /* _PIR_H */ ================================================ FILE: src/printf.c ================================================ #include #include #include #include #define NANOPRINTF_IMPLEMENTATION #define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 0 #define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 #define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 1 #include #include #include #include #include #include #include struct flanterm_context *flanterm_ctx = NULL; static EFI_SERIAL_IO_PROTOCOL *serial_protocol = NULL; static bool serial_protocol_init_done = false; static bool direct_io_initialised = false; static void serial_protocol_initialise(void) { if (serial_protocol_init_done) { return; } serial_protocol_init_done = true; EFI_GUID serial_guid = EFI_SERIAL_IO_PROTOCOL_GUID; if (gBS->LocateProtocol(&serial_guid, NULL, (void **)&serial_protocol)) { serial_protocol = NULL; return; } serial_protocol->Reset(serial_protocol); serial_protocol->SetAttributes( serial_protocol, gConfig.serial_baud, 0, /* ReceiveFifoDepth (default) */ 0, /* Timeout (default) */ NoParity, /* Parity */ 8, /* DataBits */ OneStopBit /* StopBits */ ); } static void serial_direct_io_initialise(void) { if (direct_io_initialised) { return; } uint16_t port = gConfig.serial_port; outb(port + 3, 0x00); outb(port + 1, 0x00); outb(port + 3, 0x80); uint16_t divisor = (uint16_t)(115200 / gConfig.serial_baud); if (divisor == 0) divisor = 1; outb(port + 0, divisor & 0xff); outb(port + 1, (divisor >> 8) & 0xff); /* port+1 is DLM while DLAB=1; clear DLAB before treating it as IER. */ outb(port + 3, 0x03); outb(port + 2, 0xc7); outb(port + 4, 0x0b); direct_io_initialised = true; } static void serial_out(uint8_t b) { if (gBootServicesExited) { serial_direct_io_initialise(); uint16_t port = gConfig.serial_port; while ((inb(port + 5) & 0x20) == 0); outb(port, b); return; } serial_protocol_initialise(); if (serial_protocol == NULL) { return; } UINTN buf_size = 1; serial_protocol->Write(serial_protocol, &buf_size, &b); } static void _putchar(int character, void *extra_arg) { (void)extra_arg; if (character == '\n') { _putchar('\r', NULL); } if (gConfig.serial_debug) { serial_out((uint8_t)character); } if (gConfig.verbose && flanterm_ctx != NULL) { flanterm_write(flanterm_ctx, (const char *)&character, 1); } } int printf(const char *restrict fmt, ...) { va_list l; va_start(l, fmt); int ret = npf_vpprintf(_putchar, NULL, fmt, l); va_end(l); return ret; } int vprintf(const char *restrict fmt, va_list l) { return npf_vpprintf(_putchar, NULL, fmt, l); } int snprintf(char *buffer, size_t bufsz, const char *restrict fmt, ...) { va_list l; va_start(l, fmt); int ret = npf_vsnprintf(buffer, bufsz, fmt, l); va_end(l); return ret; } ================================================ FILE: src/printf.h ================================================ #ifndef PRINTF_H #define PRINTF_H #include #include #include extern struct flanterm_context *flanterm_ctx; int printf(const char *restrict fmt, ...); int vprintf(const char *restrict fmt, va_list l); int snprintf(char *buffer, size_t bufsz, const char *restrict fmt, ...); #endif ================================================ FILE: src/qsort.c ================================================ #include // Function to swap two elements static void swap(void* a, void* b, size_t size) { char buf[16]; char *ca = a, *cb = b; while (size > 0) { size_t chunk = size < sizeof(buf) ? size : sizeof(buf); memcpy(buf, ca, chunk); memcpy(ca, cb, chunk); memcpy(cb, buf, chunk); ca += chunk; cb += chunk; size -= chunk; } } // Partition function static int partition(void* base, size_t size, int (*cmp)(const void*, const void*), int low, int high) { char* arr = (char*)base; void* pivot = arr + high * size; // Choosing the last element as pivot int i = low - 1; // Index of smaller element for (int j = low; j < high; j++) { if (cmp(arr + j * size, pivot) <= 0) { i++; swap(arr + i * size, arr + j * size, size); } } swap(arr + (i + 1) * size, arr + high * size, size); return (i + 1); } // Quick Sort function static void quick_sort(void* base, size_t size, int (*cmp)(const void*, const void*), int low, int high) { if (low < high) { int pi = partition(base, size, cmp, low, high); quick_sort(base, size, cmp, low, pi - 1); quick_sort(base, size, cmp, pi + 1, high); } } // Public interface function void qsort(void* ptr, size_t count, size_t size, int (*comp)(const void*, const void*)) { if (count < 2) { return; } quick_sort(ptr, size, comp, 0, (int)(count - 1)); } ================================================ FILE: src/qsort.h ================================================ #ifndef QSORT_H #define QSORT_H #include void qsort(void *ptr, size_t count, size_t size, int (*comp)(const void *, const void *)); #endif ================================================ FILE: src/time.c ================================================ #include #include #include #include uint64_t tsc_freq; /* TSC ticks per second */ static uint64_t tsc_boot; /* TSC value at calibration time */ /* * Try to determine TSC frequency from CPUID leaves. * Returns frequency in Hz, or 0 if not available. */ static uint64_t tsc_freq_from_cpuid(void) { uint32_t eax, ebx, ecx, edx; /* Check max CPUID leaf */ asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0), "c"(0)); uint32_t max_leaf = eax; /* CPUID leaf 0x15: TSC/Crystal ratio and crystal frequency */ if (max_leaf >= 0x15) { asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x15), "c"(0)); if (eax != 0 && ebx != 0 && ecx != 0) { return (uint64_t)ecx * ebx / eax; } } return 0; } /* * Calibrate TSC frequency. * Prefers CPUID-based detection; falls back to gBS->Stall() calibration. * Must be called before ExitBootServices. */ void calibrate_tsc(void) { tsc_freq = tsc_freq_from_cpuid(); if (tsc_freq == 0) { uint64_t start = rdtsc(); gBS->Stall(1000); /* 1ms */ uint64_t end = rdtsc(); tsc_freq = (end - start) * 1000; } tsc_boot = rdtsc(); } uint64_t get_nanoseconds_since_boot(void) { if (tsc_freq == 0) return 0; uint64_t elapsed = rdtsc() - tsc_boot; uint64_t usec = elapsed / tsc_freq * 1000000 + elapsed % tsc_freq * 1000000 / tsc_freq; return usec * 1000; } void stall(uint64_t us) { uint64_t next_stop = rdtsc() + (tsc_freq * us + 999999) / 1000000; while (rdtsc() < next_stop); } ================================================ FILE: src/time.h ================================================ #ifndef _TIME_H #define _TIME_H #include extern uint64_t tsc_freq; void calibrate_tsc(void); uint64_t get_nanoseconds_since_boot(void); void stall(uint64_t us); #endif ================================================ FILE: src/uacpi_config.h ================================================ #pragma once #include #include #define UACPI_DEFAULT_LOG_LEVEL UACPI_LOG_INFO #define UACPI_DEFAULT_LOOP_TIMEOUT_SECONDS 30 #define UACPI_DEFAULT_MAX_CALL_STACK_DEPTH 256 #define UACPI_USE_BUILTIN_STRING #ifndef __LP64__ #define UACPI_PHYS_ADDR_IS_32BITS #endif #define UACPI_PLAIN_LOG_BUFFER_SIZE 128 #define UACPI_STATIC_TABLE_ARRAY_LEN 128 ================================================ FILE: src/unlock_region.c ================================================ /* * legacy_region_unlock.c * * Implementation of BIOS region unlocking using the UEFI Legacy Region 2 Protocol * with fallback to direct PCI configuration space access for specific chipsets. */ #include #include #include "csmwrap.h" #include "edk2/LegacyRegion2.h" #include "io.h" static EFI_GUID gEfiLegacyRegion2ProtocolGuid = EFI_LEGACY_REGION2_PROTOCOL_GUID; /* * Intel chipset PCI configuration register addresses for PAM * (Programmable Attribute Map) controls */ #define PAM0_REGISTER 0x90 /* Q35 chipset */ #define PAM_LOCK_BIT 0x01 /* Bit indicating PAM registers are locked */ #define PAM_LOCK_REG 0x80 /* Register containing PAM lock bit on newer Intel chipsets */ #define PAM_ENABLE 0x33 /* bits[1:0]=11 (LOENABLE R+W), bits[5:4]=11 (HIENABLE R+W) */ #define PAM0_ENABLE 0x30 /* PAM0 only has HIENABLE; bits[3:0] are reserved/lock */ /* * AMD MTRRs for Legacy Region * This is already here since AMD64 */ #define AMD_AP_MTRR_VARIABLE_BASE0 0x200 #define AMD_AP_MTRR_VARIABLE_BASE6 0x20C #define AMD_AP_MTRR_FIX64k_00000 0x250 #define AMD_AP_MTRR_FIX16k_80000 0x258 #define AMD_AP_MTRR_FIX16k_A0000 0x259 #define AMD_AP_MTRR_FIX4k_C0000 0x268 #define AMD_AP_MTRR_FIX4k_C8000 0x269 #define AMD_AP_MTRR_FIX4k_D0000 0x26A #define AMD_AP_MTRR_FIX4k_D8000 0x26B #define AMD_AP_MTRR_FIX4k_E0000 0x26C #define AMD_AP_MTRR_FIX4k_E8000 0x26D #define AMD_AP_MTRR_FIX4k_F0000 0x26E #define AMD_AP_MTRR_FIX4k_F8000 0x26F #define AMD_MTRR_FIX64K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull #define AMD_MTRR_FIX64K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull #define AMD_MTRR_FIX64K_UC_DRAM 0x1818181818181818ull #define AMD_MTRR_FIX16K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull #define AMD_MTRR_FIX16K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull #define AMD_MTRR_FIX16K_UC_DRAM 0x1818181818181818ull #define AMD_MTRR_FIX4K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull #define AMD_MTRR_FIX4K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull #define AMD_MTRR_FIX4K_UC_DRAM 0x1818181818181818ull #define MSR_SYS_CFG 0xC0010010ul #define SYS_CFG_MTRR_FIX_DRAM_EN (1 << 18) ///< Core::X86::Msr::SYS_CFG::MtrrFixDramEn. ///< MTRR fixed RdDram and WrDram attributes enable. #define SYS_CFG_MTRR_FIX_DRAM_MOD_EN (1 << 19) ///< Core::X86::Msr::SYS_CFG::MtrrFixDramModEn. ///< MTRR fixed RdDram and WrDram modification enable. #define SYS_CFG_MTRR_VAR_DRAM_EN (1 << 20) ///< Core::X86::Msr::SYS_CFG::MtrrVarDramEn. ///< MTRR variable DRAM enable. #define SYS_CFG_MTRR_TOM2_EN (1 << 21) ///< Core::X86::Msr::SYS_CFG::MtrrTom2En. MTRR ///< top of memory 2 enable. #define SYS_CFG_TOM2_FORCE_MEM_TYPE_WB (1 << 22) ///< Core::X86::Msr::SYS_CFG::Tom2ForceMemTypeWB. ///< top of memory 2 memory type write back. /* Intel PCI Vendor ID */ #define INTEL_VENDOR_ID 0x8086 /* AMD Vendor ID */ #define AMD_VENDOR_ID 0x1022 /** * Unlock BIOS memory region using the Legacy Region 2 Protocol * * @return EFI_SUCCESS on success, or an error status code on failure */ EFI_STATUS unlock_legacy_region_protocol(void) { EFI_LEGACY_REGION2_PROTOCOL *legacy_region = NULL; EFI_STATUS status; uint32_t granularity; /* Look for the Legacy Region 2 Protocol */ status = gBS->LocateProtocol( &gEfiLegacyRegion2ProtocolGuid, NULL, (void **)&legacy_region ); if (EFI_ERROR(status)) { printf("Legacy Region 2 Protocol not found (status: %lx)\n", status); return status; } /* * Unlock the entire legacy BIOS region (0xC0000 to 0xFFFFF) * Each region covers 64KB */ /* First enable memory reads in the region */ bool on = TRUE; status = legacy_region->Decode( legacy_region, 0xC0000, /* Start address */ 0x40000, /* Length (256KB) */ &granularity, &on ); if (EFI_ERROR(status)) { printf("Failed to enable memory reads in legacy region (status: %lx)\n", status); return status; } /* Then enable memory writes in the region */ status = legacy_region->UnLock( legacy_region, 0xC0000, /* Start address */ 0x40000, /* Length (256KB) */ &granularity ); if (EFI_ERROR(status)) { printf("Failed to enable memory writes in legacy region (status: %lx)\n", status); return status; } printf("Successfully unlocked legacy region 0xC0000-0xFFFFF using UEFI protocol\n"); printf("Granularity: 0x%x bytes\n", granularity); return EFI_SUCCESS; } /** * Unlock BIOS region using direct PCI configuration space access for piix4 chipset * * @return 0 on success, -1 on failure */ int unlock_piix4_pam(void) { printf("Unlocking BIOS region with PIIX4 PAM\n"); /* Enable read+write for PAM0-PAM6 (0x59-0x5F) */ pciConfigWriteByte(0, 0, 0, 0x59, PAM0_ENABLE); /* PAM0: 0xF0000-0xFFFFF */ pciConfigWriteByte(0, 0, 0, 0x5a, PAM_ENABLE); /* PAM1: 0xC0000-0xC7FFF */ pciConfigWriteByte(0, 0, 0, 0x5b, PAM_ENABLE); /* PAM2: 0xC8000-0xCFFFF */ pciConfigWriteByte(0, 0, 0, 0x5c, PAM_ENABLE); /* PAM3: 0xD0000-0xD7FFF */ pciConfigWriteByte(0, 0, 0, 0x5d, PAM_ENABLE); /* PAM4: 0xD8000-0xDFFFF */ pciConfigWriteByte(0, 0, 0, 0x5e, PAM_ENABLE); /* PAM5: 0xE0000-0xE7FFF */ pciConfigWriteByte(0, 0, 0, 0x5f, PAM_ENABLE); /* PAM6: 0xE8000-0xEFFFF */ return 0; } /** * Unlock BIOS region using direct PCI configuration space access for Q35 chipset * * @return 0 on success, -1 on failure */ int unlock_q35_pam(void) { printf("Unlocking BIOS region with Q35 PAM\n"); /* Enable read+write for PAM0-PAM6 (0x90-0x96) */ pciConfigWriteByte(0, 0, 0, 0x90, PAM0_ENABLE); /* PAM0: 0xF0000-0xFFFFF */ pciConfigWriteByte(0, 0, 0, 0x91, PAM_ENABLE); /* PAM1: 0xC0000-0xC7FFF */ pciConfigWriteByte(0, 0, 0, 0x92, PAM_ENABLE); /* PAM2: 0xC8000-0xCFFFF */ pciConfigWriteByte(0, 0, 0, 0x93, PAM_ENABLE); /* PAM3: 0xD0000-0xD7FFF */ pciConfigWriteByte(0, 0, 0, 0x94, PAM_ENABLE); /* PAM4: 0xD8000-0xDFFFF */ pciConfigWriteByte(0, 0, 0, 0x95, PAM_ENABLE); /* PAM5: 0xE0000-0xE7FFF */ pciConfigWriteByte(0, 0, 0, 0x96, PAM_ENABLE); /* PAM6: 0xE8000-0xEFFFF */ return 0; } /** * Unlock BIOS region using direct PCI configuration space access for Intel * Sandy Bridge and later host bridges (PAM at D0:F0 offsets 0x80-0x86, * with PAM-LCK at PAM0 bit 0). * * @return 0 on success, -1 on failure */ int unlock_sandybridge_pam(void) { printf("Unlocking BIOS region with Intel Sandy Bridge+ PAM\n"); /* Check if PAM is locked */ if (pciConfigReadByte(0, 0, 0, PAM_LOCK_REG) & PAM_LOCK_BIT) { printf("PAM is locked on your platform\n"); return -1; } /* Enable read+write for PAM0-PAM6 (0x80-0x86) */ pciConfigWriteByte(0, 0, 0, 0x80, PAM0_ENABLE); /* PAM0: 0xF0000-0xFFFFF */ pciConfigWriteByte(0, 0, 0, 0x81, PAM_ENABLE); /* PAM1: 0xC0000-0xC7FFF */ pciConfigWriteByte(0, 0, 0, 0x82, PAM_ENABLE); /* PAM2: 0xC8000-0xCFFFF */ pciConfigWriteByte(0, 0, 0, 0x83, PAM_ENABLE); /* PAM3: 0xD0000-0xD7FFF */ pciConfigWriteByte(0, 0, 0, 0x84, PAM_ENABLE); /* PAM4: 0xD8000-0xDFFFF */ pciConfigWriteByte(0, 0, 0, 0x85, PAM_ENABLE); /* PAM5: 0xE0000-0xE7FFF */ pciConfigWriteByte(0, 0, 0, 0x86, PAM_ENABLE); /* PAM6: 0xE8000-0xEFFFF */ return 0; } /** * Unlock BIOS region using fixed MTRR for AMD chipsets * * @return 0 on success, -1 on failure */ int unlock_amd_mtrr(void) { uint64_t val; unsigned long flags, cr0, cr4; printf("Unlocking BIOS region with AMD MTRR\n"); /* AMD APM Vol 2 §7.6.3: disable cache, flush, modify MTRRs, flush, restore. * Required so stale cache lines and TLB entries don't outlive the change. */ asm volatile ("pushf; pop %0; cli" : "=rm"(flags) :: "memory"); asm volatile ("mov %%cr0, %0" : "=r"(cr0)); asm volatile ("mov %0, %%cr0" :: "r"(cr0 | (1UL << 30))); /* CD = 1 */ asm volatile ("wbinvd"); asm volatile ("mov %%cr4, %0" : "=r"(cr4)); if (cr4 & (1UL << 7)) { /* PGE */ asm volatile ("mov %0, %%cr4" :: "r"(cr4 & ~(1UL << 7))); } /* Enable MTRR modification: set SYS_CFG.MtrrFixDramModEn (bit 19) */ val = rdmsr(MSR_SYS_CFG); val |= SYS_CFG_MTRR_FIX_DRAM_MOD_EN; wrmsr(MSR_SYS_CFG, val); /* Set all to WB */ wrmsr(AMD_AP_MTRR_FIX64k_00000, AMD_MTRR_FIX64K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX16k_80000, AMD_MTRR_FIX16K_WB_DRAM); /* A0000 map to UC IO */ wrmsr(AMD_AP_MTRR_FIX16k_A0000, 0x0); wrmsr(AMD_AP_MTRR_FIX4k_C0000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_C8000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_D0000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_D8000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_E0000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_E8000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_F0000, AMD_MTRR_FIX4K_WB_DRAM); wrmsr(AMD_AP_MTRR_FIX4k_F8000, AMD_MTRR_FIX4K_WB_DRAM); val = rdmsr(MSR_SYS_CFG); val &= ~SYS_CFG_MTRR_FIX_DRAM_MOD_EN; val |= SYS_CFG_MTRR_FIX_DRAM_EN; wrmsr(MSR_SYS_CFG, val); asm volatile ("wbinvd"); asm volatile ("mov %0, %%cr0" :: "r"(cr0)); asm volatile ("mov %0, %%cr4" :: "r"(cr4)); asm volatile ("push %0; popf" :: "rm"(flags) : "memory", "cc"); return 0; } /** * Get information about the legacy region and display it * * @param legacy_region Legacy Region 2 Protocol instance * @return EFI_SUCCESS on success, or an error status code on failure */ EFI_STATUS print_legacy_region_info(EFI_LEGACY_REGION2_PROTOCOL *legacy_region) { EFI_STATUS status; uint32_t descriptor_count = 0; EFI_LEGACY_REGION_DESCRIPTOR *descriptors = NULL; status = legacy_region->GetInfo( legacy_region, &descriptor_count, &descriptors ); if (EFI_ERROR(status)) { printf("Failed to get legacy region information (status: %lx)\n", status); return status; } printf("Legacy Region Information:\n"); printf("Found %u region descriptors\n", descriptor_count); for (uint32_t i = 0; i < descriptor_count; i++) { printf("Region %u: 0x%08x-0x%08x, Granularity: 0x%x bytes\n", i, descriptors[i].Start, descriptors[i].Start + descriptors[i].Length - 1, descriptors[i].Granularity); printf(" Attribute: "); switch (descriptors[i].Attribute) { case LegacyRegionDecoded: printf("Read Enabled\n"); break; case LegacyRegionNotDecoded: printf("Read Disabled\n"); break; case LegacyRegionWriteEnabled: printf("Write Enabled\n"); break; case LegacyRegionWriteDisabled: printf("Write Disabled\n"); break; case LegacyRegionBootLocked: printf("Boot Locked\n"); break; case LegacyRegionNotLocked: printf("Not Locked\n"); break; default: printf("Unknown\n"); break; } } return EFI_SUCCESS; } static bool test_bios_region_rw(void) { uint32_t *bios_region = (uint32_t *)BIOSROM_START; uint32_t *bios_region_end = (uint32_t *)BIOSROM_END; uint32_t *ptr = bios_region; while (ptr < bios_region_end) { clflush(ptr); uint32_t val = readl(ptr); writel(ptr, ~val); clflush(ptr); if (readl(ptr) != ~val) { printf("Unable to write to BIOS region\n"); return false; } writel(ptr, val); ptr++; } return true; } /** * Main function to unlock the BIOS region * Tries to use the UEFI protocol first, then falls back to chipset-specific methods * * @return 0 on success, non-zero on failure */ int unlock_bios_region(void) { EFI_LEGACY_REGION2_PROTOCOL *legacy_region = NULL; EFI_STATUS status; // No need to do anything if the region is already unlocked and working. if (test_bios_region_rw()) { return 0; } /* First, try to use the Legacy Region 2 Protocol */ status = gBS->LocateProtocol( &gEfiLegacyRegion2ProtocolGuid, NULL, (void **)&legacy_region ); if (!EFI_ERROR(status)) { /* If we have the protocol, print region information for debugging */ print_legacy_region_info(legacy_region); /* Try to unlock using the protocol */ status = unlock_legacy_region_protocol(); if (!EFI_ERROR(status) && test_bios_region_rw()) { return 0; /* Success */ } /* Protocol method failed, fall back to chipset-specific methods */ printf("Protocol method failed, trying chipset-specific methods\n"); } else { printf("Legacy Region 2 Protocol not found, trying chipset-specific methods\n"); } /* Check for known chipsets and use appropriate method */ uint32_t host_bridge_id = pciConfigReadDWord(0, 0, 0, 0x0); printf("Host Bridge ID: 0x%08x\n", host_bridge_id); uint16_t vendor_id = (host_bridge_id & 0xFFFF); uint16_t device_id = (host_bridge_id >> 16) & 0xFFFF; switch (vendor_id) { case INTEL_VENDOR_ID: switch (device_id) { case 0x1237: /* 440FX (QEMU) */ case 0x7190: /* 440BX/ZX/DX (VMware) */ case 0x71A0: /* 440GX */ case 0x7194: /* 440MX */ case 0x7180: /* 440LX/EX */ status = unlock_piix4_pam(); break; case 0x29C0: /* Q35 (QEMU) */ case 0x29E0: /* X38/X48 (VirtualBox) */ status = unlock_q35_pam(); break; default: status = unlock_sandybridge_pam(); break; } break; case AMD_VENDOR_ID: /* AMD chipsets */ status = unlock_amd_mtrr(); break; default: status = EFI_UNSUPPORTED; printf("Unknown chipset, unable to unlock BIOS region\n"); break; } return (status == 0 && test_bios_region_rw()) ? 0 : -1; } ================================================ FILE: src/video.c ================================================ #include #include #include #include #include #include // Generated by: xxd -i vgabios.bin >> vgabios.h #include void *vbios_loc = NULL; uintptr_t vbios_size; /* Forward declaration */ static bool is_amd_rdna_or_newer(uint16_t vendor_id, uint16_t device_id); /* * Calculate bits per pixel from linear pixel masks. * Ported from Limine. */ static uint16_t linear_masks_to_bpp(uint32_t red_mask, uint32_t green_mask, uint32_t blue_mask, uint32_t alpha_mask) { uint32_t compound_mask = red_mask | green_mask | blue_mask | alpha_mask; if (compound_mask == 0) return 0; uint16_t ret = 32; while ((compound_mask & (1U << 31)) == 0) { ret--; compound_mask <<= 1; } return ret; } /* True if Gop->Mode points at a directly-usable linear framebuffer. Checks * are run against the current Gop->Mode without calling SetMode, so this is * safe to call before deciding whether to disturb the firmware's mode. */ static bool gop_mode_usable(EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop) { if (Gop->Mode == NULL || Gop->Mode->Info == NULL) return false; if (Gop->Mode->FrameBufferBase == 0) return false; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mi = Gop->Mode->Info; if (mi->PixelFormat >= PixelBltOnly) return false; if (mi->PixelFormat == PixelBitMask && (mi->PixelInformation.RedMask | mi->PixelInformation.GreenMask | mi->PixelInformation.BlueMask | mi->PixelInformation.ReservedMask) == 0) return false; if (mi->PixelsPerScanLine < mi->HorizontalResolution) return false; return true; } /* * Find a GOP with a valid framebuffer and set its mode. * This is needed for Flanterm and SeaVGABIOS framebuffer access. */ static EFI_STATUS FindGop(struct csmwrap_priv *priv) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; Status = gBS->LocateHandleBuffer( ByProtocol, &gopGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR(Status)) { printf("Failed to locate GOP handles: %d\n", Status); return Status; } // Iterate through each GOP handle, find one with valid FrameBufferBase for (UINTN i = 0; i < HandleCount; i++) { Status = gBS->HandleProtocol( HandleBuffer[i], &gopGuid, (VOID**)&Gop ); if (EFI_ERROR(Status)) { continue; } // Initialize GOP if not started (Limine pattern: QueryMode may return // EFI_NOT_STARTED, kick it with SetMode(0) and re-query). EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *modeInfo; UINTN modeInfoSize; UINTN currentMode = Gop->Mode == NULL ? 0 : Gop->Mode->Mode; Status = Gop->QueryMode(Gop, currentMode, &modeInfoSize, &modeInfo); if (Status == EFI_NOT_STARTED) { Status = Gop->SetMode(Gop, 0); if (EFI_ERROR(Status)) { continue; } currentMode = Gop->Mode == NULL ? 0 : Gop->Mode->Mode; Status = Gop->QueryMode(Gop, currentMode, &modeInfoSize, &modeInfo); } if (EFI_ERROR(Status)) { continue; } /* Prefer the firmware's current mode to avoid blanking and resizing * the user's display. Only enumerate-and-SetMode if it isn't usable. */ bool found = gop_mode_usable(Gop); if (!found) { UINTN maxMode = Gop->Mode->MaxMode; for (UINTN mode = 0; mode < maxMode; mode++) { Status = Gop->SetMode(Gop, mode); if (EFI_ERROR(Status)) continue; if (gop_mode_usable(Gop)) { found = true; break; } } } if (!found) { continue; } priv->gop = Gop; priv->gop_handle = HandleBuffer[i]; break; } gBS->FreePool(HandleBuffer); if (priv->gop == NULL) { printf("No GOP with valid framebuffer found\n"); return EFI_NOT_FOUND; } return EFI_SUCCESS; } /* * Populate priv VGA PCI fields from a PCI I/O protocol handle. */ static void PopulateVgaPciInfo(struct csmwrap_priv *priv, EFI_PCI_IO_PROTOCOL *PciIo) { UINT16 VendorId, DeviceId; UINTN Seg, Bus, Device, Function; priv->vga_pci_io = PciIo; PciIo->GetLocation(PciIo, &Seg, &Bus, &Device, &Function); priv->vga_pci_bus = (UINT8)Bus; priv->vga_pci_devfn = (UINT8)(Device << 3 | Function); PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId); PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId); priv->vga_vendor_id = VendorId; priv->vga_device_id = DeviceId; printf("VGA PCI: %04x:%02x:%02x.%x %04x:%04x\n", Seg, (UINT8)Bus, (UINT8)Device, (UINT8)Function, VendorId, DeviceId); } /* * Find a PCI device by bus/device/function and return its PCI I/O protocol. */ static EFI_STATUS FindPciDevice(uint8_t bus, uint8_t device, uint8_t function, EFI_PCI_IO_PROTOCOL **OutPciIo) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; Status = gBS->LocateHandleBuffer(ByProtocol, &PciIoGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR(Status)) return Status; for (UINTN i = 0; i < HandleCount; i++) { EFI_PCI_IO_PROTOCOL *PciIo; Status = gBS->HandleProtocol(HandleBuffer[i], &PciIoGuid, (VOID **)&PciIo); if (EFI_ERROR(Status)) continue; UINTN Seg, Bus, Device, Function; PciIo->GetLocation(PciIo, &Seg, &Bus, &Device, &Function); if ((uint8_t)Bus == bus && (uint8_t)Device == device && (uint8_t)Function == function) { *OutPciIo = PciIo; gBS->FreePool(HandleBuffer); return EFI_SUCCESS; } } gBS->FreePool(HandleBuffer); return EFI_NOT_FOUND; } /* * Find PCI device info for VGA output. * * If a specific VGA device is configured, locate it by PCI address. * Otherwise, derive it from the GOP handle's device path. * * This is needed for OpROM loading, VGA arbitration, and legacy handoff. */ static EFI_STATUS FindVgaPciInfo(struct csmwrap_priv *priv) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; /* If user specified a VGA device, find it directly by PCI address */ if (gConfig.vga_specified) { Status = FindPciDevice(gConfig.vga_bus, gConfig.vga_device, gConfig.vga_function, &PciIo); if (EFI_ERROR(Status)) { printf("VGA: configured device %02x:%02x.%x not found\n", gConfig.vga_bus, gConfig.vga_device, gConfig.vga_function); return Status; } PopulateVgaPciInfo(priv, PciIo); return EFI_SUCCESS; } /* Default: derive from GOP handle's device path */ EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_HANDLE Handle; if (priv->gop_handle == NULL) return EFI_NOT_FOUND; Status = gBS->HandleProtocol(priv->gop_handle, &DevicePathGuid, (VOID **)&DevicePath); if (EFI_ERROR(Status)) return Status; Status = gBS->LocateDevicePath(&PciIoGuid, &DevicePath, &Handle); if (EFI_ERROR(Status)) return Status; Status = gBS->HandleProtocol(Handle, &PciIoGuid, (VOID **)&PciIo); if (EFI_ERROR(Status)) return Status; PopulateVgaPciInfo(priv, PciIo); return EFI_SUCCESS; } static EFI_STATUS csmwrap_pci_vgaarb(EFI_PCI_IO_PROTOCOL *PciIo) { EFI_STATUS Status; UINT64 Attributes = 0; UINT64 Supported = 0; BOOLEAN unsupported = FALSE; if (!PciIo) { return EFI_INVALID_PARAMETER; } Status = PciIo->Attributes(PciIo, EfiPciIoAttributeOperationSupported, 0, &Supported); if (EFI_ERROR(Status)) { printf("%s: Failed to get supported attributes: %d\n", __func__, Status); return Status; } /* Prefer aliased VGA I/O for legacy OS compatibility (ISA-style decoding); * fall back to strict 16-bit if that's all the bridge supports. */ if (Supported & EFI_PCI_IO_ATTRIBUTE_VGA_IO) { Attributes = EFI_PCI_IO_ATTRIBUTE_VGA_IO; } else if (Supported & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16) { Attributes = EFI_PCI_IO_ATTRIBUTE_VGA_IO_16; } else { printf("%s: No VGA IO attributes support\n", __func__); unsupported = TRUE; } if (Supported & EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY) { Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; } else { printf("%s: No VGA memory attributes support\n", __func__); unsupported = TRUE; } if (unsupported) { printf("%s: Unable to select attribute\n", __func__); return EFI_UNSUPPORTED; } Status = PciIo->Attributes(PciIo, EfiPciIoAttributeOperationEnable, Attributes, NULL); if (EFI_ERROR(Status)) { printf("%s: Failed to set attributes: %d\n", __func__, Status); return Status; } printf("%s: Success! Attributes: %llx\n", __func__, Attributes); return EFI_SUCCESS; } /* * Try to use a specific PCI device's OpROM for VGA. * Checks VGA arbitration, OpROM extraction, and size constraints. * On success, populates priv VGA fields and sets vbios_loc/vbios_size. */ static EFI_STATUS try_gpu_oprom(struct csmwrap_priv *priv, EFI_PCI_IO_PROTOCOL *PciIo) { EFI_STATUS Status; PCI_TYPE00 PciConfigHeader; UINTN LocalRomSize; VOID *LocalRomImage; if (!PciIo->RomImage || !PciIo->RomSize) return EFI_UNSUPPORTED; /* Populate priv with this device's info for VGA arbitration and dispatch */ PopulateVgaPciInfo(priv, PciIo); /* Try to claim VGA I/O and memory routing for this device */ Status = csmwrap_pci_vgaarb(PciIo); if (Status != EFI_SUCCESS) { printf(" VGA arbitration failed, skipping\n"); return EFI_UNSUPPORTED; } LocalRomSize = (UINTN) PciIo->RomSize; LocalRomImage = PciIo->RomImage; PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, 0, sizeof(PciConfigHeader) / sizeof(UINT32), &PciConfigHeader); if (is_amd_rdna_or_newer(PciConfigHeader.Hdr.VendorId, PciConfigHeader.Hdr.DeviceId)) { printf(" AMD RDNA+ GPU detected (device %04x), skipping OpROM\n", PciConfigHeader.Hdr.DeviceId); return EFI_UNSUPPORTED; } Status = GetPciLegacyRom( 0x0300, PciConfigHeader.Hdr.VendorId, PciConfigHeader.Hdr.DeviceId, &LocalRomImage, &LocalRomSize, NULL, NULL, NULL); if (EFI_ERROR(Status)) { printf(" No legacy ROM image found\n"); return Status; } /* Reject OpROM if it won't fit below the CSM binary */ uintptr_t max_vbios_size = priv->csm_bin_base - VGABIOS_START; if (LocalRomSize > max_vbios_size) { printf(" OpROM too large (%u bytes, max %u), skipping\n", (unsigned)LocalRomSize, (unsigned)max_vbios_size); return EFI_UNSUPPORTED; } vbios_loc = LocalRomImage; vbios_size = LocalRomSize; priv->video_type = CSMWRAP_VIDEO_OPROM; printf("Video Initialisation Succeed with OpROM\n"); return EFI_SUCCESS; } static EFI_STATUS csmwrap_video_oprom_init(struct csmwrap_priv *priv) { EFI_STATUS Status; /* * If the user specified a GPU with vga=, only try that device. */ if (gConfig.vga_specified) { EFI_PCI_IO_PROTOCOL *PciIo; Status = FindPciDevice(gConfig.vga_bus, gConfig.vga_device, gConfig.vga_function, &PciIo); if (EFI_ERROR(Status)) { printf("VGA: configured device %02x:%02x.%x not found\n", gConfig.vga_bus, gConfig.vga_device, gConfig.vga_function); return EFI_UNSUPPORTED; } Status = try_gpu_oprom(priv, PciIo); if (Status == EFI_SUCCESS) return EFI_SUCCESS; goto clear_and_fail; } /* * Auto-select: try the GOP device first (most likely to be the active * display), then fall through to other GPUs if it fails. */ FindVgaPciInfo(priv); if (priv->vga_pci_io) { Status = try_gpu_oprom(priv, priv->vga_pci_io); if (Status == EFI_SUCCESS) return EFI_SUCCESS; } /* * GOP device didn't work — enumerate all display-class PCI devices * and try each one until we find a working OpROM with VGA arbitration. */ EFI_HANDLE *HandleBuffer; UINTN HandleCount; EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; Status = gBS->LocateHandleBuffer(ByProtocol, &PciIoGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR(Status)) goto clear_and_fail; for (UINTN i = 0; i < HandleCount; i++) { EFI_PCI_IO_PROTOCOL *PciIo; PCI_TYPE00 PciConfig; if (gBS->HandleProtocol(HandleBuffer[i], &PciIoGuid, (VOID **)&PciIo)) continue; PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, 0, sizeof(PciConfig) / sizeof(UINT32), &PciConfig); if (PciConfig.Hdr.ClassCode[2] != PCI_CLASS_DISPLAY) continue; /* Skip the GOP device we already tried */ if (PciIo == priv->vga_pci_io) continue; printf("VGA: trying alternate GPU %04x:%04x\n", PciConfig.Hdr.VendorId, PciConfig.Hdr.DeviceId); Status = try_gpu_oprom(priv, PciIo); if (Status == EFI_SUCCESS) { gBS->FreePool(HandleBuffer); return EFI_SUCCESS; } } gBS->FreePool(HandleBuffer); clear_and_fail: /* Reset VGA priv fields populated by failed try_gpu_oprom calls so the * SeaVGABIOS fallback and later oprom_dispatch_all see no stale state. */ priv->vga_pci_io = NULL; priv->vga_pci_bus = 0; priv->vga_pci_devfn = 0; priv->vga_vendor_id = 0; priv->vga_device_id = 0; return EFI_UNSUPPORTED; } static EFI_STATUS csmwrap_video_seavgabios_init(struct csmwrap_priv *priv) { struct cb_framebuffer *cb_fb = &priv->cb_fb; unsigned long fb_addr = 0; EFI_STATUS status; EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = priv->gop; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL; UINTN isiz = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), currentMode; if (!gop) { return EFI_UNSUPPORTED; } /* Mode already set by FindGopPciDevice, just query info */ currentMode = gop->Mode->Mode; status = gop->QueryMode(gop, currentMode, &isiz, &info); if (EFI_ERROR(status)) { printf("unable to get current video mode\n"); return -1; } printf("%c %3d. %4d x%4d (pitch %4d fmt %d r:%06x g:%06x b:%06x)\n", '*', currentMode, info->HorizontalResolution, info->VerticalResolution, info->PixelsPerScanLine, info->PixelFormat, info->PixelFormat==PixelRedGreenBlueReserved8BitPerColor?0xff:( info->PixelFormat==PixelBlueGreenRedReserved8BitPerColor?0xff0000:( info->PixelFormat==PixelBitMask?info->PixelInformation.RedMask:0)), info->PixelFormat==PixelRedGreenBlueReserved8BitPerColor || info->PixelFormat==PixelBlueGreenRedReserved8BitPerColor?0xff00:( info->PixelFormat==PixelBitMask?info->PixelInformation.GreenMask:0), info->PixelFormat==PixelRedGreenBlueReserved8BitPerColor?0xff0000:( info->PixelFormat==PixelBlueGreenRedReserved8BitPerColor?0xff:( info->PixelFormat==PixelBitMask?info->PixelInformation.BlueMask:0))); fb_addr = (unsigned long)gop->Mode->FrameBufferBase; printf("EFI Framebuffer: %lx\n", fb_addr); if (!fb_addr) { printf("Framebuffer invalid.\n"); return EFI_UNSUPPORTED; } cb_fb->physical_address = fb_addr; cb_fb->x_resolution = info->HorizontalResolution; cb_fb->y_resolution = info->VerticalResolution; switch (info->PixelFormat) { case PixelRedGreenBlueReserved8BitPerColor: cb_fb->bits_per_pixel = 32; cb_fb->red_mask_pos = 0; cb_fb->red_mask_size = 8; cb_fb->green_mask_pos = 8; cb_fb->green_mask_size = 8; cb_fb->blue_mask_pos = 16; cb_fb->blue_mask_size = 8; cb_fb->reserved_mask_pos = 24; cb_fb->reserved_mask_size = 8; break; case PixelBlueGreenRedReserved8BitPerColor: cb_fb->bits_per_pixel = 32; cb_fb->blue_mask_pos = 0; cb_fb->blue_mask_size = 8; cb_fb->green_mask_pos = 8; cb_fb->green_mask_size = 8; cb_fb->red_mask_pos = 16; cb_fb->red_mask_size = 8; cb_fb->reserved_mask_pos = 24; cb_fb->reserved_mask_size = 8; break; case PixelBitMask: /* Reject modes with all-zero pixel masks */ if ((info->PixelInformation.RedMask | info->PixelInformation.GreenMask | info->PixelInformation.BlueMask | info->PixelInformation.ReservedMask) == 0) { printf("PixelBitMask mode with all-zero masks\n"); return EFI_UNSUPPORTED; } /* Calculate BPP from masks instead of assuming 32 */ cb_fb->bits_per_pixel = linear_masks_to_bpp( info->PixelInformation.RedMask, info->PixelInformation.GreenMask, info->PixelInformation.BlueMask, info->PixelInformation.ReservedMask); // Calculate position (find first set bit, 0 if mask is empty) cb_fb->red_mask_pos = info->PixelInformation.RedMask ? __builtin_ffs(info->PixelInformation.RedMask) - 1 : 0; cb_fb->green_mask_pos = info->PixelInformation.GreenMask ? __builtin_ffs(info->PixelInformation.GreenMask) - 1 : 0; cb_fb->blue_mask_pos = info->PixelInformation.BlueMask ? __builtin_ffs(info->PixelInformation.BlueMask) - 1 : 0; cb_fb->reserved_mask_pos = info->PixelInformation.ReservedMask ? __builtin_ffs(info->PixelInformation.ReservedMask) - 1 : 0; // Calculate size (count set bits) cb_fb->red_mask_size = __builtin_popcount(info->PixelInformation.RedMask); cb_fb->green_mask_size = __builtin_popcount(info->PixelInformation.GreenMask); cb_fb->blue_mask_size = __builtin_popcount(info->PixelInformation.BlueMask); cb_fb->reserved_mask_size = __builtin_popcount(info->PixelInformation.ReservedMask); break; default: printf("Unsupported pixel format: %d\n", info->PixelFormat); return EFI_UNSUPPORTED; } /* * Recalculate pitch from gop->Mode->Info, as some firmware (e.g. Apple * Macs) report incorrect PixelsPerScanLine via QueryMode. */ cb_fb->bytes_per_line = gop->Mode->Info->PixelsPerScanLine * (cb_fb->bits_per_pixel / 8); /* Validate pitch */ { uint32_t bytes_per_pixel = cb_fb->bits_per_pixel / 8; if (bytes_per_pixel == 0 || cb_fb->bytes_per_line % bytes_per_pixel != 0 || cb_fb->bytes_per_line < cb_fb->x_resolution * bytes_per_pixel) { printf("Invalid pitch %u (width=%u, bpp=%u)\n", cb_fb->bytes_per_line, cb_fb->x_resolution, cb_fb->bits_per_pixel); return EFI_UNSUPPORTED; } } vbios_loc = vgabios_bin; vbios_size = sizeof(vgabios_bin); priv->video_type = CSMWRAP_VIDEO_SEAVGABIOS; printf("Video Initialisation Succeed with SeaVGABIOS GOP\n"); return 0; } EFI_STATUS csmwrap_video_prepare_exitbs(struct csmwrap_priv *priv) { /* * Unlink Controller before ExitBS, it mat disable FB so we can't * do that for other video types. */ if (priv->video_type == CSMWRAP_VIDEO_OPROM) { EFI_STATUS Status; if (!priv->gop_handle) { printf("No GOP handle found\n"); return EFI_UNSUPPORTED; } if (gBS->Hdr.Revision < EFI_1_10_BOOT_SERVICES_REVISION && !gBS->DisconnectController) { printf("DisconnectController not supported\n"); return EFI_UNSUPPORTED; } Status = gBS->DisconnectController( priv->gop_handle, NULL, NULL ); if (EFI_ERROR(Status)) { printf("DisconnectController failed: %d\n", Status); return Status; } } return EFI_SUCCESS; } /* * Check if the GPU is AMD RDNA or newer architecture. * * AMD RDNA+ iGPUs have broken/non-functional legacy VGA BIOS (OpROM), * so we need to force SeaVGABIOS even if the GPU advertises an OpROM. * * Strategy: Instead of listing all RDNA+ device IDs (which requires constant * updates), we whitelist known-good pre-RDNA (Vega-based) APUs and assume * any other AMD iGPU in the typical APU device ID ranges is RDNA+. * * Device IDs sourced from Linux amdgpu driver and Folding@home GPU database. */ #define AMD_VENDOR_ID 0x1002 static bool is_amd_vega_apu(uint16_t device_id) { /* * Known Vega-based APUs with working legacy OpROM: * - Raven Ridge (Ryzen 2000 APU) * - Picasso (Ryzen 3000 APU) * - Renoir (Ryzen 4000 APU) * - Lucienne (Ryzen 5000 APU, Zen 2 refresh) * - Cezanne (Ryzen 5000 APU, Zen 3) * - Barcelo (Ryzen 5000 APU refresh) */ switch (device_id) { case 0x15D8: /* Picasso */ case 0x15DD: /* Raven Ridge */ case 0x15E7: /* Barcelo */ case 0x1636: /* Renoir */ case 0x1638: /* Renoir/Cezanne */ case 0x164C: /* Lucienne */ return true; default: return false; } } static bool is_amd_rdna_or_newer(uint16_t vendor_id, uint16_t device_id) { if (vendor_id != AMD_VENDOR_ID) return false; /* * AMD RDNA 1/2/3/4 discrete GPUs (Navi series): * - 0x73xx: Navi 10/12/14 (RDNA 1), Navi 21/22/23 (RDNA 2) * - 0x74xx: Navi 24 (RDNA 2), Navi 31/32/33 (RDNA 3) * - 0x75xx: Navi 48/44 (RDNA 4) */ if ((device_id & 0xFF00) == 0x7300 || (device_id & 0xFF00) == 0x7400 || (device_id & 0xFF00) == 0x7500) return true; /* * AMD APU/iGPU detection: * Device IDs in ranges 0x14xx, 0x15xx, 0x16xx, 0x19xx are typically iGPUs. * If it's not a known Vega APU, assume it's RDNA+ with broken OpROM. */ if ((device_id & 0xFF00) == 0x1400 || (device_id & 0xFF00) == 0x1500 || (device_id & 0xFF00) == 0x1600 || (device_id & 0xFF00) == 0x1900) { /* Check if it's a known-good Vega APU */ if (is_amd_vega_apu(device_id)) return false; /* Unknown APU in these ranges - assume RDNA+ */ return true; } return false; } void csmwrap_video_early_init(struct csmwrap_priv *priv) { if (FindGop(priv) != EFI_SUCCESS) { priv->cb_fb.physical_address = 0; return; } if (csmwrap_video_seavgabios_init(priv) != EFI_SUCCESS) { priv->cb_fb.physical_address = 0; return; } /* Clear vbios_loc so csmwrap_video_init() doesn't skip OpROM init */ vbios_loc = NULL; } /* * If a specific VGA device is configured, find its GOP handle and switch * priv->gop_handle so that DisconnectController targets the correct device * during exit-boot-services preparation. */ static void FindVgaGop(struct csmwrap_priv *priv) { EFI_HANDLE *HandleBuffer; UINTN HandleCount; EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; if (gBS->LocateHandleBuffer(ByProtocol, &gopGuid, NULL, &HandleCount, &HandleBuffer)) return; for (UINTN i = 0; i < HandleCount; i++) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; if (gBS->HandleProtocol(HandleBuffer[i], &DevicePathGuid, (VOID **)&DevicePath)) continue; EFI_HANDLE PciHandle; if (gBS->LocateDevicePath(&PciIoGuid, &DevicePath, &PciHandle)) continue; EFI_PCI_IO_PROTOCOL *PciIo; if (gBS->HandleProtocol(PciHandle, &PciIoGuid, (VOID **)&PciIo)) continue; UINTN Seg, Bus, Device, Function; PciIo->GetLocation(PciIo, &Seg, &Bus, &Device, &Function); if ((uint8_t)Bus != gConfig.vga_bus || (uint8_t)Device != gConfig.vga_device || (uint8_t)Function != gConfig.vga_function) continue; EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; if (gBS->HandleProtocol(HandleBuffer[i], &gopGuid, (VOID **)&Gop)) continue; priv->gop = Gop; priv->gop_handle = HandleBuffer[i]; printf("VGA: switched GOP to configured device %02x:%02x.%x\n", gConfig.vga_bus, gConfig.vga_device, gConfig.vga_function); break; } gBS->FreePool(HandleBuffer); } EFI_STATUS csmwrap_video_init(struct csmwrap_priv *priv) { EFI_STATUS status; /* Find GOP if not already found by early init */ if (!priv->gop) { status = FindGop(priv); if (EFI_ERROR(status)) { printf("Unable to get GOP service; continuing without video\n"); return EFI_UNSUPPORTED; } } if (vbios_loc != NULL) { /* * User-provided VBIOS: still need PCI info and VGA arbitration * so the VBIOS is dispatched to the right device. */ FindVgaPciInfo(priv); status = csmwrap_pci_vgaarb(priv->vga_pci_io); if (status != EFI_SUCCESS) { printf("VGA arbitration failed, cannot dispatch user VBIOS\n"); vbios_loc = NULL; vbios_size = 0; /* Fall through to try SeaVGABIOS instead */ goto try_seavga; } if (gConfig.vga_specified) FindVgaGop(priv); priv->video_type = CSMWRAP_VIDEO_OPROM; return 0; } /* Try OpROM: user-specified GPU, or auto-select from all GPUs */ status = csmwrap_video_oprom_init(priv); if (status == EFI_SUCCESS) { /* * Switch gop_handle to the VGA device so DisconnectController * targets the right device during exit-boot-services preparation. */ if (gConfig.vga_specified) FindVgaGop(priv); return 0; } try_seavga: status = csmwrap_video_seavgabios_init(priv); if (status == EFI_SUCCESS) { return 0; } panic("No video initialization method available\n"); } ================================================ FILE: src/video.h ================================================ #ifndef VIDEO_H #define VIDEO_H #include #include #include extern void *vbios_loc; extern uintptr_t vbios_size; EFI_STATUS csmwrap_video_init(struct csmwrap_priv *priv); EFI_STATUS csmwrap_video_prepare_exitbs(struct csmwrap_priv *priv); void csmwrap_video_early_init(struct csmwrap_priv *priv); #endif ================================================ FILE: src/x86thunk.c ================================================ /* * Real Mode Thunk Functions for IA32 and x64. * * Based on EDK2: MdePkg/Library/BaseLib/X86Thunk.c * * Which is: * Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
* SPDX-License-Identifier: BSD-2-Clause-Patent */ #include #include #include "csmwrap.h" // FIXME: Are we going to implement it? #define ASSERT(x) extern const uint8_t m16Start; extern const uint16_t m16Size; extern const uint16_t mThunk16Attr; extern const uint16_t m16Gdt; extern const uint16_t m16GdtrBase; extern const uint16_t mTransition; /** Invokes 16-bit code in big real mode and returns the updated register set. This function transfers control to the 16-bit code specified by CS:EIP using the stack specified by SS:ESP in RegisterSet. The updated registers are saved on the real mode stack and the starting address of the save area is returned. @param RegisterSet Values of registers before invocation of 16-bit code. @param Transition The pointer to the transition code under 1MB. @return The pointer to a IA32_REGISTER_SET structure containing the updated register values. **/ __attribute__((__ms_abi__)) IA32_REGISTER_SET *InternalAsmThunk16(IA32_REGISTER_SET *RegisterSet, void *Transition); /** Retrieves the properties for 16-bit thunk functions. Computes the size of the buffer and stack below 1MB required to use the AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This buffer size is returned in RealModeBufferSize, and the stack size is returned in ExtraStackSize. If parameters are passed to the 16-bit real mode code, then the actual minimum stack size is ExtraStackSize plus the maximum number of bytes that need to be passed to the 16-bit real mode code. If RealModeBufferSize is NULL, then ASSERT(). If ExtraStackSize is NULL, then ASSERT(). @param RealModeBufferSize A pointer to the size of the buffer below 1MB required to use the 16-bit thunk functions. @param ExtraStackSize A pointer to the extra size of stack below 1MB that the 16-bit thunk functions require for temporary storage in the transition to and from 16-bit real mode. **/ void AsmGetThunk16Properties (uint32_t *RealModeBufferSize, uint32_t *ExtraStackSize) { ASSERT (RealModeBufferSize != NULL); ASSERT (ExtraStackSize != NULL); *RealModeBufferSize = m16Size; // // Extra 4 bytes for return address, and another 4 bytes for mode transition // *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8; } /** Prepares all structures a code required to use AsmThunk16(). Prepares all structures and code required to use AsmThunk16(). This interface is limited to be used in either physical mode or virtual modes with paging enabled where the virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. If ThunkContext is NULL, then ASSERT(). @param ThunkContext A pointer to the context structure that describes the 16-bit real mode code to call. **/ void AsmPrepareThunk16 (THUNK_CONTEXT *ThunkContext) { IA32_SEGMENT_DESCRIPTOR *RealModeGdt; ASSERT (ThunkContext != NULL); ASSERT ((uintptr_t)ThunkContext->RealModeBuffer < 0x100000); ASSERT (ThunkContext->RealModeBufferSize >= m16Size); ASSERT ((uintptr_t)ThunkContext->RealModeBuffer + m16Size <= 0x100000); memcpy (ThunkContext->RealModeBuffer, &m16Start, m16Size); // // Point RealModeGdt to the GDT to be used in transition // // RealModeGdt[0]: Reserved as NULL descriptor // RealModeGdt[1]: Code Segment // RealModeGdt[2]: Data Segment // RealModeGdt[3]: Call Gate // RealModeGdt = (IA32_SEGMENT_DESCRIPTOR *)( (uintptr_t)ThunkContext->RealModeBuffer + m16Gdt); // // Update Code & Data Segment Descriptor // RealModeGdt[1].Bits.BaseLow = (uint32_t)(uintptr_t)ThunkContext->RealModeBuffer & ~0xf; RealModeGdt[1].Bits.BaseMid = (uint32_t)(uintptr_t)ThunkContext->RealModeBuffer >> 16; // // Update transition code entry point offset // *(uint32_t *)((uintptr_t)ThunkContext->RealModeBuffer + mTransition) += (uint32_t)(uintptr_t)ThunkContext->RealModeBuffer & 0xf; // // Update Segment Limits for both Code and Data Segment Descriptors // if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) { // // Set segment limits to 64KB // RealModeGdt[1].Bits.LimitHigh = 0; RealModeGdt[1].Bits.G = 0; RealModeGdt[2].Bits.LimitHigh = 0; RealModeGdt[2].Bits.G = 0; } // // Update GDTBASE for this thunk context // *(void **)((uintptr_t)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt; // // Update Thunk Attributes // *(uint32_t *)((uintptr_t)ThunkContext->RealModeBuffer + mThunk16Attr) = ThunkContext->ThunkAttributes; } /** Transfers control to a 16-bit real mode entry point and returns the results. Transfers control to a 16-bit real mode entry point and returns the results. AsmPrepareThunk16() must be called with ThunkContext before this function is used. This function must be called with interrupts disabled. The register state from the RealModeState field of ThunkContext is restored just prior to calling the 16-bit real mode entry point. This includes the EFLAGS field of RealModeState, which is used to set the interrupt state when a 16-bit real mode entry point is called. Control is transferred to the 16-bit real mode entry point specified by the CS and Eip fields of RealModeState. The stack is initialized to the SS and ESP fields of RealModeState. Any parameters passed to the 16-bit real mode code must be populated by the caller at SS:ESP prior to calling this function. The 16-bit real mode entry point is invoked with a 16-bit CALL FAR instruction, so when accessing stack contents, the 16-bit real mode code must account for the 16-bit segment and 16-bit offset of the return address that were pushed onto the stack. The 16-bit real mode entry point must exit with a RETF instruction. The register state is captured into RealModeState immediately after the RETF instruction is executed. If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, or any of the 16-bit real mode code makes a SW interrupt, then the caller is responsible for making sure the IDT at address 0 is initialized to handle any HW or SW interrupts that may occur while in 16-bit real mode. If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, then the caller is responsible for making sure the 8259 PIC is in a state compatible with 16-bit real mode. This includes the base vectors, the interrupt masks, and the edge/level trigger mode. If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the ThunkAttributes field of ThunkContext, then the user code is invoked in big real mode. Otherwise, the user code is invoked in 16-bit real mode with 64KB segment limits. If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in ThunkAttributes, then it is assumed that the user code did not enable the A20 mask, and no attempt is made to disable the A20 mask. If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear in ThunkAttributes, then attempt to use the INT 15 service to disable the A20 mask. If this INT 15 call fails, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports. If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in ThunkAttributes, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports. If ThunkContext is NULL, then ASSERT(). If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT(). If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in ThunkAttributes, then ASSERT(). This interface is limited to be used in either physical mode or virtual modes with paging enabled where the virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. @param ThunkContext A pointer to the context structure that describes the 16-bit real mode code to call. **/ void AsmThunk16 (THUNK_CONTEXT *ThunkContext) { IA32_REGISTER_SET *UpdatedRegs; ASSERT (ThunkContext != NULL); ASSERT ((uintptr_t)ThunkContext->RealModeBuffer < 0x100000); ASSERT (ThunkContext->RealModeBufferSize >= m16Size); ASSERT ((uintptr_t)ThunkContext->RealModeBuffer + m16Size <= 0x100000); ASSERT ( ((ThunkContext->ThunkAttributes & (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL)) != \ (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL)) ); UpdatedRegs = InternalAsmThunk16 ( ThunkContext->RealModeState, ThunkContext->RealModeBuffer ); memcpy(ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs)); } /** Prepares all structures and code for a 16-bit real mode thunk, transfers control to a 16-bit real mode entry point, and returns the results. Prepares all structures and code for a 16-bit real mode thunk, transfers control to a 16-bit real mode entry point, and returns the results. If the caller only need to perform a single 16-bit real mode thunk, then this service should be used. If the caller intends to make more than one 16-bit real mode thunk, then it is more efficient if AsmPrepareThunk16() is called once and AsmThunk16() can be called for each 16-bit real mode thunk. This interface is limited to be used in either physical mode or virtual modes with paging enabled where the virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. See AsmPrepareThunk16() and AsmThunk16() for the detailed description and ASSERT() conditions. @param ThunkContext A pointer to the context structure that describes the 16-bit real mode code to call. **/ void AsmPrepareAndThunk16 (THUNK_CONTEXT *ThunkContext) { AsmPrepareThunk16(ThunkContext); AsmThunk16(ThunkContext); } THUNK_CONTEXT mThunkContext; bool InternalLegacyBiosFarCall (uint16_t Segment, uint16_t Offset, EFI_IA32_REGISTER_SET *Regs, void *Stack, uintptr_t StackSize) { // uintptr_t Status; uint16_t *Stack16; // EFI_TPL OriginalTpl; IA32_REGISTER_SET ThunkRegSet; // bool InterruptState; // uint64_t TimerPeriod; memset(&ThunkRegSet, 0, sizeof (ThunkRegSet)); ThunkRegSet.X.DI = Regs->X.DI; ThunkRegSet.X.SI = Regs->X.SI; ThunkRegSet.X.BP = Regs->X.BP; ThunkRegSet.X.BX = Regs->X.BX; ThunkRegSet.X.DX = Regs->X.DX; // // Sometimes, ECX is used to pass in 32 bit data. For example, INT 1Ah, AX = B10Dh is // "PCI BIOS v2.0c + Write Configuration DWORD" and ECX has the dword to write. // ThunkRegSet.E.ECX = Regs->E.ECX; ThunkRegSet.X.AX = Regs->X.AX; ThunkRegSet.E.DS = Regs->X.DS; ThunkRegSet.E.ES = Regs->X.ES; memcpy (&(ThunkRegSet.E.EFLAGS.UintN), &(Regs->X.Flags), sizeof (Regs->X.Flags)); // // Clear the error flag; thunk code may set it. Stack16 should be the high address // Make Statk16 address the low 16 bit must be not zero. // Stack16 = (uint16_t *)((uint8_t *)mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (uint16_t)); // // Save current rate of DXE Timer // // Private->Timer->GetTimerPeriod (Private->Timer, &TimerPeriod); // // Disable DXE Timer while executing in real mode // // Private->Timer->SetTimerPeriod (Private->Timer, 0); // // Save and disable interrupt of debug timer // // InterruptState = SaveAndSetDebugTimerInterrupt (FALSE); // // The call to Legacy16 is a critical section to EFI // // OriginalTpl = ggBS->RaiseTPL (TPL_HIGH_LEVEL); // // Check to see if there is more than one HW interrupt registers with the CPU AP. // If there is, then ASSERT() since that is not compatible with the CSM because // interupts other than the Timer interrupt that was disabled above can not be // handled properly from real mode. // #if 0 DEBUG_CODE_BEGIN (); uintptr_t Vector; uintptr_t Count; for (Vector = 0x20, Count = 0; Vector < 0x100; Vector++) { Status = Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, LegacyBiosNullInterruptHandler); if (Status == EFI_ALREADY_STARTED) { Count++; } if (Status == EFI_SUCCESS) { Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, NULL); } } if (Count >= 2) { printf("ERROR: More than one HW interrupt active with CSM enabled\n"); } ASSERT (Count < 2); DEBUG_CODE_END (); #endif // // If the Timer AP has enabled the 8254 timer IRQ and the current 8254 timer // period is less than the CSM required rate of 54.9254, then force the 8254 // PIT counter to 0, which is the CSM required rate of 54.9254 ms // // if (Private->TimerUses8254 && (TimerPeriod < 549254)) { // SetPitCount (0); // } if ((Stack != NULL) && (StackSize != 0)) { // // Copy Stack to low memory stack // Stack16 -= StackSize / sizeof (uint16_t); memcpy (Stack16, Stack, StackSize); } ThunkRegSet.E.SS = (uint16_t)(((uintptr_t)Stack16 >> 16) << 12); ThunkRegSet.E.ESP = (uint16_t)(uintptr_t)Stack16; ThunkRegSet.E.CS = Segment; ThunkRegSet.E.Eip = Offset; mThunkContext.RealModeState = &ThunkRegSet; // // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases. // /* FIXME: DO we need to care 8259? */ // Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL); // ASSERT_EFI_ERROR (Status); AsmThunk16 (&mThunkContext); if ((Stack != NULL) && (StackSize != 0)) { // // Copy low memory stack to Stack // memcpy (Stack, Stack16, StackSize); } // // Restore protected mode interrupt state // /* FIXME: DO we need to care 8259? */ // Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL); // ASSERT_EFI_ERROR (Status); mThunkContext.RealModeState = NULL; // // Enable and restore rate of DXE Timer // // Private->Timer->SetTimerPeriod (Private->Timer, TimerPeriod); // // End critical section // // ggBS->RestoreTPL (OriginalTpl); // // OPROM may allocate EBDA range by itself and change EBDA base and EBDA size. // Get the current EBDA base address, and compared with pre-allocate minimum // EBDA base address, if the current EBDA base address is smaller, it indicates // PcdEbdaReservedMemorySize should be adjusted to larger for more OPROMs. // #if 0 DEBUG_CODE_BEGIN (); { uintptr_t EbdaBaseAddress; uintptr_t ReservedEbdaBaseAddress; ACCESS_PAGE0_CODE ( EbdaBaseAddress = (*(uint16_t *)(uintptr_t)0x40E) << 4; ReservedEbdaBaseAddress = CONVENTIONAL_MEMORY_TOP - PcdGet32 (PcdEbdaReservedMemorySize); ASSERT (ReservedEbdaBaseAddress <= EbdaBaseAddress); ); } DEBUG_CODE_END (); #endif // // Restore interrupt of debug timer // // SaveAndSetDebugTimerInterrupt (InterruptState); Regs->E.EDI = ThunkRegSet.E.EDI; Regs->E.ESI = ThunkRegSet.E.ESI; Regs->E.EBP = ThunkRegSet.E.EBP; Regs->E.EBX = ThunkRegSet.E.EBX; Regs->E.EDX = ThunkRegSet.E.EDX; Regs->E.ECX = ThunkRegSet.E.ECX; Regs->E.EAX = ThunkRegSet.E.EAX; Regs->X.SS = ThunkRegSet.E.SS; Regs->X.CS = ThunkRegSet.E.CS; Regs->X.DS = ThunkRegSet.E.DS; Regs->X.ES = ThunkRegSet.E.ES; memcpy (&(Regs->X.Flags), &(ThunkRegSet.E.EFLAGS.UintN), sizeof (Regs->X.Flags)); return (bool)(Regs->X.Flags.CF == 1); } // Return final pointer uintptr_t LegacyBiosInitializeThunkAndTable(uintptr_t MemoryAddress, size_t data_size) { uintptr_t data_pages = (data_size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE; mThunkContext.RealModeBuffer = (void *)(uintptr_t)(MemoryAddress + (data_pages * EFI_PAGE_SIZE)); mThunkContext.RealModeBufferSize = EFI_PAGE_SIZE; mThunkContext.ThunkAttributes = THUNK_ATTRIBUTE_BIG_REAL_MODE | THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15; memset(mThunkContext.RealModeBuffer, 0, mThunkContext.RealModeBufferSize); printf("RealmodeBuffer %lx\n", (uintptr_t)mThunkContext.RealModeBuffer); AsmPrepareThunk16 (&mThunkContext); return (uintptr_t)mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize + EFI_PAGE_SIZE; } bool LegacyBiosInt86(uint8_t BiosInt, EFI_IA32_REGISTER_SET *Regs) { uint16_t Segment; uint16_t Offset; /* FIXME: Not working!!!!!!!!!!!! */ Regs->X.Flags.Reserved1 = 1; Regs->X.Flags.Reserved2 = 0; Regs->X.Flags.Reserved3 = 0; Regs->X.Flags.Reserved4 = 0; Regs->X.Flags.IOPL = 3; Regs->X.Flags.NT = 0; Regs->X.Flags.IF = 0; Regs->X.Flags.TF = 0; Regs->X.Flags.CF = 0; // // The base address of legacy interrupt vector table is 0. // We use this base address to get the legacy interrupt handler. // ACCESS_PAGE0_CODE ( Segment = (UINT16)(((UINT32 *)0)[BiosInt] >> 16); Offset = (UINT16)((UINT32 *)0)[BiosInt]; ); return InternalLegacyBiosFarCall ( Segment, Offset, Regs, &Regs->X.Flags, sizeof (Regs->X.Flags) ); } /** Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the 16-bit register context on entry and exit. Arguments can be passed on the Stack argument @param This Protocol instance pointer. @param Segment Segemnt of 16-bit mode call @param Offset Offset of 16-bit mdoe call @param Regs Register contexted passed into (and returned) from thunk to 16-bit mode @param Stack Caller allocated stack used to pass arguments @param StackSize Size of Stack in bytes @retval FALSE Thunk completed, and there were no BIOS errors in the target code. See Regs for status. @retval TRUE There was a BIOS erro in the target code. **/ bool LegacyBiosFarCall86 (uint16_t Segment, uint16_t Offset, EFI_IA32_REGISTER_SET *Regs, void *Stack, uintptr_t StackSize) { Regs->X.Flags.Reserved1 = 1; Regs->X.Flags.Reserved2 = 0; Regs->X.Flags.Reserved3 = 0; Regs->X.Flags.Reserved4 = 0; Regs->X.Flags.IOPL = 3; Regs->X.Flags.NT = 0; Regs->X.Flags.IF = 1; Regs->X.Flags.TF = 0; Regs->X.Flags.CF = 0; return InternalLegacyBiosFarCall (Segment, Offset, Regs, Stack, StackSize); } ================================================ FILE: src/x86thunk.h ================================================ /* * Real Mode Thunk Functions for IA32 and x64. * * Based on various EDK2 headers * * Which is: * Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
* SPDX-License-Identifier: BSD-2-Clause-Patent */ #ifndef _X86_THUNK_H #define _X86_THUNK_H #include #include #include #pragma pack (1) /// /// Byte packed structure for EFLAGS/RFLAGS. /// 32-bits on IA-32. /// 64-bits on x64. The upper 32-bits on x64 are reserved. /// typedef union { struct { uint32_t CF : 1; ///< Carry Flag. uint32_t Reserved_0 : 1; ///< Reserved. uint32_t PF : 1; ///< Parity Flag. uint32_t Reserved_1 : 1; ///< Reserved. uint32_t AF : 1; ///< Auxiliary Carry Flag. uint32_t Reserved_2 : 1; ///< Reserved. uint32_t ZF : 1; ///< Zero Flag. uint32_t SF : 1; ///< Sign Flag. uint32_t TF : 1; ///< Trap Flag. uint32_t IF : 1; ///< Interrupt Enable Flag. uint32_t DF : 1; ///< Direction Flag. uint32_t OF : 1; ///< Overflow Flag. uint32_t IOPL : 2; ///< I/O Privilege Level. uint32_t NT : 1; ///< Nested Task. uint32_t Reserved_3 : 1; ///< Reserved. uint32_t RF : 1; ///< Resume Flag. uint32_t VM : 1; ///< Virtual 8086 Mode. uint32_t AC : 1; ///< Alignment Check. uint32_t VIF : 1; ///< Virtual Interrupt Flag. uint32_t VIP : 1; ///< Virtual Interrupt Pending. uint32_t ID : 1; ///< ID Flag. uint32_t Reserved_4 : 10; ///< Reserved. } Bits; uintptr_t UintN; } IA32_EFLAGS32; /// /// Byte packed structure for an x64 Interrupt Gate Descriptor. /// typedef union { struct { uint32_t OffsetLow : 16; ///< Offset bits 15..0. uint32_t Selector : 16; ///< Selector. uint32_t Reserved_0 : 8; ///< Reserved. uint32_t GateType : 8; ///< Gate Type. See #defines above. uint32_t OffsetHigh : 16; ///< Offset bits 31..16. uint32_t OffsetUpper : 32; ///< Offset bits 63..32. uint32_t Reserved_1 : 32; ///< Reserved. } Bits; struct { uint64_t Uint64; uint64_t Uint64_1; } Uint128; } IA32_IDT_GATE_DESCRIPTOR; // // IA32 Task-State Segment Definition // typedef struct { uint32_t Reserved_0; uint64_t RSP0; uint64_t RSP1; uint64_t RSP2; uint64_t Reserved_28; uint64_t IST[7]; uint64_t Reserved_92; uint16_t Reserved_100; uint16_t IOMapBaseAddress; } IA32_TASK_STATE_SEGMENT; typedef union { struct { uint32_t LimitLow : 16; ///< Segment Limit 15..00 uint32_t BaseLow : 16; ///< Base Address 15..00 uint32_t BaseMidl : 8; ///< Base Address 23..16 uint32_t Type : 4; ///< Type (1 0 B 1) uint32_t Reserved_43 : 1; ///< 0 uint32_t DPL : 2; ///< Descriptor Privilege Level uint32_t P : 1; ///< Segment Present uint32_t LimitHigh : 4; ///< Segment Limit 19..16 uint32_t AVL : 1; ///< Available for use by system software uint32_t Reserved_52 : 2; ///< 0 0 uint32_t G : 1; ///< Granularity uint32_t BaseMidh : 8; ///< Base Address 31..24 uint32_t BaseHigh : 32; ///< Base Address 63..32 uint32_t Reserved_96 : 32; ///< Reserved } Bits; struct { uint64_t Uint64; uint64_t Uint64_1; } Uint128; } IA32_TSS_DESCRIPTOR; /// /// Byte packed structure for an FP/SSE/SSE2 context. /// typedef struct { uint8_t Buffer[512]; } IA32_FX_BUFFER; /// /// Structures for the 16-bit real mode thunks. /// typedef struct { uint32_t Reserved1; uint32_t Reserved2; uint32_t Reserved3; uint32_t Reserved4; uint8_t BL; uint8_t BH; uint16_t Reserved5; uint8_t DL; uint8_t DH; uint16_t Reserved6; uint8_t CL; uint8_t CH; uint16_t Reserved7; uint8_t AL; uint8_t AH; uint16_t Reserved8; } IA32_BYTE_REGS; typedef struct { uint16_t DI; uint16_t Reserved1; uint16_t SI; uint16_t Reserved2; uint16_t BP; uint16_t Reserved3; uint16_t SP; uint16_t Reserved4; uint16_t BX; uint16_t Reserved5; uint16_t DX; uint16_t Reserved6; uint16_t CX; uint16_t Reserved7; uint16_t AX; uint16_t Reserved8; } IA32_WORD_REGS; typedef struct { uint32_t EDI; uint32_t ESI; uint32_t EBP; uint32_t ESP; uint32_t EBX; uint32_t EDX; uint32_t ECX; uint32_t EAX; uint16_t DS; uint16_t ES; uint16_t FS; uint16_t GS; IA32_EFLAGS32 EFLAGS; uint32_t Eip; uint16_t CS; uint16_t SS; } IA32_DWORD_REGS; typedef union { IA32_DWORD_REGS E; IA32_WORD_REGS X; IA32_BYTE_REGS H; } IA32_REGISTER_SET; typedef union { struct { uint32_t LimitLow : 16; uint32_t BaseLow : 16; uint32_t BaseMid : 8; uint32_t Type : 4; uint32_t S : 1; uint32_t DPL : 2; uint32_t P : 1; uint32_t LimitHigh : 4; uint32_t AVL : 1; uint32_t L : 1; uint32_t DB : 1; uint32_t G : 1; uint32_t BaseHigh : 8; } Bits; uint64_t Uint64; } IA32_SEGMENT_DESCRIPTOR; /// /// Byte packed structure for an 16-bit real mode thunks. /// typedef struct { IA32_REGISTER_SET *RealModeState; void *RealModeBuffer; uint32_t RealModeBufferSize; uint32_t ThunkAttributes; } THUNK_CONTEXT; #define THUNK_ATTRIBUTE_BIG_REAL_MODE 0x00000001 #define THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 0x00000002 #define THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL 0x00000004 #pragma pack(1) #define NUM_REAL_GDT_ENTRIES 8 #define CONVENTIONAL_MEMORY_TOP 0xA0000 // 640 KB #define INITIAL_VALUE_BELOW_1K 0x0 // // Define what a processor GDT looks like // typedef struct { uint16_t LimitLow; uint16_t BaseLow; uint8_t BaseMid; uint8_t Attribute; uint8_t LimitHi; uint8_t BaseHi; } GDT64; // // Define what a processor descriptor looks like // This data structure must be kept in sync with ASM STRUCT in Thunk.inc // typedef struct { uint16_t Limit; uint64_t Base; } DESCRIPTOR64; typedef struct { uint16_t Limit; uint32_t Base; } DESCRIPTOR32; // // Low stub lay out // #define LOW_STACK_SIZE (8 * 1024) // 8k? #define EFI_MAX_E820_ENTRY 100 #define FIRST_INSTANCE 1 #define NOT_FIRST_INSTANCE 0 typedef struct { // // Space for the code // The address of Code is also the beginning of the relocated Thunk code // uint8_t Code[4096]; // ? // // Data for the code (cs releative) // DESCRIPTOR64 X64GdtDesc; // Protected mode GDT DESCRIPTOR64 X64IdtDesc; // Protected mode IDT uintptr_t X64Ss; uintptr_t X64Esp; uintptr_t RealStack; DESCRIPTOR32 RealModeIdtDesc; DESCRIPTOR32 RealModeGdtDesc; // // real-mode GDT (temporary GDT with two real mode segment descriptors) // GDT64 RealModeGdt[NUM_REAL_GDT_ENTRIES]; uint64_t PageMapLevel4; // // A low memory stack // uint8_t Stack[LOW_STACK_SIZE]; } LOW_MEMORY_THUNK; #pragma pack() extern uintptr_t LegacyBiosInitializeThunkAndTable(uintptr_t MemoryAddress, size_t data_size); extern bool LegacyBiosFarCall86 (uint16_t Segment, uint16_t Offset, EFI_IA32_REGISTER_SET *Regs, void *Stack, uintptr_t StackSize); #endif