# # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2025 Oxide Computer Company # *.bin *.sym *.efi *.out */amd64/machine */amd64/x86 */i386/machine */i386/x86 efi/*/amd64/machine efi/*/amd64/x86 efi/*/i386/machine efi/*/i386/x86 i386/*/machine i386/*/x86 i386/btx/btx/btx i386/btx/btxldr/btxldr i386/cdboot/cdboot i386/gptzfsboot/gptzfsboot i386/isoboot/isoboot i386/loader/loader i386/loader/loader.help i386/pmbr/pmbr i386/pxeldr/loader i386/pxeldr/pxeboot i386/pxeldr/pxeldr libsa/amd64/*.[ch] libsa/i386/*.[ch] efi/loader/amd64/*.[ch] efi/loader/i386/*.[ch] i386/loader/8x16.c i386/loader/vers.c libficl/softcore/softcore.c libsa/amd64/sha1-x86_64.S # $FreeBSD$ # @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94 The compilation of software known as FreeBSD is distributed under the following terms: Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved. 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. 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. The 4.4BSD and 4.4BSD-Lite software is distributed under the following terms: All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite Releases is copyrighted by The Regents of the University of California. Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. 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. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. The Institute of Electrical and Electronics Engineers and the American National Standards Committee X3, on Information Processing Systems have given us permission to reprint portions of their documentation. In the following statement, the phrase ``this text'' refers to portions of the system documentation. Portions of this text are reprinted and reproduced in electronic form in the second BSD Networking Software Release, from IEEE Std 1003.1-1988, IEEE Standard Portable Operating System Interface for Computer Environments (POSIX), copyright C 1988 by the Institute of Electrical and Electronics Engineers, Inc. In the event of any discrepancy between these versions and the original IEEE Standard, the original IEEE Standard is the referee document. In the following statement, the phrase ``This material'' refers to portions of the system documentation. This material is reproduced with permission from American National Standards Committee X3, on Information Processing Systems. Computer and Business Equipment Manufacturers Association (CBEMA), 311 First St., NW, Suite 500, Washington, DC 20001-2178. The developmental work of Programming Language C was completed by the X3J11 Technical Committee. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the Regents of the University of California. NOTE: The copyright of UC Berkeley's Berkeley Software Distribution ("BSD") source has been updated. The copyright addendum may be found at ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change and is included below. July 22, 1999 To All Licensees, Distributors of Any Version of BSD: As you know, certain of the Berkeley Software Distribution ("BSD") source code files require that further distributions of products containing all or portions of the software, acknowledge within their advertising materials that such products contain software developed by UC Berkeley and its contributors. Specifically, the provision reads: " * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors." Effective immediately, licensees and distributors are no longer required to include the acknowledgement within advertising materials. Accordingly, the foregoing paragraph of those BSD Unix files containing it is hereby deleted in its entirety. William Hoskins Director, Office of Technology Licensing University of California, Berkeley $FreeBSD$ # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2015 Toomas Soome # .KEEP_STATE: include $(SRC)/Makefile.master # Hammerhead: amd64-only, removed i386 (32-bit BIOS bootloader) # Keep efi for UEFI boot, forth for Forth interpreter SUBDIRS = libsa libficl efi forth all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber install : TARGET = install all clean clobber: $(SUBDIRS) # NOTE: Do NOT use "install: all .WAIT $(SUBDIRS)" — GNU Make dispatch bug. # When 'all' builds efi/forth, GNU Make considers them "already built" and # won't re-dispatch them with TARGET=install. Instead, dispatch install to # all SUBDIRS directly. Each subdirectory's own install target handles # building first (e.g. loader's "install: all $(ROOTBOOTFILES)"). install: $(SUBDIRS) # efi and forth depend on support libraries being built first efi: libsa libficl .PARALLEL: libsa libficl $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2017 Toomas Soome # Copyright 2019 Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # # loader.help build needs better awk AWK= /usr/xpg4/bin/awk # Hammerhead: auto-detect GNU binutils paths. # OI has g-prefixed tools (gld, gobjcopy); Hammerhead has unprefixed (gnu-ld, objcopy). GLD= $(shell test -x $(GNU_ROOT)/bin/gld && echo $(GNU_ROOT)/bin/gld || echo /usr/bin/gnu-ld) OBJCOPY= $(shell test -x $(GNU_ROOT)/bin/gobjcopy && echo $(GNU_ROOT)/bin/gobjcopy || echo /usr/bin/objcopy) OBJDUMP= $(shell test -x $(GNU_ROOT)/bin/gobjdump && echo $(GNU_ROOT)/bin/gobjdump || echo /usr/bin/objdump) GSTRIP= $(shell test -x $(GNU_ROOT)/bin/gstrip && echo $(GNU_ROOT)/bin/gstrip || echo /usr/bin/strip) # Default Console font setup. # We want it to be the same as kernel. # We build compressed, stripped down version of the default font, so we have # bare minimum for case we can not load font from the OS root. FONT= 8x16 FONT_SRC= ter-u16b.bdf FONT_DIR= $(SRC)/data/consfonts PNGLITE= $(SRC)/common/pnglite BOOTSRC= $(SRC)/boot SASRC= $(BOOTSRC)/libsa CRYPTOSRC= $(SASRC)/crypto ZFSSRC= $(SASRC)/zfs ZLIB= $(SRC)/contrib/zlib LZ4= $(SRC)/common/lz4 # set standard values AS_CPPFLAGS= CPPFLAGS= -D_STANDALONE -DFICL_WANT_FLOAT=0 -nostdinc CFLAGS64= -mno-red-zone CFLAGS= -Os -ffreestanding -fno-builtin CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -mno-mmx -mno-3dnow -mno-sse -mno-sse2 CFLAGS += -mno-sse3 -msoft-float CFLAGS += -mno-avx -mno-aes CFLAGS += -Wall -Werror CFLAGS += $(CCNOAUTOINLINE) $(CCNOREORDER) $(CSTD_GNU99) CFLAGS += $(CSOURCEDEBUGFLAGS) CCASFLAGS= -Wa,--divide ASFLAGS= -Wa,--divide ASFLAGS64= -Wa,--divide SMATCH_ = SMATCH_on = SMATCH_off = COMPILE.S= $(CC) $(SMATCH_off) $(CCASFLAGS) $(CPPFLAGS) -c ROOT_BOOT= $(ROOT)/boot ROOTBOOTPROG=$(PROG:%=$(ROOT_BOOT)/%) $(ROOT_BOOT)/%: % $(INS.file) #.if ${MACHINE_CPUARCH} == "arm" # Do not generate movt/movw, because the relocation fixup for them does not # translate to the -Bsymbolic -pie format required by self_reloc() in loader(8). # Also, the fpu is not available in a standalone environment. #CFLAGS.clang+= -mllvm -arm-use-movt=0 #CFLAGS.clang+= -mfpu=none #.endif # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2021 Toomas Soome # .SECONDEXPANSION: OBJS= $(OBJECTS:%=objs/%) PICS= $(OBJECTS:%=pics/%) .PARALLEL: $(OBJS) $(PICS) DUMMY $(PICS) : CFLAGS += -fPIC $(PICS) : CCASFLAGS += -fPIC $(OBJS) $(PICS): machine x86 objs pics: -@mkdir -p $@ $(LIBRARY): objs .WAIT $$(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) $(DYNLIB): pics .WAIT $$(PICS) $(AR) $(ARFLAGS) $@ $(PICS) CLEANFILES += $(OBJS) $(PICS) $(LIBRARY) $(DYNLIB) # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2020 RackTop Systems, Inc. # Copyright 2024 MNX Cloud, Inc. # # # The version string is composed according to IPS version string rules: # dotted verstion strings are consisting of numbers and dots, # different strings are separated by comma or dash, # at the end of the dotted version can be timestamp, separated by # the colon. # # The dotted version part are compared by numbers, timestamps are # compared lexicographically, as strings. # # Here we define two version strings, for loader and boot program. # The BOOT_VERSION is used by installboot program to decide if the # boot program update is needed, and should be updated according to # boot loader code updates. LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. BOOT_VERSION = $(LOADER_VERSION)-2026.01.13.1 $FreeBSD$ README file, for the boot config file setup. This is meant to explain how to manage the loader configuration process. The boot and loading process is either defined, or being defined in boot(8) and loader(8). The ongoing development of the FreeBSD bootloader, and its rapid deployment while still in the development phase, has resulted in a large number of installations with outdated configurations. Those installations actively tracking the FreeBSD development should also ensure that their bootloader configurations are updated. If you see files discussed here that your system doesn't yet have, add them yourself. This is an effort to give the currently correct method for setting up your boot process. It includes information on setting up screen savers and plug and play information, and also on recording any changes you make in your kernel configuration. This file is temporary, because as I noted, the process is still undergoing development, and will still change. Man pages are coming out, but they're still going to be somewhat fragile for a while. If you note anything in here that's broken, it would be a good idea to report it to the FreeBSD-current list, or to Daniel C. Sobral or Mike Smith . After the first two stages in the booting process (described in boot(8)), the last stage of the booting process, called the loader (see loader(8)) reads in the /boot/loader.rc file. The two lines you should have there are: include /boot/loader.4th start This reads the ficl (forth) initialization files, then /boot/default/loader.conf. This file, which strongly resembles in form /etc/rc.conf but functions quite differently, has spots for endless user customization but isn't yet completely finished. For one thing, it used to assume a /kernel.config instead of a /boot/kernel.conf. Watch the first few lines of /boot/defaults/loader.conf to see if the file name changes. [See the section at the end on loader.conf syntax] You don't actually want to make any changes to /boot/defaults/loader.conf, the file that is a hacking- target is: /boot/loader.conf and might very likely not exist yet on your system). You should copy /boot/defaults/loader.conf to /boot/loader.conf, and then cut out anything you didn't want changed. The start command also loads your kernel for you, so don't put any lines in there like "load kernel", they'll fail (but really have already worked for you). Start also reads in the file /boot/defaults/loader.conf and /boot/loader.conf. If you don't have /boot/loader.conf, you'll see a message on boot about it, but it's a warning only, no other effects. See the section on loader.conf syntax at the end of this document, for some more pointers on loader.conf syntax. The best way to manage splash screens is with entries in /boot/loader.conf, and this is very clearly illustrated in /boot/defaults/loader.conf (which you could just copy over to /boot/loader.conf). I'm going to illustrate here how you *could* do it in /boot/loader.rc (for information only) but I don't recommend you do this; use the /boot/defaults/loader.conf syntax, it's easier to get it correct. You can load your splash screen by putting the following lines into /boot/loader.rc: load splash_bmp load -t splash_image_data /path/to/file.bmp The top line causes the splash_bmp module to get loaded. The second line has the parameter "-t" which tells the loader that the class of DATA being loaded is not a module, but instead a splash_image_data located in file /path/to/file.bmp. To get your plug and play data correctly set, run kget, redirecting the output to /boot/kernel.conf. Note that kget right now adds an extra "q" to it's output (from the q for quit you press when you exit config), and if you want, you can remove that from the file. Kget reports data only, so feel free to run it, just to see the output. Make certain you have the kernel option USERCONFIG set in your kernel, so that you can do a boot -c, to initially set your cards up. Then, edit /boot/loader.conf so that the following line shows up (overwriting, in effect, a similar line in /boot/default/loader.conf): userconfig_script_load="YES" My own pnp line looks like: pnp 1 0 os irq0 15 irq1 0 drq0 1 drq1 0 port0 1332 (kget changes numbers from hexadecimal to decimal). Note that, at this moment, the change from using /kernel.config to using /boot/kernel.conf as the storage place for kernel config changes is going on. Take a look at your /boot/defaults/loader.conf, see what's defined as userconfig_script_name, and if you override, make sure the file exists. Note that the loader only has access to the root filesystem, so be careful where you tell it to read from. o If you interrupt autoboot, you'll engage interactive mode with loader. Everything you type will have the same effects as if it were lines in /boot/loader.rc. o While in interactive mode, you can get help by typing "?", "help [ []]" and "help index". These are mostly commands one would expect a normal user to use. I recommend you play with them a little, to gain further familiarity with what's going on. Note that it is not possible to damage or corrupt your system while experimenting with the loader, as it cannot write to any of your filesystems. o The command "unload" will unload everything. This is very useful. Once loader.rc has finished and the system is in the autoboot count-down, you will usually have the kernel and other modules loaded. Now, suppose your new /kernel is broken, how do you load /kernel.old? By typing: unload load kernel.old [any other modules you wish to load] boot o If you use loader.conf, you can do: unload set kernel=kernel.old boot-conf this will then load all the modules you have configured, using kernel.old as kernel, and boot. o From loader, you can use the command "more" to read the contents of /boot/loader.rc, if you wish. This is not FreeBSD's more. It is one of loader's builtin commands. Useful if you can't quite recall what you have there. :-) Of course, you can use this command to read anything else you want. o "boot -flag" works, "boot kernelname" works, "boot -flag kernelname" doesn't. "boot kernelname -flag" might work, but I'm not sure. The problem is that these flags are kernel's flags, not boot's flags. o There are a number of variables that can be set. You can see them in loader.conf, but you can get much more detailed information using the "help" command, eg. help set . o The variable root_disk_unit is particularly important, as it solves a relatively common problem. This problem shows when the BIOS assign disk units in a different way than the kernel. For example, if you have two IDE disks, one on the primary, the other on the secondary controller, and both as master, the default in most kernels is having the first as wd0, and the second as wd2. If your root partition is in wd2, you'll get an error, because the BIOS sees these disks as 0 and 1 (well, 1 and 2), and that's what loader tells the kernel. In this case, "set root_disk_unit=2" solves the problem. You use this whenever the kernel fails to mount to root partition because it has a wrong unit number. FILE OVERVIEW o /boot/defaults/loader.conf -- Master configuration file, not to be edited. Overridden by /boot/loader.conf. o /boot/loader.conf -- local system customization file, in form very much like /boot/defaults/loader.conf. This file is meant to be used by local users and the sysinstall process. o /boot/loader.conf.local -- local installation override file. This is intended for use by installations with large numbers of systems, to allow global policy overrides. No FreeBSD tools should ever write this file. o /kernel.config -- old location of kernel configuration changes (like pnp changes). o /boot/kernel.conf -- new location for kernel configuration changes. o /boot/loader.rc -- loader initial configuration file, chiefly used to source in a forth file, and start the configuration process. NOTES ON LOADER.CONF SYNTAX I'm copy here from the last 11 lines from /boot/defaults/loader.conf: ############################################################## ### Module loading syntax example ########################## ############################################################## #module_load="YES" # loads module "module" #module_name="realname" # uses "realname" instead of "module" #module_type="type" # passes "-t type" to load #module_flags="flags" # passes "flags" to the module #module_before="cmd" # executes "cmd" before loading module #module_after="cmd" # executes "cmd" after loading module #module_error="cmd" # executes "cmd" if load fails The way this works, the command processor used by the loader (which is a subset of forth) inspects these variables for their suffix, and the 7 lines above illustrate all the currently defined suffixes, and their use. Take the part before the underscore, and customize it i(make it unique) for your particular use, keeping the suffix to allow the particular function you want to activate. Extra underscores are fine, because it's only the sufixes that are scanned for. (authors Chuck Robey and Daniel Sobral). # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2022 Toomas Soome # This is source tree snapshot of loader and related parts from freebsd source. Directory tree layout: usr/src/boot is the root directory of the imported snapshot, containing Makefile and licence notes for build and packaging. Directories from freebsd userland (freebsd /usr/src tree): include Directories from freebsd kernel tree are located in sys subdirectory (freebsd /usr/src/sys tree): platform specific include files: sys/amd64 sys/i386 sys/x86 sys and ufs include files: sys/sys sys/ufs zfs boot module import in freebsd: sys/cddl Note, some of the directories are not 1:1 mapping in this source import, because of differences of build systems used in illumos and freebsd. Also some differences are due to fact, we do not need all the variants of stage1/stage2 boot blocks which are built in freebsd due to the historical or technical reasons. Feb, 2022 /* * Copyright (c) 1998 Michael Smith * Copyright 2015 Toomas Soome * All rights reserved. * * 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. * * 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. */ #include #include /* * Simple hashed block cache */ #include #include #include #include #include "bootstrap.h" /* #define BCACHE_DEBUG */ #ifdef BCACHE_DEBUG #define DPRINTF(fmt, args...) printf("%s: " fmt "\n", __func__, ## args) #else #define DPRINTF(fmt, args...) ((void)0) #endif struct bcachectl { daddr_t bc_blkno; int bc_count; }; /* * bcache per device node. cache is allocated on device first open and freed * on last close, to save memory. The issue there is the size; biosdisk * supports up to 31 (0x1f) devices. Classic setup would use single disk * to boot from, but this has changed with zfs. */ struct bcache { struct bcachectl *bcache_ctl; caddr_t bcache_data; size_t bcache_nblks; size_t ra; }; static uint_t bcache_total_nblks; /* set by bcache_init */ static uint_t bcache_blksize; /* set by bcache_init */ static uint_t bcache_numdev; /* set by bcache_add_dev */ /* statistics */ static uint_t bcache_units; /* number of devices with cache */ static uint_t bcache_unit_nblks; /* nblocks per unit */ static uint_t bcache_hits; static uint_t bcache_misses; static uint_t bcache_ops; static uint_t bcache_bypasses; static uint_t bcache_bcount; static uint_t bcache_rablks; #define BHASH(bc, blkno) ((blkno) & ((bc)->bcache_nblks - 1)) #define BCACHE_LOOKUP(bc, blkno) \ ((bc)->bcache_ctl[BHASH((bc), (blkno))].bc_blkno != (blkno)) #define BCACHE_READAHEAD 256 #define BCACHE_MINREADAHEAD 32 static void bcache_invalidate(struct bcache *bc, daddr_t blkno); static void bcache_insert(struct bcache *bc, daddr_t blkno); static void bcache_free_instance(struct bcache *bc); /* * Initialise the cache for (nblks) of (bsize). */ void bcache_init(size_t nblks, size_t bsize) { /* set up control data */ bcache_total_nblks = nblks; bcache_blksize = bsize; } /* * add number of devices to bcache. we have to divide cache space * between the devices, so bcache_add_dev() can be used to set up the * number. The issue is, we need to get the number before actual allocations. * bcache_add_dev() is supposed to be called from device init() call, so the * assumption is, devsw dv_init is called for plain devices first, and * for zfs, last. */ void bcache_add_dev(int devices) { bcache_numdev += devices; } void * bcache_allocate(void) { uint_t i; struct bcache *bc = malloc(sizeof (struct bcache)); int disks = bcache_numdev; if (disks == 0) disks = 1; /* safe guard */ if (bc == NULL) { errno = ENOMEM; return (bc); } /* * the bcache block count must be power of 2 for hash function */ i = fls(disks) - 1; /* highbit - 1 */ if (disks > (1 << i)) /* next power of 2 */ i++; bc->bcache_nblks = bcache_total_nblks >> i; bcache_unit_nblks = bc->bcache_nblks; bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize); if (bc->bcache_data == NULL) { /* dont error out yet. fall back to 32 blocks and try again */ bc->bcache_nblks = 32; bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize + sizeof (uint32_t)); } bc->bcache_ctl = malloc(bc->bcache_nblks * sizeof (struct bcachectl)); if ((bc->bcache_data == NULL) || (bc->bcache_ctl == NULL)) { bcache_free_instance(bc); errno = ENOMEM; return (NULL); } /* Flush the cache */ for (i = 0; i < bc->bcache_nblks; i++) { bc->bcache_ctl[i].bc_count = -1; bc->bcache_ctl[i].bc_blkno = -1; } bcache_units++; bc->ra = BCACHE_READAHEAD; /* optimistic read ahead */ return (bc); } void bcache_free(void *cache) { struct bcache *bc = cache; if (bc == NULL) return; bcache_free_instance(bc); bcache_units--; } /* * Handle a write request; write directly to the disk, and populate the * cache with the new values. */ static int write_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct bcache_devdata *dd = (struct bcache_devdata *)devdata; struct bcache *bc = dd->dv_cache; daddr_t i, nblk; nblk = size / bcache_blksize; /* Invalidate the blocks being written */ for (i = 0; i < nblk; i++) { bcache_invalidate(bc, blk + i); } /* Write the blocks */ return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); } /* * Handle a read request; fill in parts of the request that can * be satisfied by the cache, use the supplied strategy routine to do * device I/O and then use the I/O results to populate the cache. */ static int read_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct bcache_devdata *dd = devdata; struct bcache *bc = dd->dv_cache; size_t i, nblk, p_size, r_size, complete, ra; int result; daddr_t p_blk; caddr_t p_buf; if (bc == NULL) { errno = ENODEV; return (-1); } if (rsize != NULL) *rsize = 0; nblk = size / bcache_blksize; if (nblk == 0 && size != 0) nblk++; result = 0; complete = 1; /* Satisfy any cache hits up front, break on first miss */ for (i = 0; i < nblk; i++) { if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) { bcache_misses += (nblk - i); complete = 0; if (nblk - i > BCACHE_MINREADAHEAD && bc->ra > BCACHE_MINREADAHEAD) bc->ra >>= 1; /* reduce read ahead */ break; } else { bcache_hits++; } } if (complete) { /* whole set was in cache, return it */ if (bc->ra < BCACHE_READAHEAD) bc->ra <<= 1; /* increase read ahead */ bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); goto done; } /* * Fill in any misses. From check we have i pointing to first missing * block, read in all remaining blocks + readahead. * We have space at least for nblk - i before bcache wraps. */ p_blk = blk + i; p_buf = bc->bcache_data + (bcache_blksize * BHASH(bc, p_blk)); r_size = bc->bcache_nblks - BHASH(bc, p_blk); /* remaining blocks */ p_size = MIN(r_size, nblk - i); /* read at least those blocks */ /* * The read ahead size setup. * While the read ahead can save us IO, it also can complicate things: * 1. We do not want to read ahead by wrapping around the * bcache end - this would complicate the cache management. * 2. We are using bc->ra as dynamic hint for read ahead size, * detected cache hits will increase the read-ahead block count, * and misses will decrease, see the code above. * 3. The bcache is sized by 512B blocks, however, the underlying device * may have a larger sector size, and we should perform the IO by * taking into account these larger sector sizes. We could solve * this by passing the sector size to bcache_allocate(), or by * using ioctl(), but in this version we are using the constant, * 16 blocks, and are rounding read ahead block count down to * multiple of 16. Using the constant has two reasons, we are not * entirely sure if the BIOS disk interface is providing the * correct value for sector size. And secondly, this way we get * the most conservative setup for the ra. * * The selection of multiple of 16 blocks (8KB) is quite arbitrary, * however, we want to cover CDs (2K) and 4K disks. * bcache_allocate() will always fall back to a minimum of 32 blocks. * Our choice of 16 read ahead blocks will always fit inside the bcache. */ if ((rw & F_NORA) == F_NORA) ra = 0; else ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size); if (ra != 0 && ra != bc->bcache_nblks) { /* do we have RA space? */ ra = MIN(bc->ra, ra - 1); ra = rounddown(ra, 16); /* multiple of 16 blocks */ p_size += ra; } /* invalidate bcache */ for (i = 0; i < p_size; i++) { bcache_invalidate(bc, p_blk + i); } r_size = 0; /* * with read-ahead, it may happen we are attempting to read past * disk end, as bcache has no information about disk size. * in such case we should get partial read if some blocks can be * read or error, if no blocks can be read. * in either case we should return the data in bcache and only * return error if there is no data. */ rw &= F_MASK; result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, p_size * bcache_blksize, p_buf, &r_size); r_size /= bcache_blksize; for (i = 0; i < r_size; i++) bcache_insert(bc, p_blk + i); /* update ra statistics */ if (r_size != 0) { if (r_size < p_size) bcache_rablks += (p_size - r_size); else bcache_rablks += ra; } /* check how much data can we copy */ for (i = 0; i < nblk; i++) { if (BCACHE_LOOKUP(bc, (daddr_t)(blk + i))) break; } if (size > i * bcache_blksize) size = i * bcache_blksize; if (size != 0) { bcopy(bc->bcache_data + (bcache_blksize * BHASH(bc, blk)), buf, size); result = 0; } done: if ((result == 0) && (rsize != NULL)) *rsize = size; return (result); } /* * Requests larger than 1/2 cache size will be bypassed and go * directly to the disk. XXX tune this. */ int bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct bcache_devdata *dd = (struct bcache_devdata *)devdata; struct bcache *bc = dd->dv_cache; uint_t bcache_nblks = 0; int nblk, cblk, ret; size_t csize, isize, total; bcache_ops++; if (bc != NULL) bcache_nblks = bc->bcache_nblks; /* bypass large requests, or when the cache is inactive */ if (bc == NULL || ((size * 2 / bcache_blksize) > bcache_nblks)) { DPRINTF("bypass %zu from %jd", size / bcache_blksize, (intmax_t)blk); bcache_bypasses++; rw &= F_MASK; return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); } switch (rw & F_MASK) { case F_READ: nblk = size / bcache_blksize; if (size != 0 && nblk == 0) nblk++; /* read at least one block */ ret = 0; total = 0; while (size) { /* # of blocks left */ cblk = bcache_nblks - BHASH(bc, blk); cblk = MIN(cblk, nblk); if (size <= bcache_blksize) csize = size; else csize = cblk * bcache_blksize; ret = read_strategy(devdata, rw, blk, csize, buf + total, &isize); /* * we may have error from read ahead, if we have read * some data return partial read. */ if (ret != 0 || isize == 0) { if (total != 0) ret = 0; break; } blk += isize / bcache_blksize; total += isize; size -= isize; nblk = size / bcache_blksize; } if (rsize) *rsize = total; return (ret); case F_WRITE: return (write_strategy(devdata, F_WRITE, blk, size, buf, rsize)); } return (-1); } /* * Free allocated bcache instance */ static void bcache_free_instance(struct bcache *bc) { if (bc != NULL) { free(bc->bcache_ctl); free(bc->bcache_data); free(bc); } } /* * Insert a block into the cache. */ static void bcache_insert(struct bcache *bc, daddr_t blkno) { uint_t cand; cand = BHASH(bc, blkno); DPRINTF("insert blk %jd -> %u # %d", (intmax_t)blkno, cand, bcache_bcount); bc->bcache_ctl[cand].bc_blkno = blkno; bc->bcache_ctl[cand].bc_count = bcache_bcount++; } /* * Invalidate a block from the cache. */ static void bcache_invalidate(struct bcache *bc, daddr_t blkno) { uint_t i; i = BHASH(bc, blkno); if (bc->bcache_ctl[i].bc_blkno == blkno) { bc->bcache_ctl[i].bc_count = -1; bc->bcache_ctl[i].bc_blkno = -1; DPRINTF("invalidate blk %jd", (intmax_t)blkno); } } COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache); static int command_bcache(int argc, char *argv[] __unused) { if (argc != 1) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } printf("\ncache blocks: %u\n", bcache_total_nblks); printf("cache blocksz: %u\n", bcache_blksize); printf("cache readahead: %u\n", bcache_rablks); printf("unit cache blocks: %u\n", bcache_unit_nblks); printf("cached units: %u\n", bcache_units); printf("%u ops %u bypasses %u hits %u misses\n", bcache_ops, bcache_bypasses, bcache_hits, bcache_misses); return (CMD_OK); } /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include /* * Loading modules, booting the system */ #include #include #include "bootstrap.h" static char *getbootfile(int try); static int loadakernel(int try, int argc, char *argv[]); /* * List of kernel names to try (may be overwritten by boot.config) * XXX should move from here? */ static const char *default_bootfiles = "kernel"; static int autoboot_tried; /* * The user wants us to boot. */ COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot); static int command_boot(int argc, char *argv[]) { struct preloaded_file *fp; /* * See if the user has specified an explicit kernel to boot. */ if ((argc > 1) && (argv[1][0] == '/')) { /* XXX maybe we should discard everything and start again? */ if (file_findfile(NULL, NULL) != NULL) { snprintf(command_errbuf, sizeof (command_errbuf), "can't boot '%s', kernel module already loaded", argv[1]); return (CMD_ERROR); } /* find/load the kernel module */ if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0) return (CMD_ERROR); /* we have consumed all arguments */ argc = 1; } /* * See if there is a kernel module already loaded */ if (file_findfile(NULL, NULL) == NULL) if (loadakernel(0, argc - 1, argv + 1)) { /* we have consumed all arguments */ argc = 1; } /* * Loaded anything yet? */ if ((fp = file_findfile(NULL, NULL)) == NULL) { command_errmsg = "no bootable kernel"; return (CMD_ERROR); } /* * If we were given arguments, discard any previous. * XXX should we merge arguments? Hard to DWIM. */ if (argc > 1) { free(fp->f_args); fp->f_args = unargv(argc - 1, argv + 1); } /* Hook for platform-specific autoloading of modules */ if (archsw.arch_autoload() != 0) return (CMD_ERROR); /* Call the exec handler from the loader matching the kernel */ file_formats[fp->f_loader]->l_exec(fp); return (CMD_ERROR); } /* * Autoboot after a delay */ COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_autoboot); static int command_autoboot(int argc, char *argv[]) { int howlong; char *cp, *prompt; prompt = NULL; howlong = -1; switch (argc) { case 3: prompt = argv[2]; /* FALLTHROUGH */ case 2: howlong = strtol(argv[1], &cp, 0); if (*cp != 0) { snprintf(command_errbuf, sizeof (command_errbuf), "bad delay '%s'", argv[1]); return (CMD_ERROR); } /* FALLTHROUGH */ case 1: return (autoboot(howlong, prompt)); } command_errmsg = "too many arguments"; return (CMD_ERROR); } /* * Called before we go interactive. If we think we can autoboot, and * we haven't tried already, try now. */ void autoboot_maybe(void) { char *cp; /* compatibility with sparc prom, check for autoboot? */ cp = getenv("autoboot?"); if (cp != NULL && strcasecmp(cp, "true") != 0) return; cp = getenv("autoboot_delay"); if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO"))) autoboot(-1, NULL); /* try to boot automatically */ } int autoboot(int timeout, char *prompt) { time_t when, otime, ntime; int c, yes; char *argv[2], *cp, *ep; char *kernelname; struct preloaded_file *fp; autoboot_tried = 1; if (timeout == -1) { timeout = 10; /* try to get a delay from the environment */ if ((cp = getenv("autoboot_delay"))) { timeout = strtol(cp, &ep, 0); if (cp == ep) timeout = 10; /* Unparseable? Set default! */ } } fp = file_findfile(NULL, NULL); if (fp == NULL) { /* no preloaded files, run command start to load all */ bf_run("start"); fp = file_findfile(NULL, NULL); if (fp == NULL) { /* still nothing? can't boot */ command_errmsg = "no valid kernel found"; return (CMD_ERROR); } } kernelname = fp->f_name; if (timeout >= 0) { otime = time(NULL); when = otime + timeout; /* when to boot */ yes = 0; printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key " "for command prompt." : prompt); for (;;) { if (ischar()) { c = getchar(); if ((c == '\r') || (c == '\n')) yes = 1; break; } ntime = time(NULL); if (ntime >= when) { yes = 1; break; } if (ntime != otime) { printf("\rBooting [%s] in %d second%s... ", kernelname, (int)(when - ntime), (when - ntime) == 1? "":"s"); otime = ntime; } } } else { yes = 1; } if (yes) printf("\rBooting [%s]... ", kernelname); putchar('\n'); if (yes) { argv[0] = "boot"; argv[1] = NULL; return (command_boot(1, argv)); } return (CMD_OK); } /* * Scrounge for the name of the (try)'th file we will try to boot. */ static char * getbootfile(int try) { static char *name = NULL; const char *spec, *ep; size_t len; /* we use dynamic storage */ free(name); name = NULL; /* * Try $bootfile, then try our builtin default */ if ((spec = getenv("bootfile")) == NULL) spec = default_bootfiles; while ((try > 0) && (spec != NULL)) { spec = strchr(spec, ';'); if (spec) spec++; /* skip over the leading ';' */ try--; } if (spec != NULL) { if ((ep = strchr(spec, ';')) != NULL) { len = ep - spec; } else { len = strlen(spec); } name = malloc(len + 1); strncpy(name, spec, len); name[len] = 0; } if (name && name[0] == 0) { free(name); name = NULL; } return (name); } /* * Try to find the /etc/fstab file on the filesystem (rootdev), * which should be be the root filesystem, and parse it to find * out what the kernel ought to think the root filesystem is. * * If we're successful, set vfs.root.mountfrom to : * so that the kernel can tell both which VFS and which node to use * to mount the device. If this variable's already set, don't * overwrite it. */ int getrootmount(char *rootdev) { char lbuf[128], *cp, *ep, *dev, *fstyp, *options; int fd, error; if (getenv("vfs.root.mountfrom") != NULL) return (0); error = 1; sprintf(lbuf, "%s/etc/fstab", rootdev); if ((fd = open(lbuf, O_RDONLY)) < 0) goto notfound; /* * loop reading lines from /etc/fstab * What was that about sscanf again? */ fstyp = NULL; dev = NULL; while (fgetstr(lbuf, sizeof (lbuf), fd) >= 0) { if ((lbuf[0] == 0) || (lbuf[0] == '#')) continue; /* skip device name */ for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++) ; if (*cp == 0) /* misformatted */ continue; /* delimit and save */ *cp++ = 0; free(dev); dev = strdup(lbuf); /* skip whitespace up to mountpoint */ while ((*cp != 0) && isspace(*cp)) cp++; /* must have / to be root */ if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1))) continue; /* skip whitespace up to fstype */ cp += 2; while ((*cp != 0) && isspace(*cp)) cp++; if (*cp == 0) /* misformatted */ continue; /* skip text to end of fstype and delimit */ ep = cp; while ((*cp != 0) && !isspace(*cp)) cp++; *cp = 0; free(fstyp); fstyp = strdup(ep); /* skip whitespace up to mount options */ cp += 1; while ((*cp != 0) && isspace(*cp)) cp++; if (*cp == 0) /* misformatted */ continue; /* skip text to end of mount options and delimit */ ep = cp; while ((*cp != 0) && !isspace(*cp)) cp++; *cp = 0; options = strdup(ep); /* * Build the : and save it in * vfs.root.mountfrom */ sprintf(lbuf, "%s:%s", fstyp, dev); setenv("vfs.root.mountfrom", lbuf, 0); /* * Don't override vfs.root.mountfrom.options if it is * already set */ if (getenv("vfs.root.mountfrom.options") == NULL) { /* save mount options */ setenv("vfs.root.mountfrom.options", options, 0); } free(options); error = 0; break; } close(fd); free(dev); free(fstyp); notfound: if (error) { const char *currdev; currdev = getenv("currdev"); if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) { cp = strdup(currdev); cp[strlen(cp) - 1] = '\0'; setenv("vfs.root.mountfrom", cp, 0); error = 0; free(cp); } } return (error); } static int loadakernel(int try, int argc, char *argv[]) { char *cp; for (try = 0; (cp = getbootfile(try)) != NULL; try++) if (mod_loadkld(cp, argc - 1, argv + 1) != 0) printf("can't load '%s'\n", cp); else return (1); return (0); } /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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 _BOOTSTRAP_H_ #define _BOOTSTRAP_H_ #include #include #include #include /* Commands and return values; nonzero return sets command_errmsg != NULL */ typedef int (bootblk_cmd_t)(int argc, char *argv[]); #define COMMAND_ERRBUFSZ (256) extern const char *command_errmsg; extern char command_errbuf[COMMAND_ERRBUFSZ]; #define CMD_OK 0 #define CMD_WARN 1 #define CMD_ERROR 2 #define CMD_CRIT 3 #define CMD_FATAL 4 /* interp.c */ void interact(const char *rc); int include(const char *filename); /* interp_backslash.c */ char *backslash(char *str); /* interp_parse.c */ int parse(int *argc, char ***argv, char *str); /* interp_forth.c */ void bf_init(char *rc); int bf_run(char *line); /* boot.c */ int autoboot(int timeout, char *prompt); void autoboot_maybe(void); int getrootmount(char *rootdev); /* misc.c */ char *unargv(int argc, char *argv[]); void hexdump(caddr_t region, size_t len); size_t strlenout(vm_offset_t str); char *strdupout(vm_offset_t str); void kern_bzero(vm_offset_t dest, size_t len); int kern_pread(int fd, vm_offset_t dest, size_t len, off_t off); void *alloc_pread(int fd, off_t off, size_t len); /* bcache.c */ void bcache_init(size_t nblks, size_t bsize); void bcache_add_dev(int); void *bcache_allocate(void); void bcache_free(void *); int bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); /* * Disk block cache */ struct bcache_devdata { int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); void *dv_devdata; void *dv_cache; }; /* * Modular console support. */ struct console { char *c_name; char *c_desc; int c_flags; #define C_PRESENTIN (1<<0) /* console can provide input */ #define C_PRESENTOUT (1<<1) /* console can provide output */ #define C_ACTIVEIN (1<<2) /* user wants input from console */ #define C_ACTIVEOUT (1<<3) /* user wants output to console */ #define C_WIDEOUT (1<<4) /* c_out routine groks wide chars */ #define C_MODERAW (1<<5) /* raw mode */ /* set c_flags to match hardware */ void (*c_probe)(struct console *); /* reinit XXX may need more args */ int (*c_init)(struct console *, int); /* emit c */ void (*c_out)(struct console *, int); /* wait for and return input */ int (*c_in)(struct console *); /* return nonzero if input is waiting */ int (*c_ready)(struct console *); int (*c_ioctl)(struct console *, int, void *); /* Print device info */ void (*c_devinfo)(struct console *); void *c_private; /* private data */ }; /* * Provide either pointer to console device or init function * to add devices to array of console devices. */ struct console_template { struct console *ct_dev; void (*ct_init)(void); }; extern struct console_template ct_list[]; extern struct console **consoles; uint_t cons_array_size(void); int cons_inputdev(void); void cons_probe(void); void cons_mode(int); struct console *cons_get_console(const char *); void autoload_font(bool); /* * Plug-and-play enumerator/configurator interface. */ struct pnphandler { const char *pp_name; /* handler/bus name */ /* enumerate PnP devices, add to chain */ void (*pp_enumerate)(void); }; struct pnpident { /* ASCII identifier, actual format varies with bus/handler */ char *id_ident; STAILQ_ENTRY(pnpident) id_link; }; struct pnpinfo { /* ASCII description, optional */ char *pi_desc; /* optional revision (or -1) if not supported */ int pi_revision; /* module/args nominated to handle device */ char *pi_module; /* module arguments */ int pi_argc; char **pi_argv; /* handler which detected this device */ struct pnphandler *pi_handler; /* list of identifiers */ STAILQ_HEAD(, pnpident) pi_ident; STAILQ_ENTRY(pnpinfo) pi_link; }; STAILQ_HEAD(pnpinfo_stql, pnpinfo); extern struct pnphandler *pnphandlers[]; /* provided by MD code */ void pnp_addident(struct pnpinfo *pi, char *ident); struct pnpinfo *pnp_allocinfo(void); void pnp_freeinfo(struct pnpinfo *pi); void pnp_addinfo(struct pnpinfo *pi); char *pnp_eisaformat(uint8_t *data); /* * < 0 - No ISA in system * == 0 - Maybe ISA, search for read data port * > 0 - ISA in system, value is read data port address */ extern int isapnp_readport; /* * Version information */ extern char bootprog_info[]; /* * Preloaded file metadata header. * * Metadata are allocated on our heap, and copied into kernel space * before executing the kernel. */ struct file_metadata { size_t md_size; uint16_t md_type; struct file_metadata *md_next; /* data are immediately appended */ char md_data[1]; }; struct preloaded_file; struct mod_depend; struct kernel_module { char *m_name; /* module name */ int m_version; /* module version */ char *m_args; /* arguments for the module */ struct preloaded_file *m_fp; struct kernel_module *m_next; }; /* * Preloaded file information. Depending on type, file can contain * additional units called 'modules'. * * At least one file (the kernel) must be loaded in order to boot. * The kernel is always loaded first. * * String fields (m_name, m_type) should be dynamically allocated. */ struct preloaded_file { char *f_name; /* file name */ /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ char *f_type; char *f_args; /* arguments for the file */ /* metadata that will be placed in the module directory */ struct file_metadata *f_metadata; /* index of the loader that read the file */ int f_loader; vm_offset_t f_addr; /* load address */ size_t f_size; /* file size */ struct kernel_module *f_modules; /* list of modules if any */ struct preloaded_file *f_next; /* next file */ }; struct file_format { /* * Load function must return EFTYPE if it can't handle the module * supplied. */ int (*l_load)(char *, uint64_t, struct preloaded_file **); /* * Only a loader that will load a kernel (first module) * should have an exec handler. */ int (*l_exec)(struct preloaded_file *); }; extern struct file_format *file_formats[]; /* supplied by consumer */ extern struct preloaded_file *preloaded_files; int mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]); int mod_loadkld(const char *name, int argc, char *argv[]); void unload(void); struct preloaded_file *file_alloc(void); struct preloaded_file *file_findfile(const char *name, const char *type); struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type); struct preloaded_file *file_loadraw(const char *name, char *type, int argc, char **argv, int insert); void file_discard(struct preloaded_file *fp); void file_addmetadata(struct preloaded_file *, int, size_t, void *); int file_addmodule(struct preloaded_file *, char *, int, struct kernel_module **); void build_environment_module(void); void build_font_module(void); vm_offset_t bi_copyenv(vm_offset_t); /* MI module loaders */ #ifdef __elfN /* Relocation types. */ #define ELF_RELOC_REL 1 #define ELF_RELOC_RELA 2 /* Relocation offset for some architectures */ extern uint64_t __elfN(relocation_offset); struct elf_file; typedef Elf_Addr(symaddr_fn)(struct elf_file *, Elf_Size); int elf64_loadfile(char *, uint64_t, struct preloaded_file **); int elf32_loadfile(char *, uint64_t, struct preloaded_file **); int elf64_obj_loadfile(char *, uint64_t, struct preloaded_file **); int elf32_obj_loadfile(char *, uint64_t, struct preloaded_file **); int __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, int reltype, Elf_Addr relbase, Elf_Addr dataaddr, void *data, size_t len); int elf64_loadfile_raw(char *, uint64_t, struct preloaded_file **, int); int elf32_loadfile_raw(char *, uint64_t, struct preloaded_file **, int); int elf64_load_modmetadata(struct preloaded_file *, uint64_t); int elf32_load_modmetadata(struct preloaded_file *, uint64_t); #endif /* * Support for commands */ struct bootblk_command { const char *c_name; const char *c_desc; bootblk_cmd_t *c_fn; }; #define COMMAND_SET(tag, key, desc, func) \ static bootblk_cmd_t func; \ static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ DATA_SET(Xcommand_set, _cmd_ ## tag) SET_DECLARE(Xcommand_set, struct bootblk_command); /* * The intention of the architecture switch is to provide a convenient * encapsulation of the interface between the bootstrap MI and MD code. * MD code may selectively populate the switch at runtime based on the * actual configuration of the target system. */ struct arch_switch { /* Automatically load modules as required by detected hardware */ int (*arch_autoload)(void); /* Locate the device for (name), return pointer to tail in (*path) */ int (*arch_getdev)(void **dev, const char *name, const char **path); /* * Copy from local address space to module address space, * similar to bcopy() */ ssize_t (*arch_copyin)(const void *src, vm_offset_t dest, const size_t len); /* * Copy to local address space from module address space, * similar to bcopy() */ ssize_t (*arch_copyout)(const vm_offset_t src, void *dest, const size_t len); /* Read from file to module address space, same semantics as read() */ ssize_t (*arch_readin)(const int fd, vm_offset_t dest, const size_t len); /* Perform ISA byte port I/O (only for systems with ISA) */ int (*arch_isainb)(int port); void (*arch_isaoutb)(int port, int value); /* * Interface to adjust the load address according to the "object" * being loaded. */ vm_offset_t (*arch_loadaddr)(uint_t type, void *data, vm_offset_t addr); #define LOAD_ELF 1 /* data points to the ELF header. */ #define LOAD_RAW 2 /* data points to the module file name. */ #define LOAD_KERN 3 /* data points to the kernel file name. */ #define LOAD_MEM 4 /* data points to int for buffer size. */ /* * Interface to release the load address. */ void (*arch_free_loadaddr)(vm_offset_t addr, size_t pages); /* * Interface to inform MD code about a loaded (ELF) segment. This * can be used to flush caches and/or set up translations. */ #ifdef __elfN void (*arch_loadseg)(Elf_Ehdr *eh, Elf_Phdr *ph, uint64_t delta); #else void (*arch_loadseg)(void *eh, void *ph, uint64_t delta); #endif /* Probe ZFS pool(s), if needed. */ void (*arch_zfs_probe)(void); /* Return the hypervisor name/type or NULL if not virtualized. */ const char *(*arch_hypervisor)(void); }; extern struct arch_switch archsw; /* This must be provided by the MD code, but should it be in the archsw? */ void delay(int delay); void dev_cleanup(void); /* * nvstore API. */ typedef int (nvstore_getter_cb_t)(void *, const char *, void **); typedef int (nvstore_setter_cb_t)(void *, int, const char *, const void *, size_t); typedef int (nvstore_setter_str_cb_t)(void *, const char *, const char *, const char *); typedef int (nvstore_unset_cb_t)(void *, const char *); typedef int (nvstore_print_cb_t)(void *, void *); typedef int (nvstore_iterate_cb_t)(void *, int (*)(void *, void *)); typedef struct nvs_callbacks { nvstore_getter_cb_t *nvs_getter; nvstore_setter_cb_t *nvs_setter; nvstore_setter_str_cb_t *nvs_setter_str; nvstore_unset_cb_t *nvs_unset; nvstore_print_cb_t *nvs_print; nvstore_iterate_cb_t *nvs_iterate; } nvs_callbacks_t; int nvstore_init(const char *, nvs_callbacks_t *, void *); int nvstore_fini(const char *); void *nvstore_get_store(const char *); int nvstore_print(void *); int nvstore_get_var(void *, const char *, void **); int nvstore_set_var(void *, int, const char *, void *, size_t); int nvstore_set_var_from_string(void *, const char *, const char *, const char *); int nvstore_unset_var(void *, const char *); #define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") #endif /* !_BOOTSTRAP_H_ */ /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include #include #include #include "bootstrap.h" const char *command_errmsg; /* XXX should have procedural interface for setting, size limit? */ char command_errbuf[COMMAND_ERRBUFSZ]; static int page_file(char *filename); /* BEGIN CSTYLED */ /* * Help is read from a formatted text file. * * Entries in the file are formatted as # Ttopic [Ssubtopic] Ddescription help text here # * * Note that for code simplicity's sake, the above format must be followed * exactly. * * Subtopic entries must immediately follow the topic (this is used to * produce the listing of subtopics). * * If no argument(s) are supplied by the user, the help for 'help' is displayed. */ /* END CSTYLED */ COMMAND_SET(help, "help", "detailed help", command_help); static int help_getnext(int fd, char **topic, char **subtopic, char **desc) { char line[81], *cp, *ep; /* Make sure we provide sane values. */ *topic = *subtopic = *desc = NULL; for (;;) { if (fgetstr(line, 80, fd) < 0) return (0); if (strlen(line) < 3 || line[0] != '#' || line[1] != ' ') continue; *topic = *subtopic = *desc = NULL; cp = line + 2; while (cp != NULL && *cp != 0) { ep = strchr(cp, ' '); if (*cp == 'T' && *topic == NULL) { if (ep != NULL) *ep++ = 0; *topic = strdup(cp + 1); } else if (*cp == 'S' && *subtopic == NULL) { if (ep != NULL) *ep++ = 0; *subtopic = strdup(cp + 1); } else if (*cp == 'D') { *desc = strdup(cp + 1); ep = NULL; } cp = ep; } if (*topic == NULL) { free(*subtopic); free(*desc); *subtopic = *desc = NULL; continue; } return (1); } } static int help_emitsummary(char *topic, char *subtopic, char *desc) { int i; pager_output(" "); pager_output(topic); i = strlen(topic); if (subtopic != NULL) { pager_output(" "); pager_output(subtopic); i += strlen(subtopic) + 1; } if (desc != NULL) { do { pager_output(" "); } while (i++ < 30); pager_output(desc); } return (pager_output("\n")); } static int command_help(int argc, char *argv[]) { char buf[81]; /* XXX buffer size? */ int hfd, matched, doindex; char *topic, *subtopic, *t, *s, *d; /* page the help text from our load path */ snprintf(buf, sizeof (buf), "%s/boot/loader.help", getenv("loaddev")); if ((hfd = open(buf, O_RDONLY)) < 0) { printf("Verbose help not available, " "use '?' to list commands\n"); return (CMD_OK); } /* pick up request from arguments */ topic = subtopic = NULL; switch (argc) { case 3: subtopic = strdup(argv[2]); /* FALLTHROUGH */ case 2: topic = strdup(argv[1]); break; case 1: topic = strdup("help"); break; default: command_errmsg = "usage is 'help []"; close(hfd); return (CMD_ERROR); } /* magic "index" keyword */ doindex = strcmp(topic, "index") == 0? 1 : 0; matched = doindex; /* Scan the helpfile looking for help matching the request */ pager_open(); while (help_getnext(hfd, &t, &s, &d)) { if (doindex) { /* dink around formatting */ if (help_emitsummary(t, s, d)) break; } else if (strcmp(topic, t)) { /* topic mismatch */ if (matched) { /* nothing more on this topic, stop scanning */ break; } } else { /* topic matched */ matched = 1; if ((subtopic == NULL && s == NULL) || (subtopic != NULL && s != NULL && strcmp(subtopic, s) == 0)) { /* exact match, print text */ while (fgetstr(buf, 80, hfd) >= 0 && buf[0] != '#') { if (pager_output(buf)) break; if (pager_output("\n")) break; } } else if (subtopic == NULL && s != NULL) { /* topic match, list subtopics */ if (help_emitsummary(t, s, d)) break; } } free(t); free(s); free(d); t = s = d = NULL; } free(t); free(s); free(d); pager_close(); close(hfd); if (!matched) { snprintf(command_errbuf, sizeof (command_errbuf), "no help available for '%s'", topic); free(topic); free(subtopic); return (CMD_ERROR); } free(topic); free(subtopic); return (CMD_OK); } COMMAND_SET(commandlist, "?", "list commands", command_commandlist); static int command_commandlist(int argc __unused, char *argv[] __unused) { struct bootblk_command **cmdp; int res; char name[20]; res = 0; pager_open(); res = pager_output("Available commands:\n"); SET_FOREACH(cmdp, Xcommand_set) { if (res) break; if ((*cmdp)->c_name != NULL && (*cmdp)->c_desc != NULL) { snprintf(name, sizeof (name)," %-15s ", (*cmdp)->c_name); pager_output(name); pager_output((*cmdp)->c_desc); res = pager_output("\n"); } } pager_close(); return (CMD_OK); } /* * XXX set/show should become set/echo if we have variable * substitution happening. */ COMMAND_SET(show, "show", "show variable(s)", command_show); static int command_show(int argc, char *argv[]) { struct env_var *ev; char *cp; if (argc < 2) { /* * With no arguments, print everything. */ pager_open(); for (ev = environ; ev != NULL; ev = ev->ev_next) { pager_output(ev->ev_name); cp = getenv(ev->ev_name); if (cp != NULL) { pager_output("="); pager_output(cp); } if (pager_output("\n")) break; } pager_close(); } else { if ((cp = getenv(argv[1])) != NULL) { printf("%s\n", cp); } else { snprintf(command_errbuf, sizeof (command_errbuf), "variable '%s' not found", argv[1]); return (CMD_ERROR); } } return (CMD_OK); } COMMAND_SET(set, "set", "set a variable", command_set); static int command_set(int argc, char *argv[]) { int err; if (argc != 2) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } else { if ((err = putenv(argv[1])) != 0) { command_errmsg = strerror(err); return (CMD_ERROR); } } return (CMD_OK); } COMMAND_SET(setprop, "setprop", "set a variable", command_setprop); static int command_setprop(int argc, char *argv[]) { int err; if (argc != 3) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } else { if ((err = setenv(argv[1], argv[2], 1)) != 0) { command_errmsg = strerror(err); return (CMD_ERROR); } } return (CMD_OK); } COMMAND_SET(unset, "unset", "unset a variable", command_unset); static int command_unset(int argc, char *argv[]) { int err; if (argc != 2) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } else { if ((err = unsetenv(argv[1])) != 0) { command_errmsg = strerror(err); return (CMD_ERROR); } } return (CMD_OK); } COMMAND_SET(echo, "echo", "echo arguments", command_echo); static int command_echo(int argc, char *argv[]) { char *s; int nl, ch; nl = 0; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "n")) != -1) { switch (ch) { case 'n': nl = 1; break; case '?': default: /* getopt has already reported an error */ return (CMD_OK); } } argv += (optind); argc -= (optind); s = unargv(argc, argv); if (s != NULL) { printf("%s", s); free(s); } if (!nl) printf("\n"); return (CMD_OK); } /* * A passable emulation of the sh(1) command of the same name. */ COMMAND_SET(read, "read", "read input from the terminal", command_read); static int command_read(int argc, char *argv[]) { char *prompt; int timeout; time_t when; char *cp; char *name; char buf[256]; /* XXX size? */ int c; timeout = -1; prompt = NULL; optind = 1; optreset = 1; while ((c = getopt(argc, argv, "p:t:")) != -1) { switch (c) { case 'p': prompt = optarg; break; case 't': timeout = strtol(optarg, &cp, 0); if (cp == optarg) { snprintf(command_errbuf, sizeof (command_errbuf), "bad timeout '%s'", optarg); return (CMD_ERROR); } break; default: return (CMD_OK); } } argv += (optind); argc -= (optind); name = (argc > 0) ? argv[0]: NULL; if (prompt != NULL) printf("%s", prompt); if (timeout >= 0) { when = time(NULL) + timeout; while (!ischar()) if (time(NULL) >= when) return (CMD_OK); /* is timeout an error? */ } ngets(buf, sizeof (buf)); if (name != NULL) setenv(name, buf, 1); return (CMD_OK); } /* * File pager */ COMMAND_SET(more, "more", "show contents of a file", command_more); static int command_more(int argc, char *argv[]) { int i; int res; char line[80]; res = 0; pager_open(); for (i = 1; (i < argc) && (res == 0); i++) { snprintf(line, sizeof (line), "*** FILE %s BEGIN ***\n", argv[i]); if (pager_output(line)) break; res = page_file(argv[i]); if (!res) { snprintf(line, sizeof (line), "*** FILE %s END ***\n", argv[i]); res = pager_output(line); } } pager_close(); if (res == 0) return (CMD_OK); else return (CMD_ERROR); } static int page_file(char *filename) { int result; result = pager_file(filename); if (result == -1) { snprintf(command_errbuf, sizeof (command_errbuf), "error showing %s", filename); } return (result); } /* * List all disk-like devices */ COMMAND_SET(lsdev, "lsdev", "list all devices", command_lsdev); static int command_lsdev(int argc, char *argv[]) { int verbose, ch, i; char line[80]; verbose = 0; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "v")) != -1) { switch (ch) { case 'v': verbose = 1; break; case '?': default: /* getopt has already reported an error */ return (CMD_OK); } } argv += (optind); argc -= (optind); pager_open(); for (i = 0; devsw[i] != NULL; i++) { if (devsw[i]->dv_print != NULL) { if (devsw[i]->dv_print(verbose)) break; } else { snprintf(line, sizeof (line), "%s: (unknown)\n", devsw[i]->dv_name); if (pager_output(line)) break; } } pager_close(); return (CMD_OK); } /* * Copyright (c) 1998 Michael Smith * All rights reserved. * Copyright 2025 Edgecast Cloud LLC. * * 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. * * 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. */ #include #include #include #include "bootstrap.h" /* * Core console support */ static int cons_set(struct env_var *ev, int flags, const void *value); static int cons_find(const char *name); static int cons_check(const char *string); static int cons_change(const char *string, char **); static int twiddle_set(struct env_var *ev, int flags, const void *value); static int last_input = -1; /* input device index */ /* * With multiple active console devices, return index of last input * device, so we can set up os_console variable to denote console * device for kernel. * * Please note, this feature can not really work with UEFI, because * efi console input is returned from any device listed in ConIn, * and we have no way to check which device from ConIn actually was * generating input. */ int cons_inputdev(void) { int cons; int flags = C_PRESENTIN | C_ACTIVEIN; int active = 0; for (cons = 0; consoles[cons] != NULL; cons++) if ((consoles[cons]->c_flags & flags) == flags) active++; /* With just one active console, we will not set os_console */ if (active == 1) return (-1); return (last_input); } /* * Return number of array slots. */ uint_t cons_array_size(void) { uint_t n; if (consoles == NULL) return (0); for (n = 0; consoles[n] != NULL; n++) ; return (n + 1); } struct console * cons_get_console(const char *name) { char port[5]; (void) strlcpy(port, name, sizeof (port)); for (uint_t i = 0; consoles[i] != NULL; i++) { if (strcmp(port, consoles[i]->c_name) == 0) return (consoles[i]); } printf("No such port: %s\n", port); return (NULL); } static void cons_add_dev(struct console *dev) { uint_t c = cons_array_size(); uint_t n = 1; struct console **tmp; if (c == 0) n++; tmp = realloc(consoles, (c + n) * sizeof (struct console *)); if (tmp == NULL) return; if (c > 0) c--; consoles = tmp; consoles[c] = dev; consoles[c + 1] = NULL; } /* * Detect possible console(s) to use. If preferred console(s) have been * specified, mark them as active. Else, mark the first probed console * as active. Also create the console variable. */ void cons_probe(void) { int cons; int active; char *prefconsole, *list, *console; /* Build list of consoles */ consoles = NULL; for (cons = 0;; cons++) { if (ct_list[cons].ct_dev != NULL) { cons_add_dev(ct_list[cons].ct_dev); continue; } if (ct_list[cons].ct_init != NULL) { ct_list[cons].ct_init(); continue; } break; } /* We want a callback to install the new value when this var changes. */ (void) env_setenv("twiddle_divisor", EV_VOLATILE, "16", twiddle_set, env_nounset); /* Do all console probes */ for (cons = 0; consoles[cons] != NULL; cons++) { consoles[cons]->c_flags = 0; consoles[cons]->c_probe(consoles[cons]); } /* Now find the first working one */ active = -1; for (cons = 0; consoles[cons] != NULL; cons++) { if (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT)) { active = cons; break; } } /* Force a console even if all probes failed */ if (active == -1) active = 0; /* Check to see if a console preference has already been registered */ list = NULL; prefconsole = getenv("console"); if (prefconsole != NULL) prefconsole = strdup(prefconsole); if (prefconsole == NULL) prefconsole = strdup(consoles[active]->c_name); /* * unset "console", we need to create one with callbacks. */ unsetenv("console"); cons_change(prefconsole, &list); printf("Consoles:"); bool first = true; for (cons = 0; consoles[cons] != NULL; cons++) { if (consoles[cons]->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) { if (first) first = false; else putchar(','); printf(" %s", consoles[cons]->c_desc); } } printf("\n"); if (list != NULL) console = list; else console = prefconsole; (void) env_setenv("console", EV_VOLATILE, console, cons_set, env_nounset); free(prefconsole); free(list); } void cons_mode(int raw) { int cons; for (cons = 0; consoles[cons] != NULL; cons++) { if (raw == 0) consoles[cons]->c_flags &= ~C_MODERAW; else consoles[cons]->c_flags |= C_MODERAW; } } int getchar(void) { int cons; int flags = C_PRESENTIN | C_ACTIVEIN; int rv; /* * Loop forever polling all active consoles. Somewhat strangely, * this code expects all ->c_in() implementations to effectively do an * ischar() check first, returning -1 if there's not a char ready. */ for (;;) { for (cons = 0; consoles[cons] != NULL; cons++) { if ((consoles[cons]->c_flags & flags) == flags) { rv = consoles[cons]->c_in(consoles[cons]); if (rv != -1) { #ifndef EFI last_input = cons; #endif return (rv); } } } delay(30 * 1000); /* delay 30ms */ } } int ischar(void) { int cons; for (cons = 0; consoles[cons] != NULL; cons++) if ((consoles[cons]->c_flags & (C_PRESENTIN | C_ACTIVEIN)) == (C_PRESENTIN | C_ACTIVEIN) && (consoles[cons]->c_ready(consoles[cons]) != 0)) return (1); return (0); } void putchar(int c) { int cons; /* Expand newlines if not in raw mode */ for (cons = 0; consoles[cons] != NULL; cons++) if ((consoles[cons]->c_flags & (C_PRESENTOUT | C_ACTIVEOUT)) == (C_PRESENTOUT | C_ACTIVEOUT)) { if (c == '\n' && (consoles[cons]->c_flags & C_MODERAW) == 0) consoles[cons]->c_out(consoles[cons], '\r'); consoles[cons]->c_out(consoles[cons], c); } } /* * Find the console with the specified name. */ static int cons_find(const char *name) { int cons; for (cons = 0; consoles[cons] != NULL; cons++) if (strcmp(consoles[cons]->c_name, name) == 0) return (cons); return (-1); } /* * Select one or more consoles. */ static int cons_set(struct env_var *ev, int flags, const void *value) { int ret; char *list; if ((value == NULL) || (cons_check(value) == 0)) { /* * Return CMD_OK instead of CMD_ERROR to prevent forth syntax * error, which would prevent it processing any further * loader.conf entries. */ return (CMD_OK); } list = NULL; ret = cons_change(value, &list); if (ret != CMD_OK) return (ret); /* * set console variable. */ if (list != NULL) { (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, list, NULL, NULL); } else { (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); } free(list); return (ret); } /* * Check that at least one the consoles listed in *string is valid */ static int cons_check(const char *string) { int cons, found, failed; char *curpos, *dup, *next; dup = next = strdup(string); found = failed = 0; while (next != NULL) { curpos = strsep(&next, " ,"); if (*curpos != '\0') { cons = cons_find(curpos); if (cons == -1) { printf("console %s is invalid!\n", curpos); failed++; } else { if ((consoles[cons]->c_flags & (C_PRESENTIN | C_PRESENTOUT)) != (C_PRESENTIN | C_PRESENTOUT)) { failed++; } else found++; } } } free(dup); if (found == 0) printf("no valid consoles!\n"); if (found == 0 || failed != 0) { printf("Available consoles:\n"); for (cons = 0; consoles[cons] != NULL; cons++) { printf(" %s", consoles[cons]->c_name); if (consoles[cons]->c_devinfo != NULL) consoles[cons]->c_devinfo(consoles[cons]); printf("\n"); } } return (found); } /* * Helper function to build string with list of console names. */ static char * cons_add_list(char *list, const char *value) { char *tmp; if (list == NULL) return (strdup(value)); if (asprintf(&tmp, "%s,%s", list, value) > 0) { free(list); list = tmp; } return (list); } /* * Activate all the valid consoles listed in string and disable all others. * Return comma separated string with list of activated console names. */ static int cons_change(const char *string, char **list) { int cons, active, rv; char *curpos, *dup, *next; /* Disable all consoles */ for (cons = 0; consoles[cons] != NULL; cons++) { consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT); } /* Enable selected consoles */ dup = next = strdup(string); active = 0; *list = NULL; rv = CMD_OK; while (next != NULL) { curpos = strsep(&next, " ,"); if (*curpos == '\0') continue; cons = cons_find(curpos); if (cons >= 0) { consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT; consoles[cons]->c_init(consoles[cons], 0); if ((consoles[cons]->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == (C_ACTIVEIN | C_ACTIVEOUT)) { active++; *list = cons_add_list(*list, curpos); continue; } if (active != 0) { /* * If no consoles have initialised we wouldn't * see this. */ printf("console %s failed to initialize\n", consoles[cons]->c_name); } } } free(dup); if (active == 0) { /* * All requested consoles failed to initialise, try to recover. */ for (cons = 0; consoles[cons] != NULL; cons++) { consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT; consoles[cons]->c_init(consoles[cons], 0); if ((consoles[cons]->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == (C_ACTIVEIN | C_ACTIVEOUT)) { active++; *list = cons_add_list(*list, consoles[cons]->c_name); } } if (active == 0) rv = CMD_ERROR; /* Recovery failed. */ } return (rv); } /* * Change the twiddle divisor. * * The user can set the twiddle_divisor variable to directly control how fast * the progress twiddle spins, useful for folks with slow serial consoles. The * code to monitor changes to the variable and propagate them to the twiddle * routines has to live somewhere. Twiddling is console-related so it's here. */ static int twiddle_set(struct env_var *ev, int flags, const void *value) { ulong_t tdiv; char *eptr; tdiv = strtoul(value, &eptr, 0); if (*(const char *)value == 0 || *eptr != 0) { printf("invalid twiddle_divisor '%s'\n", (const char *)value); return (CMD_ERROR); } twiddle_divisor((uint_t)tdiv); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } COMMAND_SET(console, "console", "console info", command_console); static int command_console(int argc, char *argv[]) { if (argc > 1) printf("%s: list info about available consoles\n", argv[0]); printf("Current console: %s\n", getenv("console")); printf("Available consoles:\n"); for (int cons = 0; consoles[cons] != NULL; cons++) { printf(" %s", consoles[cons]->c_name); if (consoles[cons]->c_devinfo != NULL) consoles[cons]->c_devinfo(consoles[cons]); printf("\n"); } return (CMD_OK); } /* * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Gordon W. Ross. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /* * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include /* * This module implements a "raw device" interface suitable for * use by the stand-alone I/O library NFS code. This interface * does not support any "block" access, and exists only for the * purpose of initializing the network interface, getting boot * parameters, and performing the NFS mount. * * At open time, this does: * * find interface - netif_open() * RARP for IP address - rarp_getipaddress() * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...) * RPC/mountd - nfs_mount(sock, ip, path) * * the root file handle from mountd is saved in a global * for use by the NFS open code (NFS/lookup). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dev_net.h" #include "bootstrap.h" #ifdef NETIF_DEBUG int debug = 0; #endif static char *netdev_name; static int netdev_sock = -1; static int netdev_opens; static int net_init(void); static int net_open(struct open_file *, ...); static int net_close(struct open_file *); static void net_cleanup(void); static int net_strategy(void *, int, daddr_t, size_t, char *, size_t *); static int net_print(int); static int net_getparams(int sock); struct devsw netdev = { "net", DEVT_NET, net_init, net_strategy, net_open, net_close, noioctl, net_print, net_cleanup }; static struct uri_scheme { const char *scheme; int proto; } uri_schemes[] = { { "tftp:/", NET_TFTP }, { "nfs:/", NET_NFS }, }; static int net_init(void) { return (0); } /* * Called by devopen after it sets f->f_dev to our devsw entry. * This opens the low-level device and sets dev->d_opendata. * This is declared with variable arguments... */ static int net_open(struct open_file *f, ...) { struct iodesc *d; va_list args; struct devdesc *dev; const char *devname; /* Device part of file name (or NULL). */ int error = 0; va_start(args, f); dev = va_arg(args, struct devdesc *); va_end(args); devname = dev->d_dev->dv_name; /* Before opening another interface, close the previous one first. */ if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0) net_cleanup(); /* On first open, do netif open, mount, etc. */ if (netdev_opens == 0) { /* Find network interface. */ if (netdev_sock < 0) { netdev_sock = netif_open(dev); if (netdev_sock < 0) { printf("%s: netif_open() failed\n", __func__); return (ENXIO); } netdev_name = strdup(devname); #ifdef NETIF_DEBUG if (debug) printf("%s: netif_open() succeeded\n", __func__); #endif } /* * If network params were not set by netif_open(), try to get * them via bootp, rarp, etc. */ if (rootip.s_addr == 0) { /* Get root IP address, and path, etc. */ error = net_getparams(netdev_sock); if (error) { /* getparams makes its own noise */ free(netdev_name); netif_close(netdev_sock); netdev_sock = -1; return (error); } } /* * Set the variables required by the kernel's nfs_diskless * mechanism. This is the minimum set of variables required to * mount a root filesystem without needing to obtain additional * info from bootp or other sources. */ d = socktodesc(netdev_sock); setenv("boot.netif.hwaddr", ether_sprintf(d->myea), 1); setenv("boot.netif.ip", inet_ntoa(myip), 1); setenv("boot.netif.netmask", intoa(netmask), 1); setenv("boot.netif.gateway", inet_ntoa(gateip), 1); setenv("boot.netif.server", inet_ntoa(rootip), 1); if (netproto == NET_TFTP) { setenv("boot.tftproot.server", inet_ntoa(rootip), 1); setenv("boot.tftproot.path", rootpath, 1); } else { setenv("boot.nfsroot.server", inet_ntoa(rootip), 1); setenv("boot.nfsroot.path", rootpath, 1); } if (intf_mtu != 0) { char mtu[16]; snprintf(mtu, sizeof (mtu), "%u", intf_mtu); setenv("boot.netif.mtu", mtu, 1); } } netdev_opens++; dev->d_opendata = &netdev_sock; return (error); } static int net_close(struct open_file *f) { struct devdesc *dev; #ifdef NETIF_DEBUG if (debug) printf("%s: opens=%d\n", __func__, netdev_opens); #endif dev = f->f_devdata; dev->d_opendata = NULL; return (0); } static void net_cleanup(void) { if (netdev_sock >= 0) { #ifdef NETIF_DEBUG if (debug) printf("%s: calling netif_close()\n", __func__); #endif rootip.s_addr = 0; free(netdev_name); netif_close(netdev_sock); netdev_sock = -1; } } static int net_strategy(void *devdata __unused, int rw __unused, daddr_t blk __unused, size_t size __unused, char *buf __unused, size_t *rsize __unused) { return (EIO); } /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP/DHCP way. (RFC951, RFC1048) */ extern n_long ip_convertaddr(char *p); static int net_getparams(int sock) { char buf[MAXHOSTNAMELEN]; n_long rootaddr, smask; /* * Try to get boot info using BOOTP/DHCP. If we succeed, then * the server IP address, gateway, and root path will all * be initialized. If any remain uninitialized, we will * use RARP and RPC/bootparam (the Sun way) to get them. */ bootp(sock); if (myip.s_addr != 0) goto exit; #ifdef NETIF_DEBUG if (debug) printf("%s: BOOTP failed, trying RARP/RPC...\n", __func__); #endif /* * Use RARP to get our IP address. This also sets our * netmask to the "natural" default for our address. */ if (rarp_getipaddress(sock)) { printf("%s: RARP failed\n", __func__); return (EIO); } printf("%s: client addr: %s\n", __func__, inet_ntoa(myip)); /* Get our hostname, server IP address, gateway. */ if (bp_whoami(sock)) { printf("%s: bootparam/whoami RPC failed\n", __func__); return (EIO); } #ifdef NETIF_DEBUG if (debug) printf("%s: client name: %s\n", __func__, hostname); #endif /* * Ignore the gateway from whoami (unreliable). * Use the "gateway" parameter instead. */ smask = 0; gateip.s_addr = 0; if (bp_getfile(sock, "gateway", &gateip, buf) == 0) { /* Got it! Parse the netmask. */ smask = ip_convertaddr(buf); } if (smask) { netmask = smask; #ifdef NETIF_DEBUG if (debug) printf("%s: subnet mask: %s\n", __func__, intoa(netmask)); #endif } #ifdef NETIF_DEBUG if (gateip.s_addr && debug) printf("%s: net gateway: %s\n", __func__, inet_ntoa(gateip)); #endif /* Get the root server and pathname. */ if (bp_getfile(sock, "root", &rootip, rootpath)) { printf("%s: bootparam/getfile RPC failed\n", __func__); return (EIO); } exit: if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) rootip.s_addr = rootaddr; #ifdef NETIF_DEBUG if (debug) { printf("%s: server addr: %s\n", __func__, inet_ntoa(rootip)); printf("%s: server path: %s\n", __func__, rootpath); } #endif return (0); } static int net_print(int verbose) { struct netif_driver *drv; int i, d, cnt; int ret = 0; if (netif_drivers[0] == NULL) return (ret); printf("%s devices:", netdev.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); cnt = 0; for (d = 0; netif_drivers[d]; d++) { drv = netif_drivers[d]; for (i = 0; i < drv->netif_nifs; i++) { printf("\t%s%d:", netdev.dv_name, cnt++); if (verbose) { printf(" (%s%d)", drv->netif_bname, drv->netif_ifs[i].dif_unit); } if ((ret = pager_output("\n")) != 0) return (ret); } } return (ret); } /* * Parses the rootpath if present * * The rootpath format can be in the form * ://IPv4/path * :/path * * For compatibility with previous behaviour it also accepts as an NFS scheme * IPv4:/path * /path * * If an IPv4 address has been specified, it will be stripped out and passed * out as the return value of this function in network byte order. * * If no rootpath is present then we will default to TFTP. * * If no global default scheme has been specified and no scheme has been * specified, we will assume that this is an NFS URL. * * The pathname will be stored in the global variable rootpath. */ uint32_t net_parse_rootpath(void) { n_long addr = htonl(INADDR_NONE); size_t i; char ip[FNAME_SIZE]; char *ptr, *val; netproto = NET_NONE; for (i = 0; i < nitems(uri_schemes); i++) { if (strncmp(rootpath, uri_schemes[i].scheme, strlen(uri_schemes[i].scheme)) != 0) continue; netproto = uri_schemes[i].proto; break; } ptr = rootpath; /* Fallback for compatibility mode */ if (netproto == NET_NONE) { if (strcmp(rootpath, "/") == 0) { netproto = NET_TFTP; } else { netproto = NET_NFS; (void) strsep(&ptr, ":"); if (ptr != NULL) { addr = inet_addr(rootpath); bcopy(ptr, rootpath, strlen(ptr) + 1); } } } else { ptr += strlen(uri_schemes[i].scheme); if (*ptr == '/') { /* * We are in the form ://, we do expect an ip. */ ptr++; /* * XXX when http will be there we will need to check for * a port, but right now we do not need it yet. * Also will need rework for IPv6. */ val = strchr(ptr, '/'); if (val == NULL) { /* If no pathname component, default to / */ strlcat(rootpath, "/", sizeof (rootpath)); val = strchr(ptr, '/'); } if (val != NULL) { snprintf(ip, sizeof (ip), "%.*s", (int)((uintptr_t)val - (uintptr_t)ptr), ptr); addr = inet_addr(ip); if (addr == htonl(INADDR_NONE)) { printf("Bad IP address: %s\n", ip); } bcopy(val, rootpath, strlen(val) + 1); } } else { ptr--; bcopy(ptr, rootpath, strlen(ptr) + 1); } } return (addr); } /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _BOOT_DEV_NET_H_ #define _BOOT_DEV_NET_H_ extern struct devsw netdev; uint32_t net_parse_rootpath(void); #endif /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include #include #include #include "bootstrap.h" int devopen(struct open_file *f, const char *fname, const char **file) { struct devdesc *dev; int result; result = archsw.arch_getdev((void **)&dev, fname, file); if (result) return (result); /* point to device-specific data so that device open can use it */ f->f_dev = dev->d_dev; f->f_devdata = dev; result = dev->d_dev->dv_open(f, dev); if (result != 0) { f->f_devdata = NULL; f->f_dev = NULL; free(dev); } return (result); } int devclose(struct open_file *f) { free(f->f_devdata); return (0); } /* * Copyright (c) 1998 Michael Smith * Copyright (c) 2012 Andrey V. Elsukov * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include "disk.h" #ifdef DISK_DEBUG #define DPRINTF(fmt, args...) printf("%s: " fmt "\n", __func__, ## args) #else #define DPRINTF(fmt, args...) ((void)0) #endif struct open_disk { struct ptable *table; uint64_t mediasize; uint64_t entrysize; uint_t sectorsize; }; struct print_args { struct disk_devdesc *dev; const char *prefix; int verbose; }; /* Convert size to a human-readable number. */ static char * display_size(uint64_t size, uint_t sectorsize) { static char buf[80]; char unit; size = size * sectorsize / 1024; unit = 'K'; if (size >= 10485760000LL) { size /= 1073741824; unit = 'T'; } else if (size >= 10240000) { size /= 1048576; unit = 'G'; } else if (size >= 10000) { size /= 1024; unit = 'M'; } snprintf(buf, sizeof (buf), "%4" PRIu64 "%cB", size, unit); return (buf); } static int ptblread(void *d, void *buf, size_t blocks, uint64_t offset) { struct disk_devdesc *dev; struct open_disk *od; dev = (struct disk_devdesc *)d; od = (struct open_disk *)dev->dd.d_opendata; /* * The strategy function assumes the offset is in units of 512 byte * sectors. For larger sector sizes, we need to adjust the offset to * match the actual sector size. */ offset *= (od->sectorsize / 512); /* * As the GPT backup partition is located at the end of the disk, * to avoid reading past disk end, flag bcache not to use RA. */ return (dev->dd.d_dev->dv_strategy(dev, F_READ | F_NORA, offset, blocks * od->sectorsize, (char *)buf, NULL)); } static int ptable_print(void *arg, const char *pname, const struct ptable_entry *part) { struct disk_devdesc dev; struct print_args *pa, bsd; struct open_disk *od; struct ptable *table; char line[80]; int res; uint_t sectsize; uint64_t partsize; pa = (struct print_args *)arg; od = (struct open_disk *)pa->dev->dd.d_opendata; sectsize = od->sectorsize; partsize = part->end - part->start + 1; snprintf(line, sizeof (line), " %s%s: %s", pa->prefix, pname, parttype2str(part->type)); if (pager_output(line)) return (1); if (pa->verbose) { /* Emit extra tab when the line is shorter than 3 tab stops */ if (strlen(line) < 24) (void) pager_output("\t"); snprintf(line, sizeof (line), "\t%s", display_size(partsize, sectsize)); if (pager_output(line)) return (1); } if (pager_output("\n")) return (1); res = 0; if (part->type == PART_FREEBSD || part->type == PART_SOLARIS2) { /* Open slice with BSD or VTOC label */ dev.dd.d_dev = pa->dev->dd.d_dev; dev.dd.d_unit = pa->dev->dd.d_unit; dev.d_slice = part->index; dev.d_partition = D_PARTNONE; if (disk_open(&dev, partsize, sectsize) == 0) { table = ptable_open(&dev, partsize, sectsize, ptblread); if (table != NULL) { snprintf(line, sizeof (line), " %s%s", pa->prefix, pname); bsd.dev = &dev; bsd.prefix = line; bsd.verbose = pa->verbose; res = ptable_iterate(table, &bsd, ptable_print); ptable_close(table); } disk_close(&dev); } } return (res); } int disk_print(struct disk_devdesc *dev, char *prefix, int verbose) { struct open_disk *od; struct print_args pa; /* Disk should be opened */ od = (struct open_disk *)dev->dd.d_opendata; pa.dev = dev; pa.prefix = prefix; pa.verbose = verbose; return (ptable_iterate(od->table, &pa, ptable_print)); } int disk_read(struct disk_devdesc *dev, void *buf, uint64_t offset, uint_t blocks) { struct open_disk *od; int ret; od = (struct open_disk *)dev->dd.d_opendata; ret = dev->dd.d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset, blocks * od->sectorsize, buf, NULL); return (ret); } int disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, uint_t blocks) { struct open_disk *od; int ret; od = (struct open_disk *)dev->dd.d_opendata; ret = dev->dd.d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset, blocks * od->sectorsize, buf, NULL); return (ret); } int disk_ioctl(struct disk_devdesc *dev, unsigned long cmd, void *data) { struct open_disk *od = dev->dd.d_opendata; if (od == NULL) return (ENOTTY); switch (cmd) { case DIOCGSECTORSIZE: *(uint_t *)data = od->sectorsize; break; case DIOCGMEDIASIZE: if (dev->d_offset == 0) *(uint64_t *)data = od->mediasize; else *(uint64_t *)data = od->entrysize * od->sectorsize; break; default: return (ENOTTY); } return (0); } int disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize) { struct disk_devdesc partdev; struct open_disk *od; struct ptable *table; struct ptable_entry part; int rc, slice, partition; if (sectorsize == 0) { DPRINTF("unknown sector size"); return (ENXIO); } rc = 0; od = (struct open_disk *)malloc(sizeof (struct open_disk)); if (od == NULL) { DPRINTF("no memory"); return (ENOMEM); } dev->dd.d_opendata = od; od->entrysize = 0; od->mediasize = mediasize; od->sectorsize = sectorsize; /* * While we are reading disk metadata, make sure we do it relative * to the start of the disk */ memcpy(&partdev, dev, sizeof(partdev)); partdev.d_offset = 0; partdev.d_slice = D_SLICENONE; partdev.d_partition = D_PARTNONE; dev->d_offset = 0; table = NULL; slice = dev->d_slice; partition = dev->d_partition; DPRINTF("%s unit %d, slice %d, partition %d => %p", disk_fmtdev(dev), dev->dd.d_unit, dev->d_slice, dev->d_partition, od); /* Determine disk layout. */ od->table = ptable_open(&partdev, mediasize / sectorsize, sectorsize, ptblread); if (od->table == NULL) { DPRINTF("Can't read partition table"); rc = ENXIO; goto out; } if (ptable_getsize(od->table, &mediasize) != 0) { rc = ENXIO; goto out; } od->mediasize = mediasize; if ((ptable_gettype(od->table) == PTABLE_BSD || ptable_gettype(od->table) == PTABLE_VTOC) && partition >= 0) { /* It doesn't matter what value has d_slice */ rc = ptable_getpart(od->table, &part, partition); if (rc == 0) { dev->d_offset = part.start; od->entrysize = part.end - part.start + 1; } } else if (ptable_gettype(od->table) == PTABLE_ISO9660) { dev->d_offset = 0; od->entrysize = mediasize; } else if (slice >= 0) { /* Try to get information about partition */ if (slice == 0) rc = ptable_getbestpart(od->table, &part); else rc = ptable_getpart(od->table, &part, slice); if (rc != 0) /* Partition doesn't exist */ goto out; dev->d_offset = part.start; od->entrysize = part.end - part.start + 1; slice = part.index; if (ptable_gettype(od->table) == PTABLE_GPT) { partition = D_PARTISGPT; goto out; /* Nothing more to do */ } else if (partition == D_PARTISGPT) { /* * When we try to open GPT partition, but partition * table isn't GPT, reset partition value to * D_PARTWILD and try to autodetect appropriate value. */ partition = D_PARTWILD; } /* * If partition is D_PARTNONE, then disk_open() was called * to open raw MBR slice. */ if (partition == D_PARTNONE) goto out; /* * If partition is D_PARTWILD and we are looking at a * BSD/VTOC slice, then try to read label, otherwise return * the whole MBR slice. */ if (partition == D_PARTWILD) { switch (part.type) { case PART_FREEBSD: case PART_SOLARIS2: break; default: goto out; } } /* Try to read label */ table = ptable_open(dev, part.end - part.start + 1, od->sectorsize, ptblread); if (table == NULL) { DPRINTF("Can't read BSD/VTOC label"); rc = ENXIO; goto out; } /* * If slice contains BSD/VTOC label and partition < 0, then * assume the 'a' partition. Otherwise just return the * whole MBR slice, because it can contain ZFS. */ if (partition < 0) { if (ptable_gettype(table) != PTABLE_BSD && ptable_gettype(table) != PTABLE_VTOC) goto out; partition = 0; } rc = ptable_getpart(table, &part, partition); if (rc != 0) goto out; dev->d_offset += part.start; od->entrysize = part.end - part.start + 1; } out: if (table != NULL) ptable_close(table); if (rc != 0) { if (od->table != NULL) ptable_close(od->table); free(od); DPRINTF("%s could not open", disk_fmtdev(dev)); } else { /* Save the slice and partition number to the dev */ dev->d_slice = slice; dev->d_partition = partition; DPRINTF("%s offset %" PRIu64 " => %p", disk_fmtdev(dev), dev->d_offset, od); } return (rc); } int disk_close(struct disk_devdesc *dev) { struct open_disk *od; od = (struct open_disk *)dev->dd.d_opendata; DPRINTF("%s closed => %p", disk_fmtdev(dev), od); ptable_close(od->table); free(od); return (0); } char * disk_fmtdev(struct disk_devdesc *dev) { static char buf[128]; char *cp; cp = buf + sprintf(buf, "%s%d", dev->dd.d_dev->dv_name, dev->dd.d_unit); if (dev->d_slice > D_SLICENONE) { #ifdef LOADER_GPT_SUPPORT if (dev->d_partition == D_PARTISGPT) { sprintf(cp, "p%d:", dev->d_slice); return (buf); } else #endif #ifdef LOADER_MBR_SUPPORT cp += sprintf(cp, "s%d", dev->d_slice); #endif } if (dev->d_partition > D_PARTNONE) cp += sprintf(cp, "%c", dev->d_partition + 'a'); strcat(cp, ":"); return (buf); } int disk_parsedev(struct disk_devdesc *dev, const char *devspec, const char **path) { int unit, slice, partition; const char *np; char *cp; np = devspec; unit = -1; /* * If there is path/file info after the device info, then any missing * slice or partition info should be considered a request to search for * an appropriate partition. Otherwise we want to open the raw device * itself and not try to fill in missing info by searching. */ if ((cp = strchr(np, ':')) != NULL && cp[1] != '\0') { slice = D_SLICEWILD; partition = D_PARTWILD; } else { slice = D_SLICENONE; partition = D_PARTNONE; } if (*np != '\0' && *np != ':') { unit = strtol(np, &cp, 10); if (cp == np) return (EUNIT); #ifdef LOADER_GPT_SUPPORT if (*cp == 'p') { np = cp + 1; slice = strtol(np, &cp, 10); if (np == cp) return (ESLICE); /* we don't support nested partitions on GPT */ if (*cp != '\0' && *cp != ':') return (EINVAL); partition = D_PARTISGPT; } else #endif #ifdef LOADER_MBR_SUPPORT if (*cp == 's') { np = cp + 1; slice = strtol(np, &cp, 10); if (np == cp) return (ESLICE); } #endif if (*cp != '\0' && *cp != ':') { partition = *cp - 'a'; if (partition < 0) return (EPART); cp++; } } else return (EINVAL); if (*cp != '\0' && *cp != ':') return (EINVAL); dev->dd.d_unit = unit; dev->d_slice = slice; dev->d_partition = partition; if (path != NULL) *path = (*cp == '\0') ? cp: cp + 1; return (0); } /* * Copyright (c) 2011 Google, Inc. * All rights reserved. * * 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. * * 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. */ /* * Device descriptor for partitioned disks. To use, set the * d_slice and d_partition variables as follows: * * Whole disk access: * * d_slice = D_SLICENONE * d_partition = * * Whole MBR slice: * * d_slice = MBR slice number (typically 1..4) * d_partition = D_PARTNONE * * VTOC disklabel partition within an MBR slice: * * d_slice = MBR slice number (typically 1..4) * d_partition = disklabel partition (typically 0..19 or D_PARTWILD) * * BSD disklabel partition within an MBR slice: * * d_slice = MBR slice number (typically 1..4) * d_partition = disklabel partition (typically 0..19 or D_PARTWILD) * * BSD disklabel partition on the true dedicated disk: * * d_slice = D_SLICENONE * d_partition = disklabel partition (typically 0..19 or D_PARTWILD) * * GPT partition: * * d_slice = GPT partition number (typically 1..N) * d_partition = D_PARTISGPT * * For MBR, setting d_partition to D_PARTWILD will automatically use the first * partition within the slice. * * For both MBR and GPT, to automatically find the 'best' slice and partition, * set d_slice to D_SLICEWILD. This uses the partition type to decide which * partition to use according to the following list of preferences: * * Solaris2 (active) * Solaris2 (inactive) * Linux (active) * Linux (inactive) * DOS/Windows (active) * DOS/Windows (inactive) * * Active MBR slices (marked as bootable) are preferred over inactive. GPT * doesn't have the concept of active/inactive partitions. In both MBR and GPT, * if there are multiple slices/partitions of a given type, the first one * is chosen. * * The low-level disk device will typically call disk_open() from its open * method to interpret the disk partition tables according to the rules above. * This will initialize d_offset to the block offset of the start of the * selected partition - this offset should be added to the offset passed to * the device's strategy method. */ #ifndef _DISK_H #define _DISK_H #define D_SLICENONE -1 #define D_SLICEWILD 0 #define D_PARTNONE -1 #define D_PARTWILD -2 #define D_PARTISGPT 255 struct disk_devdesc { struct devdesc dd; /* Must be first. */ int d_slice; int d_partition; uint64_t d_offset; }; enum disk_ioctl { IOCTL_GET_BLOCKS, IOCTL_GET_BLOCK_SIZE }; /* * Parse disk metadata and initialise dev->d_offset. */ extern int disk_open(struct disk_devdesc *, uint64_t, u_int); extern int disk_close(struct disk_devdesc *); extern int disk_ioctl(struct disk_devdesc *, u_long, void *); extern int disk_read(struct disk_devdesc *, void *, uint64_t, u_int); extern int disk_write(struct disk_devdesc *, void *, uint64_t, u_int); /* * Print information about slices on a disk. */ extern int disk_print(struct disk_devdesc *, char *, int); extern char* disk_fmtdev(struct disk_devdesc *); extern int disk_parsedev(struct disk_devdesc *, const char *, const char **); #endif /* _DISK_H */ /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2016 Toomas Soome * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. * Copyright 2020 RackTop Systems, Inc. */ /* * The workhorse here is gfxfb_blt(). It is implemented to mimic UEFI * GOP Blt, and allows us to fill the rectangle on screen, copy * rectangle from video to buffer and buffer to video and video to video. * Such implementation does allow us to have almost identical implementation * for both BIOS VBE and UEFI. * * ALL pixel data is assumed to be 32-bit BGRA (byte order Blue, Green, Red, * Alpha) format, this allows us to only handle RGB data and not to worry * about mixing RGB with indexed colors. * Data exchange between memory buffer and video will translate BGRA * and native format as following: * * 32-bit to/from 32-bit is trivial case. * 32-bit to/from 24-bit is also simple - we just drop the alpha channel. * 32-bit to/from 16-bit is more complicated, because we nee to handle * data loss from 32-bit to 16-bit. While reading/writing from/to video, we * need to apply masks of 16-bit color components. This will preserve * colors for terminal text. For 32-bit truecolor PMG images, we need to * translate 32-bit colors to 15/16 bit colors and this means data loss. * There are different algorithms how to perform such color space reduction, * we are currently using bitwise right shift to reduce color space and so far * this technique seems to be sufficient (see also gfx_fb_putimage(), the * end of for loop). * 32-bit to/from 8-bit is the most troublesome because 8-bit colors are * indexed. From video, we do get color indexes, and we do translate * color index values to RGB. To write to video, we again need to translate * RGB to color index. Additionally, we need to translate between VGA and * Sun colors. * * Our internal color data is represented using BGRA format. But the hardware * used indexed colors for 8-bit colors (0-255) and for this mode we do * need to perform translation to/from BGRA and index values. * * - paletteentry RGB <-> index - * BGRA BUFFER <----/ \ - VIDEO * \ / * - RGB (16/24/32) - * * To perform index to RGB translation, we use palette table generated * from when we set up 8-bit mode video. We cannot read palette data from * the hardware, because not all hardware supports reading it. * * BGRA to index is implemented in rgb_to_color_index() by searching * palette array for closest match of RBG values. * * Note: In 8-bit mode, We do store first 16 colors to palette registers * in VGA color order, this serves two purposes; firstly, * if palette update is not supported, we still have correct 16 colors. * Secondly, the kernel does get correct 16 colors when some other boot * loader is used. However, the palette map for 8-bit colors is using * Sun color ordering - this does allow us to skip translation * from VGA colors to Sun colors, while we are reading RGB data. */ #include #include #include #if defined(EFI) #include #include #include #else #include #include #endif #include #include #include #include #include #include #include #include #include #include #include /* VGA text mode does use bold font. */ #if !defined(VGA_8X16_FONT) #define VGA_8X16_FONT "/boot/fonts/8x16b.fnt" #endif #if !defined(DEFAULT_8X16_FONT) #define DEFAULT_8X16_FONT "/boot/fonts/8x16.fnt" #endif /* * Global framebuffer struct, to be updated with mode changes. */ multiboot_tag_framebuffer_t gfx_fb; /* To support setenv, keep track of inverses and colors. */ static int gfx_inverse = 0; static int gfx_inverse_screen = 0; static uint8_t gfx_fg = DEFAULT_ANSI_FOREGROUND; static uint8_t gfx_bg = DEFAULT_ANSI_BACKGROUND; #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *shadow_fb; static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GlyphBuffer; #else struct paletteentry *shadow_fb; static struct paletteentry *GlyphBuffer; #endif static size_t GlyphBufferSize; int gfx_fb_cons_clear(struct vis_consclear *); void gfx_fb_cons_copy(struct vis_conscopy *); void gfx_fb_cons_display(struct vis_consdisplay *); static bool insert_font(char *, FONT_FLAGS); /* * Set default operations to use bitmap based implementation. * In case of UEFI, if GOP is available, we will switch to GOP based * implementation. * * Also note, for UEFI we do attempt to boost the execution by setting * Task Priority Level (TPL) to TPL_NOTIFY, which is highest priority * usable in application. */ /* * Translate platform specific FB address. */ static uint8_t * gfx_get_fb_address(void) { return ((uint8_t *)ptov(gfx_fb.framebuffer_common.framebuffer_addr)); } /* * Generic platform callbacks for tem. */ void plat_tem_get_prom_font_size(int *charheight, int *windowtop) { *charheight = 0; *windowtop = 0; } void plat_tem_get_colors(uint8_t *fg, uint8_t *bg) { *fg = gfx_fg; *bg = gfx_bg; } void plat_tem_get_inverses(int *inverse, int *inverse_screen) { *inverse = gfx_inverse; *inverse_screen = gfx_inverse_screen; } /* * Utility function to parse gfx mode line strings. */ bool gfx_parse_mode_str(char *str, int *x, int *y, int *depth) { char *p, *end; errno = 0; p = str; *x = strtoul(p, &end, 0); if (*x == 0 || errno != 0) return (false); if (*end != 'x') return (false); p = end + 1; *y = strtoul(p, &end, 0); if (*y == 0 || errno != 0) return (false); if (*end != 'x') { *depth = -1; /* auto select */ } else { p = end + 1; *depth = strtoul(p, &end, 0); if (*depth == 0 || errno != 0 || *end != '\0') return (false); } return (true); } uint32_t gfx_fb_color_map(uint8_t index) { return (rgb_color_map(&rgb_info, index, 0xff)); } static bool color_name_to_ansi(const char *name, int *val) { if (strcasecmp(name, "black") == 0) { *val = ANSI_COLOR_BLACK; return (true); } if (strcasecmp(name, "red") == 0) { *val = ANSI_COLOR_RED; return (true); } if (strcasecmp(name, "green") == 0) { *val = ANSI_COLOR_GREEN; return (true); } if (strcasecmp(name, "yellow") == 0) { *val = ANSI_COLOR_YELLOW; return (true); } if (strcasecmp(name, "blue") == 0) { *val = ANSI_COLOR_BLUE; return (true); } if (strcasecmp(name, "magenta") == 0) { *val = ANSI_COLOR_MAGENTA; return (true); } if (strcasecmp(name, "cyan") == 0) { *val = ANSI_COLOR_CYAN; return (true); } if (strcasecmp(name, "white") == 0) { *val = ANSI_COLOR_WHITE; return (true); } return (false); } /* Callback to check and set colors */ static int gfx_set_colors(struct env_var *ev, int flags, const void *value) { int val = 0, limit; char buf[2]; const void *evalue; if (value == NULL) return (CMD_OK); limit = 255; if (color_name_to_ansi(value, &val)) { snprintf(buf, sizeof (buf), "%d", val); evalue = buf; } else { char *end; errno = 0; val = (int)strtol(value, &end, 0); if (errno != 0 || *end != '\0') { printf("Allowed values are either ansi color name or " "number from range [0-255].\n"); return (CMD_OK); } evalue = value; } /* invalid value? */ if ((val < 0 || val > limit)) { printf("Allowed values are either ansi color name or " "number from range [0-255].\n"); return (CMD_OK); } if (strcmp(ev->ev_name, "tem.fg_color") == 0) { /* is it already set? */ if (gfx_fg == val) return (CMD_OK); gfx_fg = val; } if (strcmp(ev->ev_name, "tem.bg_color") == 0) { /* is it already set? */ if (gfx_bg == val) return (CMD_OK); gfx_bg = val; } env_setenv(ev->ev_name, flags | EV_NOHOOK, evalue, NULL, NULL); plat_cons_update_mode(-1); return (CMD_OK); } /* Callback to check and set inverses */ static int gfx_set_inverses(struct env_var *ev, int flags, const void *value) { int t, f; if (value == NULL) return (CMD_OK); t = strcmp(value, "true"); f = strcmp(value, "false"); /* invalid value? */ if (t != 0 && f != 0) return (CMD_OK); if (strcmp(ev->ev_name, "tem.inverse") == 0) { /* is it already set? */ if (gfx_inverse == (t == 0)) return (CMD_OK); gfx_inverse = (t == 0); } if (strcmp(ev->ev_name, "tem.inverse-screen") == 0) { /* is it already set? */ if (gfx_inverse_screen == (t == 0)) return (CMD_OK); gfx_inverse_screen = (t == 0); } env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); plat_cons_update_mode(-1); return (CMD_OK); } /* * Initialize gfx framework. */ void gfx_framework_init(void) { int rc, limit; char *env, buf[2]; if (gfx_fb.framebuffer_common.framebuffer_bpp < 24) limit = 7; else limit = 255; /* set up tem inverse controls */ env = getenv("tem.inverse"); if (env != NULL) { if (strcmp(env, "true") == 0) gfx_inverse = 1; unsetenv("tem.inverse"); } env = getenv("tem.inverse-screen"); if (env != NULL) { if (strcmp(env, "true") == 0) gfx_inverse_screen = 1; unsetenv("tem.inverse-screen"); } if (gfx_inverse) env = "true"; else env = "false"; env_setenv("tem.inverse", EV_VOLATILE, env, gfx_set_inverses, env_nounset); if (gfx_inverse_screen) env = "true"; else env = "false"; env_setenv("tem.inverse-screen", EV_VOLATILE, env, gfx_set_inverses, env_nounset); /* set up tem color controls */ env = getenv("tem.fg_color"); if (env != NULL) { rc = (int)strtol(env, NULL, 0); if ((rc >= 0 && rc <= limit) && (rc <= 7 || rc >= 16)) gfx_fg = rc; unsetenv("tem.fg_color"); } env = getenv("tem.bg_color"); if (env != NULL) { rc = (int)strtol(env, NULL, 0); if ((rc >= 0 && rc <= limit) && (rc <= 7 || rc >= 16)) gfx_bg = rc; unsetenv("tem.bg_color"); } snprintf(buf, sizeof (buf), "%d", gfx_fg); env_setenv("tem.fg_color", EV_VOLATILE, buf, gfx_set_colors, env_nounset); snprintf(buf, sizeof (buf), "%d", gfx_bg); env_setenv("tem.bg_color", EV_VOLATILE, buf, gfx_set_colors, env_nounset); /* * Setup font list to have builtin font. */ (void) insert_font(NULL, FONT_BUILTIN); } /* * Get indexed color from RGB. This function is used to write data to video * memory when the adapter is set to use indexed colors. * Since UEFI does only support 32-bit colors, we do not implement it for * UEFI because there is no need for it and we do not have palette array * for UEFI. */ static uint8_t rgb_to_color_index(uint8_t r, uint8_t g, uint8_t b) { #if !defined(EFI) uint32_t color, best, dist, k; int diff; color = 0; best = 255 * 255 * 255; for (k = 0; k < NCMAP; k++) { diff = r - pe8[k].Red; dist = diff * diff; diff = g - pe8[k].Green; dist += diff * diff; diff = b - pe8[k].Blue; dist += diff * diff; /* Exact match, exit the loop */ if (dist == 0) break; if (dist < best) { color = k; best = dist; } } if (k == NCMAP) k = color; return (k); #else (void) r; (void) g; (void) b; return (0); #endif } static void gfx_mem_wr1(uint8_t *base, size_t size, uint32_t o, uint8_t v) { if (o >= size) return; *(uint8_t *)(base + o) = v; } static void gfx_mem_wr2(uint8_t *base, size_t size, uint32_t o, uint16_t v) { if (o >= size) return; *(uint16_t *)(base + o) = v; } static void gfx_mem_wr4(uint8_t *base, size_t size, uint32_t o, uint32_t v) { if (o >= size) return; *(uint32_t *)(base + o) = v; } static int gfxfb_blt_fill(void *BltBuffer, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p; #else struct paletteentry *p; #endif uint32_t data, bpp, pitch, y, x; size_t size; off_t off; uint8_t *destination; if (BltBuffer == NULL) return (EINVAL); if (DestinationY + Height > gfx_fb.framebuffer_common.framebuffer_height) return (EINVAL); if (DestinationX + Width > gfx_fb.framebuffer_common.framebuffer_width) return (EINVAL); if (Width == 0 || Height == 0) return (EINVAL); p = BltBuffer; if (gfx_fb.framebuffer_common.framebuffer_bpp == 8) { data = rgb_to_color_index(p->Red, p->Green, p->Blue); } else { data = (p->Red & ((1 << gfx_fb.u.fb2.framebuffer_red_mask_size) - 1)) << gfx_fb.u.fb2.framebuffer_red_field_position; data |= (p->Green & ((1 << gfx_fb.u.fb2.framebuffer_green_mask_size) - 1)) << gfx_fb.u.fb2.framebuffer_green_field_position; data |= (p->Blue & ((1 << gfx_fb.u.fb2.framebuffer_blue_mask_size) - 1)) << gfx_fb.u.fb2.framebuffer_blue_field_position; } bpp = roundup2(gfx_fb.framebuffer_common.framebuffer_bpp, 8) >> 3; pitch = gfx_fb.framebuffer_common.framebuffer_pitch; destination = gfx_get_fb_address(); size = gfx_fb.framebuffer_common.framebuffer_height * pitch; for (y = DestinationY; y < Height + DestinationY; y++) { off = y * pitch + DestinationX * bpp; for (x = 0; x < Width; x++) { switch (bpp) { case 1: gfx_mem_wr1(destination, size, off, (data < NCOLORS) ? solaris_color_to_pc_color[data] : data); break; case 2: gfx_mem_wr2(destination, size, off, data); break; case 3: gfx_mem_wr1(destination, size, off, (data >> 16) & 0xff); gfx_mem_wr1(destination, size, off + 1, (data >> 8) & 0xff); gfx_mem_wr1(destination, size, off + 2, data & 0xff); break; case 4: gfx_mem_wr4(destination, size, off, data); break; default: return (EINVAL); } off += bpp; } } return (0); } static int gfxfb_blt_video_to_buffer(void *BltBuffer, uint32_t SourceX, uint32_t SourceY, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height, uint32_t Delta) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p; #else struct paletteentry *p; #endif uint32_t x, sy, dy; uint32_t bpp, pitch, copybytes; off_t off; uint8_t *source, *destination, *sb; uint8_t rm, rp, gm, gp, bm, bp; bool bgra; if (BltBuffer == NULL) return (EINVAL); if (SourceY + Height > gfx_fb.framebuffer_common.framebuffer_height) return (EINVAL); if (SourceX + Width > gfx_fb.framebuffer_common.framebuffer_width) return (EINVAL); if (Width == 0 || Height == 0) return (EINVAL); if (Delta == 0) Delta = Width * sizeof (*p); bpp = roundup2(gfx_fb.framebuffer_common.framebuffer_bpp, 8) >> 3; pitch = gfx_fb.framebuffer_common.framebuffer_pitch; copybytes = Width * bpp; rm = (1 << gfx_fb.u.fb2.framebuffer_red_mask_size) - 1; rp = gfx_fb.u.fb2.framebuffer_red_field_position; gm = (1 << gfx_fb.u.fb2.framebuffer_green_mask_size) - 1; gp = gfx_fb.u.fb2.framebuffer_green_field_position; bm = (1 << gfx_fb.u.fb2.framebuffer_blue_mask_size) - 1; bp = gfx_fb.u.fb2.framebuffer_blue_field_position; /* If FB pixel format is BGRA, we can use direct copy. */ bgra = bpp == 4 && gfx_fb.u.fb2.framebuffer_red_mask_size == 8 && gfx_fb.u.fb2.framebuffer_red_field_position == 16 && gfx_fb.u.fb2.framebuffer_green_mask_size == 8 && gfx_fb.u.fb2.framebuffer_green_field_position == 8 && gfx_fb.u.fb2.framebuffer_blue_mask_size == 8 && gfx_fb.u.fb2.framebuffer_blue_field_position == 0; for (sy = SourceY, dy = DestinationY; dy < Height + DestinationY; sy++, dy++) { off = sy * pitch + SourceX * bpp; source = gfx_get_fb_address() + off; destination = (uint8_t *)BltBuffer + dy * Delta + DestinationX * sizeof (*p); if (bgra) { bcopy(source, destination, copybytes); } else { for (x = 0; x < Width; x++) { uint32_t c = 0; p = (void *)(destination + x * sizeof (*p)); sb = source + x * bpp; switch (bpp) { case 1: c = *sb; break; case 2: c = *(uint16_t *)sb; break; case 3: c = sb[0] << 16 | sb[1] << 8 | sb[2]; break; case 4: c = *(uint32_t *)sb; break; default: return (EINVAL); } if (bpp == 1) { *(uint32_t *)p = gfx_fb_color_map( (c < NCOLORS) ? pc_color_to_solaris_color[c] : c); } else { p->Red = (c >> rp) & rm; p->Green = (c >> gp) & gm; p->Blue = (c >> bp) & bm; p->Reserved = 0; } } } } return (0); } static int gfxfb_blt_buffer_to_video(void *BltBuffer, uint32_t SourceX, uint32_t SourceY, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height, uint32_t Delta) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p; #else struct paletteentry *p; #endif uint32_t x, sy, dy; uint32_t bpp, pitch, copybytes; off_t off; uint8_t *source, *destination; uint8_t rm, rp, gm, gp, bm, bp; bool bgra; if (BltBuffer == NULL) return (EINVAL); if (DestinationY + Height > gfx_fb.framebuffer_common.framebuffer_height) return (EINVAL); if (DestinationX + Width > gfx_fb.framebuffer_common.framebuffer_width) return (EINVAL); if (Width == 0 || Height == 0) return (EINVAL); if (Delta == 0) Delta = Width * sizeof (*p); bpp = roundup2(gfx_fb.framebuffer_common.framebuffer_bpp, 8) >> 3; pitch = gfx_fb.framebuffer_common.framebuffer_pitch; copybytes = Width * bpp; rm = (1 << gfx_fb.u.fb2.framebuffer_red_mask_size) - 1; rp = gfx_fb.u.fb2.framebuffer_red_field_position; gm = (1 << gfx_fb.u.fb2.framebuffer_green_mask_size) - 1; gp = gfx_fb.u.fb2.framebuffer_green_field_position; bm = (1 << gfx_fb.u.fb2.framebuffer_blue_mask_size) - 1; bp = gfx_fb.u.fb2.framebuffer_blue_field_position; /* If FB pixel format is BGRA, we can use direct copy. */ bgra = bpp == 4 && gfx_fb.u.fb2.framebuffer_red_mask_size == 8 && gfx_fb.u.fb2.framebuffer_red_field_position == 16 && gfx_fb.u.fb2.framebuffer_green_mask_size == 8 && gfx_fb.u.fb2.framebuffer_green_field_position == 8 && gfx_fb.u.fb2.framebuffer_blue_mask_size == 8 && gfx_fb.u.fb2.framebuffer_blue_field_position == 0; for (sy = SourceY, dy = DestinationY; sy < Height + SourceY; sy++, dy++) { off = dy * pitch + DestinationX * bpp; destination = gfx_get_fb_address() + off; if (bgra) { source = (uint8_t *)BltBuffer + sy * Delta + SourceX * sizeof (*p); bcopy(source, destination, copybytes); } else { for (x = 0; x < Width; x++) { uint32_t c; p = (void *)((uint8_t *)BltBuffer + sy * Delta + (SourceX + x) * sizeof (*p)); if (bpp == 1) { c = rgb_to_color_index(p->Red, p->Green, p->Blue); } else { c = (p->Red & rm) << rp | (p->Green & gm) << gp | (p->Blue & bm) << bp; } off = x * bpp; switch (bpp) { case 1: gfx_mem_wr1(destination, copybytes, off, (c < NCOLORS) ? solaris_color_to_pc_color[c] : c); break; case 2: gfx_mem_wr2(destination, copybytes, off, c); break; case 3: gfx_mem_wr1(destination, copybytes, off, (c >> 16) & 0xff); gfx_mem_wr1(destination, copybytes, off + 1, (c >> 8) & 0xff); gfx_mem_wr1(destination, copybytes, off + 2, c & 0xff); break; case 4: gfx_mem_wr4(destination, copybytes, off, c); break; default: return (EINVAL); } } } } return (0); } static int gfxfb_blt_video_to_video(uint32_t SourceX, uint32_t SourceY, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height) { uint32_t bpp, copybytes; int pitch; uint8_t *source, *destination; off_t off; if (SourceY + Height > gfx_fb.framebuffer_common.framebuffer_height) return (EINVAL); if (SourceX + Width > gfx_fb.framebuffer_common.framebuffer_width) return (EINVAL); if (DestinationY + Height > gfx_fb.framebuffer_common.framebuffer_height) return (EINVAL); if (DestinationX + Width > gfx_fb.framebuffer_common.framebuffer_width) return (EINVAL); if (Width == 0 || Height == 0) return (EINVAL); bpp = roundup2(gfx_fb.framebuffer_common.framebuffer_bpp, 8) >> 3; pitch = gfx_fb.framebuffer_common.framebuffer_pitch; copybytes = Width * bpp; off = SourceY * pitch + SourceX * bpp; source = gfx_get_fb_address() + off; off = DestinationY * pitch + DestinationX * bpp; destination = gfx_get_fb_address() + off; /* * To handle overlapping areas, set up reverse copy here. */ if ((uintptr_t)destination > (uintptr_t)source) { source += Height * pitch; destination += Height * pitch; pitch = -pitch; } while (Height-- > 0) { bcopy(source, destination, copybytes); source += pitch; destination += pitch; } return (0); } static void gfxfb_shadow_fill(uint32_t *BltBuffer, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height) { uint32_t fbX, fbY; if (shadow_fb == NULL) return; fbX = gfx_fb.framebuffer_common.framebuffer_width; fbY = gfx_fb.framebuffer_common.framebuffer_height; if (BltBuffer == NULL) return; if (DestinationX + Width > fbX) Width = fbX - DestinationX; if (DestinationY + Height > fbY) Height = fbY - DestinationY; uint32_t y2 = Height + DestinationY; for (uint32_t y1 = DestinationY; y1 < y2; y1++) { uint32_t off = y1 * fbX + DestinationX; for (uint32_t x = 0; x < Width; x++) { *(uint32_t *)&shadow_fb[off + x] = *BltBuffer; } } } int gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation, uint32_t SourceX, uint32_t SourceY, uint32_t DestinationX, uint32_t DestinationY, uint32_t Width, uint32_t Height, uint32_t Delta) { int rv; #if defined(EFI) EFI_STATUS status; EFI_TPL tpl; extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; /* * We assume Blt() does work, if not, we will need to build * exception list case by case. * Once boot services are off, we can not use GOP Blt(). */ if (gop != NULL && has_boot_services) { tpl = BS->RaiseTPL(TPL_NOTIFY); switch (BltOperation) { case GfxFbBltVideoFill: gfxfb_shadow_fill(BltBuffer, DestinationX, DestinationY, Width, Height); status = gop->Blt(gop, BltBuffer, EfiBltVideoFill, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; case GfxFbBltVideoToBltBuffer: status = gop->Blt(gop, BltBuffer, EfiBltVideoToBltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; case GfxFbBltBufferToVideo: status = gop->Blt(gop, BltBuffer, EfiBltBufferToVideo, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; case GfxFbBltVideoToVideo: status = gop->Blt(gop, BltBuffer, EfiBltVideoToVideo, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; default: status = EFI_INVALID_PARAMETER; break; } switch (status) { case EFI_SUCCESS: rv = 0; break; case EFI_INVALID_PARAMETER: rv = EINVAL; break; case EFI_DEVICE_ERROR: default: rv = EIO; break; } BS->RestoreTPL(tpl); return (rv); } #endif switch (BltOperation) { case GfxFbBltVideoFill: gfxfb_shadow_fill(BltBuffer, DestinationX, DestinationY, Width, Height); rv = gfxfb_blt_fill(BltBuffer, DestinationX, DestinationY, Width, Height); break; case GfxFbBltVideoToBltBuffer: rv = gfxfb_blt_video_to_buffer(BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; case GfxFbBltBufferToVideo: rv = gfxfb_blt_buffer_to_video(BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); break; case GfxFbBltVideoToVideo: rv = gfxfb_blt_video_to_video(SourceX, SourceY, DestinationX, DestinationY, Width, Height); break; default: rv = EINVAL; break; } return (rv); } /* * visual io callbacks. */ int gfx_fb_cons_clear(struct vis_consclear *ca) { int rv; uint32_t width, height; width = gfx_fb.framebuffer_common.framebuffer_width; height = gfx_fb.framebuffer_common.framebuffer_height; rv = gfxfb_blt(&ca->bg_color, GfxFbBltVideoFill, 0, 0, 0, 0, width, height, 0); return (rv); } void gfx_fb_cons_copy(struct vis_conscopy *ma) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *source, *destination; #else struct paletteentry *source, *destination; #endif uint32_t width, height, bytes; uint32_t sx, sy, dx, dy; uint32_t pitch; int step; width = ma->e_col - ma->s_col + 1; height = ma->e_row - ma->s_row + 1; sx = ma->s_col; sy = ma->s_row; dx = ma->t_col; dy = ma->t_row; if (sx + width > gfx_fb.framebuffer_common.framebuffer_width) width = gfx_fb.framebuffer_common.framebuffer_width - sx; if (sy + height > gfx_fb.framebuffer_common.framebuffer_height) height = gfx_fb.framebuffer_common.framebuffer_height - sy; if (dx + width > gfx_fb.framebuffer_common.framebuffer_width) width = gfx_fb.framebuffer_common.framebuffer_width - dx; if (dy + height > gfx_fb.framebuffer_common.framebuffer_height) height = gfx_fb.framebuffer_common.framebuffer_height - dy; if (width == 0 || height == 0) return; /* * With no shadow fb, use video to video copy. */ if (shadow_fb == NULL) { (void) gfxfb_blt(NULL, GfxFbBltVideoToVideo, sx, sy, dx, dy, width, height, 0); return; } /* * With shadow fb, we need to copy data on both shadow and video, * to preserve the consistency. We only read data from shadow fb. */ step = 1; pitch = gfx_fb.framebuffer_common.framebuffer_width; bytes = width * sizeof (*shadow_fb); /* * To handle overlapping areas, set up reverse copy here. */ if (dy * pitch + dx > sy * pitch + sx) { sy += height; dy += height; step = -step; } while (height-- > 0) { source = &shadow_fb[sy * pitch + sx]; destination = &shadow_fb[dy * pitch + dx]; bcopy(source, destination, bytes); (void) gfxfb_blt(destination, GfxFbBltBufferToVideo, 0, 0, dx, dy, width, 1, 0); sy += step; dy += step; } } /* * Implements alpha blending for RGBA data, could use pixels for arguments, * but byte stream seems more generic. * The generic alpha blending is: * blend = alpha * fg + (1.0 - alpha) * bg. * Since our alpha is not from range [0..1], we scale appropriately. */ static uint8_t alpha_blend(uint8_t fg, uint8_t bg, uint8_t alpha) { uint16_t blend, h, l; uint8_t max_alpha; /* 15/16 bit depths have alpha channel size less than 8 */ max_alpha = (1 << (rgb_info.red.size + rgb_info.green.size + rgb_info.blue.size) / 3) - 1; /* trivial corner cases */ if (alpha == 0) return (bg); if (alpha >= max_alpha) return (fg); blend = (alpha * fg + (max_alpha - alpha) * bg); /* Division by max_alpha */ h = blend >> 8; l = blend & max_alpha; if (h + l >= max_alpha) h++; return (h); } /* Copy memory to framebuffer or to memory. */ static void bitmap_cpy(void *dst, void *src, size_t size) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ps, *pd; #else struct paletteentry *ps, *pd; #endif uint32_t i; uint8_t a; ps = src; pd = dst; for (i = 0; i < size; i++) { a = ps[i].Reserved; pd[i].Red = alpha_blend(ps[i].Red, pd[i].Red, a); pd[i].Green = alpha_blend(ps[i].Green, pd[i].Green, a); pd[i].Blue = alpha_blend(ps[i].Blue, pd[i].Blue, a); pd[i].Reserved = a; } } static void * allocate_glyphbuffer(uint32_t width, uint32_t height) { size_t size; size = sizeof (*GlyphBuffer) * width * height; if (size != GlyphBufferSize) { free(GlyphBuffer); GlyphBuffer = malloc(size); if (GlyphBuffer == NULL) return (NULL); GlyphBufferSize = size; } return (GlyphBuffer); } void gfx_fb_cons_display(struct vis_consdisplay *da) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, *data; #else struct paletteentry *BltBuffer, *data; #endif uint32_t size; /* make sure we will not write past FB */ if ((uint32_t)da->col >= gfx_fb.framebuffer_common.framebuffer_width || (uint32_t)da->row >= gfx_fb.framebuffer_common.framebuffer_height || (uint32_t)da->col + da->width > gfx_fb.framebuffer_common.framebuffer_width || (uint32_t)da->row + da->height > gfx_fb.framebuffer_common.framebuffer_height) return; /* * If we do have shadow fb, we will use shadow to render data, * and copy shadow to video. */ if (shadow_fb != NULL) { uint32_t pitch = gfx_fb.framebuffer_common.framebuffer_width; uint32_t dx, dy, width, height; dx = da->col; dy = da->row; height = da->height; width = da->width; data = (void *)da->data; /* Copy rectangle line by line. */ for (uint32_t y = 0; y < height; y++) { BltBuffer = shadow_fb + dy * pitch + dx; bitmap_cpy(BltBuffer, &data[y * width], width); (void) gfxfb_blt(BltBuffer, GfxFbBltBufferToVideo, 0, 0, dx, dy, width, 1, 0); dy++; } return; } /* * Common data to display is glyph, use preallocated * glyph buffer. */ if (tems.ts_pix_data_size != GlyphBufferSize) (void) allocate_glyphbuffer(da->width, da->height); size = sizeof (*BltBuffer) * da->width * da->height; if (size == GlyphBufferSize) { BltBuffer = GlyphBuffer; } else { BltBuffer = malloc(size); } if (BltBuffer == NULL) return; if (gfxfb_blt(BltBuffer, GfxFbBltVideoToBltBuffer, da->col, da->row, 0, 0, da->width, da->height, 0) == 0) { bitmap_cpy(BltBuffer, da->data, da->width * da->height); (void) gfxfb_blt(BltBuffer, GfxFbBltBufferToVideo, 0, 0, da->col, da->row, da->width, da->height, 0); } if (BltBuffer != GlyphBuffer) free(BltBuffer); } static void gfx_fb_cursor_impl(void *buf, uint32_t stride, uint32_t fg, uint32_t bg, struct vis_conscursor *ca) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p; #else struct paletteentry *p; #endif union pixel { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL p; #else struct paletteentry p; #endif uint32_t p32; } *row; p = buf; /* * Build inverse image of the glyph. * Since xor has self-inverse property, drawing cursor * second time on the same spot, will restore the original content. */ for (screen_size_t i = 0; i < ca->height; i++) { row = (union pixel *)(p + i * stride); for (screen_size_t j = 0; j < ca->width; j++) { row[j].p32 = (row[j].p32 ^ fg) ^ bg; } } } void gfx_fb_display_cursor(struct vis_conscursor *ca) { union pixel { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL p; #else struct paletteentry p; #endif uint32_t p32; } fg, bg; bcopy(&ca->fg_color, &fg.p32, sizeof (fg.p32)); bcopy(&ca->bg_color, &bg.p32, sizeof (bg.p32)); if (shadow_fb == NULL && allocate_glyphbuffer(ca->width, ca->height) != NULL) { if (gfxfb_blt(GlyphBuffer, GfxFbBltVideoToBltBuffer, ca->col, ca->row, 0, 0, ca->width, ca->height, 0) == 0) gfx_fb_cursor_impl(GlyphBuffer, ca->width, fg.p32, bg.p32, ca); (void) gfxfb_blt(GlyphBuffer, GfxFbBltBufferToVideo, 0, 0, ca->col, ca->row, ca->width, ca->height, 0); return; } uint32_t pitch = gfx_fb.framebuffer_common.framebuffer_width; uint32_t dx, dy, width, height; dx = ca->col; dy = ca->row; width = ca->width; height = ca->height; gfx_fb_cursor_impl(shadow_fb + dy * pitch + dx, pitch, fg.p32, bg.p32, ca); /* Copy rectangle line by line. */ for (uint32_t y = 0; y < height; y++) { (void) gfxfb_blt(shadow_fb + dy * pitch + dx, GfxFbBltBufferToVideo, 0, 0, dx, dy, width, 1, 0); dy++; } } /* * Public graphics primitives. */ static int isqrt(int num) { int res = 0; int bit = 1 << 30; /* "bit" starts at the highest power of four <= the argument. */ while (bit > num) bit >>= 2; while (bit != 0) { if (num >= res + bit) { num -= res + bit; res = (res >> 1) + bit; } else res >>= 1; bit >>= 2; } return (res); } /* set pixel in framebuffer using gfx coordinates */ void gfx_fb_setpixel(uint32_t x, uint32_t y) { text_color_t fg, bg; if (plat_stdout_is_framebuffer() == 0) return; tem_get_colors((tem_vt_state_t)tems.ts_active, &fg, &bg); if (x >= gfx_fb.framebuffer_common.framebuffer_width || y >= gfx_fb.framebuffer_common.framebuffer_height) return; gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x, y, 1, 1, 0); } /* * draw rectangle in framebuffer using gfx coordinates. */ void gfx_fb_drawrect(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t fill) { text_color_t fg, bg; if (plat_stdout_is_framebuffer() == 0) return; tem_get_colors((tem_vt_state_t)tems.ts_active, &fg, &bg); if (fill != 0) { gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x1, y1, x2 - x1, y2 - y1, 0); } else { gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x1, y1, x2 - x1, 1, 0); gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x1, y2, x2 - x1, 1, 0); gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x1, y1, 1, y2 - y1, 0); gfxfb_blt(&fg.n, GfxFbBltVideoFill, 0, 0, x2, y1, 1, y2 - y1, 0); } } void gfx_fb_line(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t wd) { int dx, sx, dy, sy; int err, e2, x2, y2, ed, width; if (plat_stdout_is_framebuffer() == 0) return; width = wd; sx = x0 < x1? 1 : -1; sy = y0 < y1? 1 : -1; dx = x1 > x0? x1 - x0 : x0 - x1; dy = y1 > y0? y1 - y0 : y0 - y1; err = dx + dy; ed = dx + dy == 0 ? 1: isqrt(dx * dx + dy * dy); for (;;) { gfx_fb_setpixel(x0, y0); e2 = err; x2 = x0; if ((e2 << 1) >= -dx) { /* x step */ e2 += dy; y2 = y0; while (e2 < ed * width && (y1 != (uint32_t)y2 || dx > dy)) { y2 += sy; gfx_fb_setpixel(x0, y2); e2 += dx; } if (x0 == x1) break; e2 = err; err -= dy; x0 += sx; } if ((e2 << 1) <= dy) { /* y step */ e2 = dx-e2; while (e2 < ed * width && (x1 != (uint32_t)x2 || dx < dy)) { x2 += sx; gfx_fb_setpixel(x2, y0); e2 += dy; } if (y0 == y1) break; err += dx; y0 += sy; } } } /* * quadratic Bézier curve limited to gradients without sign change. */ void gfx_fb_bezier(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t wd) { int sx, sy, xx, yy, xy, width; int dx, dy, err, curvature; int i; if (plat_stdout_is_framebuffer() == 0) return; width = wd; sx = x2 - x1; sy = y2 - y1; xx = x0 - x1; yy = y0 - y1; curvature = xx*sy - yy*sx; if (sx*sx + sy*sy > xx*xx+yy*yy) { x2 = x0; x0 = sx + x1; y2 = y0; y0 = sy + y1; curvature = -curvature; } if (curvature != 0) { xx += sx; sx = x0 < x2? 1 : -1; xx *= sx; yy += sy; sy = y0 < y2? 1 : -1; yy *= sy; xy = (xx*yy) << 1; xx *= xx; yy *= yy; if (curvature * sx * sy < 0) { xx = -xx; yy = -yy; xy = -xy; curvature = -curvature; } dx = 4 * sy * curvature * (x1 - x0) + xx - xy; dy = 4 * sx * curvature * (y0 - y1) + yy - xy; xx += xx; yy += yy; err = dx + dy + xy; do { for (i = 0; i <= width; i++) gfx_fb_setpixel(x0 + i, y0); if (x0 == x2 && y0 == y2) return; /* last pixel -> curve finished */ y1 = 2 * err < dx; if (2 * err > dy) { x0 += sx; dx -= xy; dy += yy; err += dy; } if (y1 != 0) { y0 += sy; dy -= xy; dx += xx; err += dx; } } while (dy < dx); /* gradient negates -> algorithm fails */ } gfx_fb_line(x0, y0, x2, y2, width); } /* * draw rectangle using terminal coordinates and current foreground color. */ void gfx_term_drawrect(uint32_t ux1, uint32_t uy1, uint32_t ux2, uint32_t uy2) { int x1, y1, x2, y2; int xshift, yshift; int width, i; uint32_t vf_width, vf_height; if (plat_stdout_is_framebuffer() == 0) return; vf_width = tems.ts_font.vf_width; vf_height = tems.ts_font.vf_height; width = vf_width / 4; /* line width */ xshift = (vf_width - width) / 2; yshift = (vf_height - width) / 2; /* Shift coordinates */ if (ux1 != 0) ux1--; if (uy1 != 0) uy1--; ux2--; uy2--; /* mark area used in tem */ tem_image_display(tems.ts_active, uy1, ux1, uy2 + 1, ux2 + 1); /* * Draw horizontal lines width points thick, shifted from outer edge. */ x1 = (ux1 + 1) * vf_width + tems.ts_p_offset.x; y1 = uy1 * vf_height + tems.ts_p_offset.y + yshift; x2 = ux2 * vf_width + tems.ts_p_offset.x; gfx_fb_drawrect(x1, y1, x2, y1 + width, 1); y2 = uy2 * vf_height + tems.ts_p_offset.y; y2 += vf_height - yshift - width; gfx_fb_drawrect(x1, y2, x2, y2 + width, 1); /* * Draw vertical lines width points thick, shifted from outer edge. */ x1 = ux1 * vf_width + tems.ts_p_offset.x + xshift; y1 = uy1 * vf_height + tems.ts_p_offset.y; y1 += vf_height; y2 = uy2 * vf_height + tems.ts_p_offset.y; gfx_fb_drawrect(x1, y1, x1 + width, y2, 1); x1 = ux2 * vf_width + tems.ts_p_offset.x; x1 += vf_width - xshift - width; gfx_fb_drawrect(x1, y1, x1 + width, y2, 1); /* Draw upper left corner. */ x1 = ux1 * vf_width + tems.ts_p_offset.x + xshift; y1 = uy1 * vf_height + tems.ts_p_offset.y; y1 += vf_height; x2 = ux1 * vf_width + tems.ts_p_offset.x; x2 += vf_width; y2 = uy1 * vf_height + tems.ts_p_offset.y + yshift; for (i = 0; i <= width; i++) gfx_fb_bezier(x1 + i, y1, x1 + i, y2 + i, x2, y2 + i, width-i); /* Draw lower left corner. */ x1 = ux1 * vf_width + tems.ts_p_offset.x; x1 += vf_width; y1 = uy2 * vf_height + tems.ts_p_offset.y; y1 += vf_height - yshift; x2 = ux1 * vf_width + tems.ts_p_offset.x + xshift; y2 = uy2 * vf_height + tems.ts_p_offset.y; for (i = 0; i <= width; i++) gfx_fb_bezier(x1, y1 - i, x2 + i, y1 - i, x2 + i, y2, width-i); /* Draw upper right corner. */ x1 = ux2 * vf_width + tems.ts_p_offset.x; y1 = uy1 * vf_height + tems.ts_p_offset.y + yshift; x2 = ux2 * vf_width + tems.ts_p_offset.x; x2 += vf_width - xshift - width; y2 = uy1 * vf_height + tems.ts_p_offset.y; y2 += vf_height; for (i = 0; i <= width; i++) gfx_fb_bezier(x1, y1 + i, x2 + i, y1 + i, x2 + i, y2, width-i); /* Draw lower right corner. */ x1 = ux2 * vf_width + tems.ts_p_offset.x; y1 = uy2 * vf_height + tems.ts_p_offset.y; y1 += vf_height - yshift; x2 = ux2 * vf_width + tems.ts_p_offset.x; x2 += vf_width - xshift - width; y2 = uy2 * vf_height + tems.ts_p_offset.y; for (i = 0; i <= width; i++) gfx_fb_bezier(x1, y1 - i, x2 + i, y1 - i, x2 + i, y2, width-i); } int gfx_fb_putimage(png_t *png, uint32_t ux1, uint32_t uy1, uint32_t ux2, uint32_t uy2, uint32_t flags) { #if defined(EFI) EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p; #else struct paletteentry *p; #endif struct vis_consdisplay da; uint32_t i, j, x, y, fheight, fwidth; uint8_t r, g, b, a; bool scale = false; bool trace = false; trace = (flags & FL_PUTIMAGE_DEBUG) != 0; if (plat_stdout_is_framebuffer() == 0) { if (trace) printf("Framebuffer not active.\n"); return (1); } if (png->color_type != PNG_TRUECOLOR_ALPHA) { if (trace) printf("Not truecolor image.\n"); return (1); } if (ux1 > gfx_fb.framebuffer_common.framebuffer_width || uy1 > gfx_fb.framebuffer_common.framebuffer_height) { if (trace) printf("Top left coordinate off screen.\n"); return (1); } if (png->width > UINT16_MAX || png->height > UINT16_MAX) { if (trace) printf("Image too large.\n"); return (1); } if (png->width < 1 || png->height < 1) { if (trace) printf("Image too small.\n"); return (1); } /* * If 0 was passed for either ux2 or uy2, then calculate the missing * part of the bottom right coordinate. */ scale = true; if (ux2 == 0 && uy2 == 0) { /* Both 0, use the native resolution of the image */ ux2 = ux1 + png->width; uy2 = uy1 + png->height; scale = false; } else if (ux2 == 0) { /* Set ux2 from uy2/uy1 to maintain aspect ratio */ ux2 = ux1 + (png->width * (uy2 - uy1)) / png->height; } else if (uy2 == 0) { /* Set uy2 from ux2/ux1 to maintain aspect ratio */ uy2 = uy1 + (png->height * (ux2 - ux1)) / png->width; } if (ux2 > gfx_fb.framebuffer_common.framebuffer_width || uy2 > gfx_fb.framebuffer_common.framebuffer_height) { if (trace) printf("Bottom right coordinate off screen.\n"); return (1); } fwidth = ux2 - ux1; fheight = uy2 - uy1; /* * If the original image dimensions have been passed explicitly, * disable scaling. */ if (fwidth == png->width && fheight == png->height) scale = false; if (ux1 == 0) { /* * No top left X co-ordinate (real coordinates start at 1), * place as far right as it will fit. */ ux2 = gfx_fb.framebuffer_common.framebuffer_width - tems.ts_p_offset.x; ux1 = ux2 - fwidth; } if (uy1 == 0) { /* * No top left Y co-ordinate (real coordinates start at 1), * place as far down as it will fit. */ uy2 = gfx_fb.framebuffer_common.framebuffer_height - tems.ts_p_offset.y; uy1 = uy2 - fheight; } if (ux1 >= ux2 || uy1 >= uy2) { if (trace) printf("Image dimensions reversed.\n"); return (1); } if (fwidth < 2 || fheight < 2) { if (trace) printf("Target area too small\n"); return (1); } if (trace) printf("Image %ux%u -> %ux%u @%ux%u\n", png->width, png->height, fwidth, fheight, ux1, uy1); da.col = ux1; da.row = uy1; da.width = fwidth; da.height = fheight; /* * mark area used in tem */ if (!(flags & FL_PUTIMAGE_NOSCROLL)) { tem_image_display(tems.ts_active, da.row / tems.ts_font.vf_height, da.col / tems.ts_font.vf_width, (da.row + da.height) / tems.ts_font.vf_height, (da.col + da.width) / tems.ts_font.vf_width); } if ((flags & FL_PUTIMAGE_BORDER)) gfx_fb_drawrect(ux1, uy1, ux2, uy2, 0); da.data = malloc(fwidth * fheight * sizeof (*p)); p = (void *)da.data; if (da.data == NULL) { if (trace) printf("Out of memory.\n"); return (1); } /* * Build image for our framebuffer. */ /* Helper to calculate the pixel index from the source png */ #define GETPIXEL(xx, yy) (((yy) * png->width + (xx)) * png->bpp) /* * For each of the x and y directions, calculate the number of pixels * in the source image that correspond to a single pixel in the target. * Use fixed-point arithmetic with 16-bits for each of the integer and * fractional parts. */ const uint32_t wcstep = ((png->width - 1) << 16) / (fwidth - 1); const uint32_t hcstep = ((png->height - 1) << 16) / (fheight - 1); uint32_t hc = 0; for (y = 0; y < fheight; y++) { uint32_t hc2 = (hc >> 9) & 0x7f; uint32_t hc1 = 0x80 - hc2; uint32_t offset_y = hc >> 16; uint32_t offset_y1 = offset_y + 1; uint32_t wc = 0; for (x = 0; x < fwidth; x++) { uint32_t wc2 = (wc >> 9) & 0x7f; uint32_t wc1 = 0x80 - wc2; uint32_t offset_x = wc >> 16; uint32_t offset_x1 = offset_x + 1; /* Target pixel index */ j = y * fwidth + x; if (!scale) { i = GETPIXEL(x, y); r = png->image[i]; g = png->image[i + 1]; b = png->image[i + 2]; a = png->image[i + 3]; } else { uint8_t pixel[4]; uint32_t p00 = GETPIXEL(offset_x, offset_y); uint32_t p01 = GETPIXEL(offset_x, offset_y1); uint32_t p10 = GETPIXEL(offset_x1, offset_y); uint32_t p11 = GETPIXEL(offset_x1, offset_y1); /* * Given a 2x2 array of pixels in the source * image, combine them to produce a single * value for the pixel in the target image. * Each column of pixels is combined using * a weighted average where the top and bottom * pixels contribute hc1 and hc2 respectively. * The calculation for bottom pixel pB and * top pixel pT is: * (pT * hc1 + pB * hc2) / (hc1 + hc2) * Once the values are determined for the two * columns of pixels, then the columns are * averaged together in the same way but using * wc1 and wc2 for the weightings. * * Since hc1 and hc2 are chosen so that * hc1 + hc2 == 128 (and same for wc1 + wc2), * the >> 14 below is a quick way to divide by * (hc1 + hc2) * (wc1 + wc2) */ for (i = 0; i < 4; i++) pixel[i] = ( (png->image[p00 + i] * hc1 + png->image[p01 + i] * hc2) * wc1 + (png->image[p10 + i] * hc1 + png->image[p11 + i] * hc2) * wc2) >> 14; r = pixel[0]; g = pixel[1]; b = pixel[2]; a = pixel[3]; } if (trace) printf("r/g/b: %x/%x/%x\n", r, g, b); /* * Rough colorspace reduction for 15/16 bit colors. */ p[j].Red = r >> (8 - gfx_fb.u.fb2.framebuffer_red_mask_size); p[j].Green = g >> (8 - gfx_fb.u.fb2.framebuffer_green_mask_size); p[j].Blue = b >> (8 - gfx_fb.u.fb2.framebuffer_blue_mask_size); p[j].Reserved = a; wc += wcstep; } hc += hcstep; } gfx_fb_cons_display(&da); free(da.data); return (0); } /* Return w^2 + h^2 or 0, if the dimensions are unknown */ static unsigned edid_diagonal_squared(void) { unsigned w, h; if (edid_info == NULL) return (0); w = edid_info->display.max_horizontal_image_size; h = edid_info->display.max_vertical_image_size; /* If either one is 0, we have aspect ratio, not size */ if (w == 0 || h == 0) return (0); /* * some monitors encode the aspect ratio instead of the physical size. */ if ((w == 16 && h == 9) || (w == 16 && h == 10) || (w == 4 && h == 3) || (w == 5 && h == 4)) return (0); /* * translate cm to inch, note we scale by 100 here. */ w = w * 100 / 254; h = h * 100 / 254; /* Return w^2 + h^2 */ return (w * w + h * h); } /* * calculate pixels per inch. */ static unsigned gfx_get_ppi(void) { unsigned dp, di; di = edid_diagonal_squared(); if (di == 0) return (0); dp = gfx_fb.framebuffer_common.framebuffer_width * gfx_fb.framebuffer_common.framebuffer_width + gfx_fb.framebuffer_common.framebuffer_height * gfx_fb.framebuffer_common.framebuffer_height; return (isqrt(dp / di)); } /* * Calculate font size from density independent pixels (dp): * ((16dp * ppi) / 160) * display_factor. * Here we are using fixed constants: 1dp == 160 ppi and * display_factor 2. * * We are rounding font size up and are searching for font which is * not smaller than calculated size value. */ bitmap_data_t * gfx_get_font(short rows, short cols, short height, short width) { unsigned ppi, size; bitmap_data_t *font = NULL; struct fontlist *fl, *next; /* Text mode is not supported here. */ if (gfx_fb.framebuffer_common.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT) return (NULL); ppi = gfx_get_ppi(); if (ppi == 0) return (NULL); /* * We will search for 16dp font. * We are using scale up by 10 for roundup. */ size = (16 * ppi * 10) / 160; /* Apply display factor 2. */ size = roundup(size * 2, 10) / 10; STAILQ_FOREACH(fl, &fonts, font_next) { /* * Skip too large fonts. */ font = fl->font_data; if (height / font->height < rows || width / font->width < cols) continue; next = STAILQ_NEXT(fl, font_next); /* * If this is last font or, if next font is smaller, * we have our font. Make sure, it actually is loaded. */ if (next == NULL || next->font_data->height < size) { if (font->font == NULL || fl->font_flags == FONT_RELOAD) { if (fl->font_load != NULL && fl->font_name != NULL) font = fl->font_load(fl->font_name); } break; } font = NULL; } return (font); } static int load_mapping(int fd, struct font *fp, int n) { size_t i, size; ssize_t rv; struct font_map *mp; if (fp->vf_map_count[n] == 0) return (0); size = fp->vf_map_count[n] * sizeof (*mp); mp = malloc(size); if (mp == NULL) return (ENOMEM); fp->vf_map[n] = mp; rv = read(fd, mp, size); if (rv < 0 || (size_t)rv != size) { free(fp->vf_map[n]); fp->vf_map[n] = NULL; return (EIO); } for (i = 0; i < fp->vf_map_count[n]; i++) { mp[i].font_src = be32toh(mp[i].font_src); mp[i].font_dst = be16toh(mp[i].font_dst); mp[i].font_len = be16toh(mp[i].font_len); } return (0); } static int builtin_mapping(struct font *fp, int n) { size_t size; struct font_map *mp; if (n >= VFNT_MAPS) return (EINVAL); if (fp->vf_map_count[n] == 0) return (0); size = fp->vf_map_count[n] * sizeof (*mp); mp = malloc(size); if (mp == NULL) return (ENOMEM); fp->vf_map[n] = mp; memcpy(mp, DEFAULT_FONT_DATA.font->vf_map[n], size); return (0); } /* * Load font from builtin or from file. * We do need special case for builtin because the builtin font glyphs * are compressed and we do need to uncompress them. * Having single load_font() for both cases will help us to simplify * font switch handling. */ static bitmap_data_t * load_font(char *path) { int fd, i; uint32_t glyphs; struct font_header fh; struct fontlist *fl; bitmap_data_t *bp; struct font *fp; size_t size; ssize_t rv; /* Get our entry from the font list. */ STAILQ_FOREACH(fl, &fonts, font_next) { if (strcmp(fl->font_name, path) == 0) break; } if (fl == NULL) return (NULL); /* Should not happen. */ bp = fl->font_data; if (bp->font != NULL && fl->font_flags != FONT_RELOAD) return (bp); fd = -1; /* * Special case for builtin font. * Builtin font is the very first font we load, we do not have * previous loads to be released. */ if (fl->font_flags == FONT_BUILTIN) { if ((fp = calloc(1, sizeof (struct font))) == NULL) return (NULL); fp->vf_width = DEFAULT_FONT_DATA.width; fp->vf_height = DEFAULT_FONT_DATA.height; fp->vf_bytes = malloc(DEFAULT_FONT_DATA.uncompressed_size); if (fp->vf_bytes == NULL) { free(fp); return (NULL); } bp->uncompressed_size = DEFAULT_FONT_DATA.uncompressed_size; bp->compressed_size = DEFAULT_FONT_DATA.compressed_size; if (lz4_decompress(DEFAULT_FONT_DATA.compressed_data, fp->vf_bytes, DEFAULT_FONT_DATA.compressed_size, DEFAULT_FONT_DATA.uncompressed_size, 0) != 0) { free(fp->vf_bytes); free(fp); return (NULL); } for (i = 0; i < VFNT_MAPS; i++) { fp->vf_map_count[i] = DEFAULT_FONT_DATA.font->vf_map_count[i]; if (builtin_mapping(fp, i) != 0) goto free_done; } bp->font = fp; return (bp); } fd = open(path, O_RDONLY); if (fd < 0) { return (NULL); } size = sizeof (fh); rv = read(fd, &fh, size); if (rv < 0 || (size_t)rv != size) { bp = NULL; goto done; } if (memcmp(fh.fh_magic, FONT_HEADER_MAGIC, sizeof (fh.fh_magic)) != 0) { bp = NULL; goto done; } if ((fp = calloc(1, sizeof (struct font))) == NULL) { bp = NULL; goto done; } for (i = 0; i < VFNT_MAPS; i++) fp->vf_map_count[i] = be32toh(fh.fh_map_count[i]); glyphs = be32toh(fh.fh_glyph_count); fp->vf_width = fh.fh_width; fp->vf_height = fh.fh_height; size = howmany(fp->vf_width, 8) * fp->vf_height * glyphs; bp->uncompressed_size = size; if ((fp->vf_bytes = malloc(size)) == NULL) goto free_done; rv = read(fd, fp->vf_bytes, size); if (rv < 0 || (size_t)rv != size) goto free_done; for (i = 0; i < VFNT_MAPS; i++) { if (load_mapping(fd, fp, i) != 0) goto free_done; } /* * Reset builtin flag now as we have full font loaded. */ if (fl->font_flags == FONT_BUILTIN) fl->font_flags = FONT_AUTO; /* * Release previously loaded entries. We can do this now, as * the new font is loaded. Note, there can be no console * output till the new font is in place and tem is notified. * We do need to keep fl->font_data for glyph dimensions. */ STAILQ_FOREACH(fl, &fonts, font_next) { if (fl->font_data->font == NULL) continue; for (i = 0; i < VFNT_MAPS; i++) free(fl->font_data->font->vf_map[i]); free(fl->font_data->font->vf_bytes); free(fl->font_data->font); fl->font_data->font = NULL; } bp->font = fp; bp->compressed_size = 0; done: if (fd != -1) close(fd); return (bp); free_done: for (i = 0; i < VFNT_MAPS; i++) free(fp->vf_map[i]); free(fp->vf_bytes); free(fp); bp = NULL; goto done; } struct name_entry { char *n_name; SLIST_ENTRY(name_entry) n_entry; }; SLIST_HEAD(name_list, name_entry); /* Read font names from index file. */ static struct name_list * read_list(char *fonts) { struct name_list *nl; struct name_entry *np; char buf[PATH_MAX]; int fd, len; fd = open(fonts, O_RDONLY); if (fd < 0) return (NULL); nl = malloc(sizeof (*nl)); if (nl == NULL) { close(fd); return (nl); } SLIST_INIT(nl); while ((len = fgetstr(buf, sizeof (buf), fd)) > 0) { np = malloc(sizeof (*np)); if (np == NULL) { close(fd); return (nl); /* return what we have */ } np->n_name = strdup(buf); if (np->n_name == NULL) { free(np); close(fd); return (nl); /* return what we have */ } SLIST_INSERT_HEAD(nl, np, n_entry); } close(fd); return (nl); } /* * Read the font properties and insert new entry into the list. * The font list is built in descending order. */ static bool insert_font(char *name, FONT_FLAGS flags) { struct font_header fh; struct fontlist *fp, *previous, *entry, *next; size_t size; ssize_t rv; int fd; char *font_name; font_name = NULL; if (flags == FONT_BUILTIN) { /* * We only install builtin font once, while setting up * initial console. Since this will happen very early, * we assume asprintf will not fail. Once we have access to * files, the builtin font will be replaced by font loaded * from file. */ if (!STAILQ_EMPTY(&fonts)) return (false); fh.fh_width = DEFAULT_FONT_DATA.width; fh.fh_height = DEFAULT_FONT_DATA.height; (void) asprintf(&font_name, "%dx%d", DEFAULT_FONT_DATA.width, DEFAULT_FONT_DATA.height); } else { fd = open(name, O_RDONLY); if (fd < 0) return (false); rv = read(fd, &fh, sizeof (fh)); close(fd); if (rv < 0 || (size_t)rv != sizeof (fh)) return (false); if (memcmp(fh.fh_magic, FONT_HEADER_MAGIC, sizeof (fh.fh_magic)) != 0) return (false); font_name = strdup(name); } if (font_name == NULL) return (false); /* * If we have an entry with the same glyph dimensions, replace * the file name and mark us. We only support unique dimensions. */ STAILQ_FOREACH(entry, &fonts, font_next) { if (fh.fh_width == entry->font_data->width && fh.fh_height == entry->font_data->height) { free(entry->font_name); entry->font_name = font_name; entry->font_flags = FONT_RELOAD; return (true); } } fp = calloc(sizeof (*fp), 1); if (fp == NULL) { free(font_name); return (false); } fp->font_data = calloc(sizeof (*fp->font_data), 1); if (fp->font_data == NULL) { free(font_name); free(fp); return (false); } fp->font_name = font_name; fp->font_flags = flags; fp->font_load = load_font; fp->font_data->width = fh.fh_width; fp->font_data->height = fh.fh_height; if (STAILQ_EMPTY(&fonts)) { STAILQ_INSERT_HEAD(&fonts, fp, font_next); return (true); } previous = NULL; size = fp->font_data->width * fp->font_data->height; STAILQ_FOREACH(entry, &fonts, font_next) { /* Should fp be inserted before the entry? */ if (size > entry->font_data->width * entry->font_data->height) { if (previous == NULL) { STAILQ_INSERT_HEAD(&fonts, fp, font_next); } else { STAILQ_INSERT_AFTER(&fonts, previous, fp, font_next); } return (true); } next = STAILQ_NEXT(entry, font_next); if (next == NULL || size > next->font_data->width * next->font_data->height) { STAILQ_INSERT_AFTER(&fonts, entry, fp, font_next); return (true); } previous = entry; } return (true); } static int font_set(struct env_var *ev __unused, int flags __unused, const void *value) { struct fontlist *fl; char *eptr; unsigned long x = 0, y = 0; /* * Attempt to extract values from "XxY" string. In case of error, * we have unmaching glyph dimensions and will just output the * available values. */ if (value != NULL) { x = strtoul(value, &eptr, 10); if (*eptr == 'x') y = strtoul(eptr + 1, &eptr, 10); } STAILQ_FOREACH(fl, &fonts, font_next) { if (fl->font_data->width == x && fl->font_data->height == y) break; } if (fl != NULL) { /* Reset any FONT_MANUAL flag. */ reset_font_flags(); /* Mark this font manually loaded */ fl->font_flags = FONT_MANUAL; /* Trigger tem update. */ tems.update_font = true; plat_cons_update_mode(-1); return (CMD_OK); } printf("Available fonts:\n"); STAILQ_FOREACH(fl, &fonts, font_next) { printf(" %dx%d\n", fl->font_data->width, fl->font_data->height); } return (CMD_OK); } void bios_text_font(bool use_vga_font) { if (use_vga_font) (void) insert_font(VGA_8X16_FONT, FONT_MANUAL); else (void) insert_font(DEFAULT_8X16_FONT, FONT_MANUAL); tems.update_font = true; } void autoload_font(bool bios) { struct name_list *nl; struct name_entry *np; nl = read_list("/boot/fonts/fonts.dir"); if (nl == NULL) return; while (!SLIST_EMPTY(nl)) { np = SLIST_FIRST(nl); SLIST_REMOVE_HEAD(nl, n_entry); if (insert_font(np->n_name, FONT_AUTO) == false) printf("failed to add font: %s\n", np->n_name); free(np->n_name); free(np); } unsetenv("screen-font"); env_setenv("screen-font", EV_VOLATILE, NULL, font_set, env_nounset); /* * If vga text mode was requested, load vga.font (8x16 bold) font. */ if (bios) { bios_text_font(true); } /* Trigger tem update. */ tems.update_font = true; plat_cons_update_mode(-1); } COMMAND_SET(load_font, "loadfont", "load console font from file", command_font); static int command_font(int argc, char *argv[]) { int i, c, rc = CMD_OK; struct fontlist *fl; bool list; list = false; optind = 1; optreset = 1; rc = CMD_OK; while ((c = getopt(argc, argv, "l")) != -1) { switch (c) { case 'l': list = true; break; case '?': default: return (CMD_ERROR); } } argc -= optind; argv += optind; if (argc > 1 || (list && argc != 0)) { printf("Usage: loadfont [-l] | [file.fnt]\n"); return (CMD_ERROR); } if (list) { STAILQ_FOREACH(fl, &fonts, font_next) { printf("font %s: %dx%d%s\n", fl->font_name, fl->font_data->width, fl->font_data->height, fl->font_data->font == NULL? "" : " loaded"); } return (CMD_OK); } if (argc == 1) { char *name = argv[0]; if (insert_font(name, FONT_MANUAL) == false) { printf("loadfont error: failed to load: %s\n", name); return (CMD_ERROR); } tems.update_font = true; plat_cons_update_mode(-1); return (CMD_OK); } if (argc == 0) { /* * Walk entire font list, release any loaded font, and set * autoload flag. The font list does have at least the builtin * default font. */ STAILQ_FOREACH(fl, &fonts, font_next) { if (fl->font_data->font != NULL) { /* Note the tem is releasing font bytes */ for (i = 0; i < VFNT_MAPS; i++) free(fl->font_data->font->vf_map[i]); free(fl->font_data->font); fl->font_data->font = NULL; fl->font_data->uncompressed_size = 0; fl->font_flags = FONT_AUTO; } } tems.update_font = true; plat_cons_update_mode(-1); } return (rc); } bool gfx_get_edid_resolution(struct vesa_edid_info *edid, edid_res_list_t *res) { struct resolution *rp, *p; /* * Walk detailed timings tables (4). */ if ((edid->display.supported_features & EDID_FEATURE_PREFERRED_TIMING_MODE) != 0) { /* Walk detailed timing descriptors (4) */ for (int i = 0; i < DET_TIMINGS; i++) { /* * Reserved value 0 is not used for display decriptor. */ if (edid->detailed_timings[i].pixel_clock == 0) continue; if ((rp = malloc(sizeof (*rp))) == NULL) continue; rp->width = GET_EDID_INFO_WIDTH(edid, i); rp->height = GET_EDID_INFO_HEIGHT(edid, i); if (rp->width > 0 && rp->width <= EDID_MAX_PIXELS && rp->height > 0 && rp->height <= EDID_MAX_LINES) TAILQ_INSERT_TAIL(res, rp, next); else free(rp); } } /* * Walk standard timings list (8). */ for (int i = 0; i < STD_TIMINGS; i++) { /* Is this field unused? */ if (edid->standard_timings[i] == 0x0101) continue; if ((rp = malloc(sizeof (*rp))) == NULL) continue; rp->width = HSIZE(edid->standard_timings[i]); switch (RATIO(edid->standard_timings[i])) { case RATIO1_1: rp->height = HSIZE(edid->standard_timings[i]); if (edid->header.version > 1 || edid->header.revision > 2) { rp->height = rp->height * 10 / 16; } break; case RATIO4_3: rp->height = HSIZE(edid->standard_timings[i]) * 3 / 4; break; case RATIO5_4: rp->height = HSIZE(edid->standard_timings[i]) * 4 / 5; break; case RATIO16_9: rp->height = HSIZE(edid->standard_timings[i]) * 9 / 16; break; } /* * Create resolution list in decreasing order, except keep * first entry (preferred timing mode). */ TAILQ_FOREACH(p, res, next) { if (p->width * p->height < rp->width * rp->height) { /* Keep preferred mode first */ if (TAILQ_FIRST(res) == p) TAILQ_INSERT_AFTER(res, p, rp, next); else TAILQ_INSERT_BEFORE(p, rp, next); break; } if (TAILQ_NEXT(p, next) == NULL) { TAILQ_INSERT_TAIL(res, rp, next); break; } } } return (!TAILQ_EMPTY(res)); } /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2017 Toomas Soome * Copyright 2020 RackTop Systems, Inc. */ #ifndef _GFX_FB_H #define _GFX_FB_H #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define EDID_MAGIC { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } struct edid_header { uint8_t header[8]; /* fixed header pattern */ uint16_t manufacturer_id; uint16_t product_code; uint32_t serial_number; uint8_t week_of_manufacture; uint8_t year_of_manufacture; uint8_t version; uint8_t revision; }; struct edid_basic_display_parameters { uint8_t video_input_parameters; uint8_t max_horizontal_image_size; uint8_t max_vertical_image_size; uint8_t display_gamma; uint8_t supported_features; }; struct edid_chromaticity_coordinates { uint8_t red_green_lo; uint8_t blue_white_lo; uint8_t red_x_hi; uint8_t red_y_hi; uint8_t green_x_hi; uint8_t green_y_hi; uint8_t blue_x_hi; uint8_t blue_y_hi; uint8_t white_x_hi; uint8_t white_y_hi; }; struct edid_detailed_timings { uint16_t pixel_clock; uint8_t horizontal_active_lo; uint8_t horizontal_blanking_lo; uint8_t horizontal_hi; uint8_t vertical_active_lo; uint8_t vertical_blanking_lo; uint8_t vertical_hi; uint8_t horizontal_sync_offset_lo; uint8_t horizontal_sync_pulse_width_lo; uint8_t vertical_sync_lo; uint8_t sync_hi; uint8_t horizontal_image_size_lo; uint8_t vertical_image_size_lo; uint8_t image_size_hi; uint8_t horizontal_border; uint8_t vertical_border; uint8_t features; }; struct vesa_edid_info { struct edid_header header; struct edid_basic_display_parameters display; #define EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) struct edid_chromaticity_coordinates chromaticity; uint8_t established_timings_1; uint8_t established_timings_2; uint8_t manufacturer_reserved_timings; uint16_t standard_timings[8]; struct edid_detailed_timings detailed_timings[4]; uint8_t number_of_extensions; uint8_t checksum; } __packed; extern struct vesa_edid_info *edid_info; #define STD_TIMINGS 8 #define DET_TIMINGS 4 #define HSIZE(x) (((x & 0xff) + 31) * 8) #define RATIO(x) ((x & 0xC000) >> 14) #define RATIO1_1 0 /* EDID Ver. 1.3 redefined this */ #define RATIO16_10 RATIO1_1 #define RATIO4_3 1 #define RATIO5_4 2 #define RATIO16_9 3 /* * Number of pixels and lines is 12-bit int, valid values 0-4095. */ #define EDID_MAX_PIXELS 4095 #define EDID_MAX_LINES 4095 #define GET_EDID_INFO_WIDTH(edid_info, timings_num) \ ((edid_info)->detailed_timings[(timings_num)].horizontal_active_lo | \ (((uint_t)(edid_info)->detailed_timings[(timings_num)].horizontal_hi & \ 0xf0) << 4)) #define GET_EDID_INFO_HEIGHT(edid_info, timings_num) \ ((edid_info)->detailed_timings[(timings_num)].vertical_active_lo | \ (((uint_t)(edid_info)->detailed_timings[(timings_num)].vertical_hi & \ 0xf0) << 4)) struct resolution { uint32_t width; uint32_t height; TAILQ_ENTRY(resolution) next; }; typedef TAILQ_HEAD(edid_resolution, resolution) edid_res_list_t; extern multiboot_tag_framebuffer_t gfx_fb; typedef enum { GfxFbBltVideoFill, GfxFbBltVideoToBltBuffer, GfxFbBltBufferToVideo, GfxFbBltVideoToVideo, GfxFbBltOperationMax, } GFXFB_BLT_OPERATION; int gfxfb_blt(void *, GFXFB_BLT_OPERATION, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void bios_text_font(bool); bool gfx_get_edid_resolution(struct vesa_edid_info *, edid_res_list_t *); void gfx_framework_init(void); uint32_t gfx_fb_color_map(uint8_t); int gfx_fb_cons_clear(struct vis_consclear *); void gfx_fb_cons_copy(struct vis_conscopy *); void gfx_fb_cons_display(struct vis_consdisplay *); void gfx_fb_display_cursor(struct vis_conscursor *); void gfx_fb_setpixel(uint32_t, uint32_t); void gfx_fb_drawrect(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void gfx_term_drawrect(uint32_t, uint32_t, uint32_t, uint32_t); void gfx_fb_line(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void gfx_fb_bezier(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void plat_cons_update_mode(int); #define FL_PUTIMAGE_BORDER 0x1 #define FL_PUTIMAGE_NOSCROLL 0x2 #define FL_PUTIMAGE_DEBUG 0x80 int gfx_fb_putimage(png_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); bool gfx_parse_mode_str(char *, int *, int *, int *); #ifdef __cplusplus } #endif #endif /* _GFX_FB_H */ /* * Copyright (c) 2010 Pawel Jakub Dawidek * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. */ #include #include #include #ifndef LITTLE_ENDIAN #error gpt.c works only for little endian architectures #endif #include "zlib.h" #include "drv.h" #include "util.h" #include "gpt.h" #define MAXTBLENTS 128 static struct gpt_hdr hdr_primary, hdr_backup, *gpthdr; static uint64_t hdr_primary_lba, hdr_backup_lba; static struct gpt_ent table_primary[MAXTBLENTS], table_backup[MAXTBLENTS]; static struct gpt_ent *gpttable; static int curent, bootonce; /* * Buffer below 64kB passed on gptread(), which can hold at least * one sector of data (512 bytes). */ static char *secbuf; static void gptupdate(const char *which, struct dsk *dskp, struct gpt_hdr *hdr, struct gpt_ent *table) { int entries_per_sec, firstent; daddr_t slba; /* * We need to update the following for both primary and backup GPT: * 1. Sector on disk that contains current partition. * 2. Partition table checksum. * 3. Header checksum. * 4. Header on disk. */ entries_per_sec = DEV_BSIZE / hdr->hdr_entsz; slba = curent / entries_per_sec; firstent = slba * entries_per_sec; bcopy(&table[firstent], secbuf, DEV_BSIZE); slba += hdr->hdr_lba_table; if (drvwrite(dskp, secbuf, slba, 1)) { printf("%s: unable to update %s GPT partition table\n", BOOTPROG, which); return; } hdr->hdr_crc_table = crc32(0, Z_NULL, 0); hdr->hdr_crc_table = crc32(hdr->hdr_crc_table, table, hdr->hdr_entries * hdr->hdr_entsz); hdr->hdr_crc_self = crc32(0, Z_NULL, 0); hdr->hdr_crc_self = crc32(hdr->hdr_crc_self, hdr, hdr->hdr_size); bzero(secbuf, DEV_BSIZE); bcopy(hdr, secbuf, hdr->hdr_size); if (drvwrite(dskp, secbuf, hdr->hdr_lba_self, 1)) { printf("%s: unable to update %s GPT header\n", BOOTPROG, which); return; } } int gptfind(const uuid_t *uuid, struct dsk *dskp, int part) { struct gpt_ent *ent; int firsttry; if (part >= 0) { if (part == 0 || part > gpthdr->hdr_entries) { printf("%s: invalid partition index\n", BOOTPROG); return (-1); } ent = &gpttable[part - 1]; if (bcmp(&ent->ent_type, uuid, sizeof (uuid_t)) != 0) { printf("%s: specified partition is not UFS\n", BOOTPROG); return (-1); } curent = part - 1; goto found; } firsttry = (curent == -1); curent++; if (curent >= gpthdr->hdr_entries) { curent = gpthdr->hdr_entries; return (-1); } if (bootonce) { /* * First look for partition with both GPT_ENT_ATTR_BOOTME and * GPT_ENT_ATTR_BOOTONCE flags. */ for (; curent < gpthdr->hdr_entries; curent++) { ent = &gpttable[curent]; if (bcmp(&ent->ent_type, uuid, sizeof (uuid_t)) != 0) continue; if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTME)) continue; if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTONCE)) continue; /* Ok, found one. */ goto found; } bootonce = 0; curent = 0; } for (; curent < gpthdr->hdr_entries; curent++) { ent = &gpttable[curent]; if (bcmp(&ent->ent_type, uuid, sizeof (uuid_t)) != 0) continue; if (!(ent->ent_attr & GPT_ENT_ATTR_BOOTME)) continue; if (ent->ent_attr & GPT_ENT_ATTR_BOOTONCE) continue; /* Ok, found one. */ goto found; } if (firsttry) { /* * No partition with BOOTME flag was found, try to boot from * first UFS partition. */ for (curent = 0; curent < gpthdr->hdr_entries; curent++) { ent = &gpttable[curent]; if (bcmp(&ent->ent_type, uuid, sizeof (uuid_t)) != 0) continue; /* Ok, found one. */ goto found; } } return (-1); found: dskp->part = curent + 1; ent = &gpttable[curent]; dskp->start = ent->ent_lba_start; if (ent->ent_attr & GPT_ENT_ATTR_BOOTONCE) { /* * Clear BOOTME, but leave BOOTONCE set before trying to * boot from this partition. */ if (hdr_primary_lba > 0) { table_primary[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTME; gptupdate("primary", dskp, &hdr_primary, table_primary); } if (hdr_backup_lba > 0) { table_backup[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTME; gptupdate("backup", dskp, &hdr_backup, table_backup); } } return (0); } static int gptread_hdr(const char *which, struct dsk *dskp, struct gpt_hdr *hdr, uint64_t hdrlba) { uint32_t crc; if (drvread(dskp, secbuf, hdrlba, 1)) { printf("%s: unable to read %s GPT header\n", BOOTPROG, which); return (-1); } bcopy(secbuf, hdr, sizeof (*hdr)); if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof (hdr->hdr_sig)) != 0 || hdr->hdr_lba_self != hdrlba || hdr->hdr_revision < 0x00010000 || hdr->hdr_entsz < sizeof (struct gpt_ent) || hdr->hdr_entries > MAXTBLENTS || DEV_BSIZE % hdr->hdr_entsz != 0) { printf("%s: invalid %s GPT header\n", BOOTPROG, which); return (-1); } crc = hdr->hdr_crc_self; hdr->hdr_crc_self = crc32(0, Z_NULL, 0); if (crc32(hdr->hdr_crc_self, hdr, hdr->hdr_size) != crc) { printf("%s: %s GPT header checksum mismatch\n", BOOTPROG, which); return (-1); } hdr->hdr_crc_self = crc; return (0); } void gptbootfailed(struct dsk *dskp) { if (!(gpttable[curent].ent_attr & GPT_ENT_ATTR_BOOTONCE)) return; if (hdr_primary_lba > 0) { table_primary[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTONCE; table_primary[curent].ent_attr |= GPT_ENT_ATTR_BOOTFAILED; gptupdate("primary", dskp, &hdr_primary, table_primary); } if (hdr_backup_lba > 0) { table_backup[curent].ent_attr &= ~GPT_ENT_ATTR_BOOTONCE; table_backup[curent].ent_attr |= GPT_ENT_ATTR_BOOTFAILED; gptupdate("backup", dskp, &hdr_backup, table_backup); } } static void gptbootconv(const char *which, struct dsk *dskp, struct gpt_hdr *hdr, struct gpt_ent *table) { struct gpt_ent *ent; daddr_t slba; int table_updated, sector_updated; int entries_per_sec, nent, part; table_updated = 0; entries_per_sec = DEV_BSIZE / hdr->hdr_entsz; for (nent = 0, slba = hdr->hdr_lba_table; slba < hdr->hdr_lba_table + hdr->hdr_entries / entries_per_sec; slba++, nent += entries_per_sec) { sector_updated = 0; for (part = 0; part < entries_per_sec; part++) { ent = &table[nent + part]; if ((ent->ent_attr & (GPT_ENT_ATTR_BOOTME | GPT_ENT_ATTR_BOOTONCE | GPT_ENT_ATTR_BOOTFAILED)) != GPT_ENT_ATTR_BOOTONCE) { continue; } ent->ent_attr &= ~GPT_ENT_ATTR_BOOTONCE; ent->ent_attr |= GPT_ENT_ATTR_BOOTFAILED; table_updated = 1; sector_updated = 1; } if (!sector_updated) continue; bcopy(&table[nent], secbuf, DEV_BSIZE); if (drvwrite(dskp, secbuf, slba, 1)) { printf("%s: unable to update %s GPT partition table\n", BOOTPROG, which); } } if (!table_updated) return; hdr->hdr_crc_table = crc32(0, Z_NULL, 0); hdr->hdr_crc_table = crc32(hdr->hdr_crc_table, table, hdr->hdr_entries * hdr->hdr_entsz); hdr->hdr_crc_self = crc32(0, Z_NULL, 0); hdr->hdr_crc_self = crc32(hdr->hdr_crc_self, hdr, hdr->hdr_size); bzero(secbuf, DEV_BSIZE); bcopy(hdr, secbuf, hdr->hdr_size); if (drvwrite(dskp, secbuf, hdr->hdr_lba_self, 1)) printf("%s: unable to update %s GPT header\n", BOOTPROG, which); } static int gptread_table(const char *which, const uuid_t *uuid, struct dsk *dskp, struct gpt_hdr *hdr, struct gpt_ent *table) { struct gpt_ent *ent; int entries_per_sec; int part, nent; daddr_t slba; if (hdr->hdr_entries == 0) return (0); entries_per_sec = DEV_BSIZE / hdr->hdr_entsz; slba = hdr->hdr_lba_table; nent = 0; for (;;) { if (drvread(dskp, secbuf, slba, 1)) { printf("%s: unable to read %s GPT partition table\n", BOOTPROG, which); return (-1); } ent = (struct gpt_ent *)secbuf; for (part = 0; part < entries_per_sec; part++, ent++) { bcopy(ent, &table[nent], sizeof (table[nent])); if (++nent >= hdr->hdr_entries) break; } if (nent >= hdr->hdr_entries) break; slba++; } if (crc32(0, table, nent * hdr->hdr_entsz) != hdr->hdr_crc_table) { printf("%s: %s GPT table checksum mismatch\n", BOOTPROG, which); return (-1); } return (0); } int gptread(const uuid_t *uuid, struct dsk *dskp, char *buf) { uint64_t altlba; /* * Read and verify both GPT headers: primary and backup. */ secbuf = buf; hdr_primary_lba = hdr_backup_lba = 0; curent = -1; bootonce = 1; dskp->start = 0; if (gptread_hdr("primary", dskp, &hdr_primary, 1) == 0 && gptread_table("primary", uuid, dskp, &hdr_primary, table_primary) == 0) { hdr_primary_lba = hdr_primary.hdr_lba_self; gpthdr = &hdr_primary; gpttable = table_primary; } if (hdr_primary_lba > 0) { /* * If primary header is valid, we can get backup * header location from there. */ altlba = hdr_primary.hdr_lba_alt; } else { altlba = drvsize(dskp); if (altlba > 0) altlba--; } if (altlba == 0) printf("%s: unable to locate backup GPT header\n", BOOTPROG); else if (gptread_hdr("backup", dskp, &hdr_backup, altlba) == 0 && gptread_table("backup", uuid, dskp, &hdr_backup, table_backup) == 0) { hdr_backup_lba = hdr_backup.hdr_lba_self; if (hdr_primary_lba == 0) { gpthdr = &hdr_backup; gpttable = table_backup; printf("%s: using backup GPT\n", BOOTPROG); } } /* * Convert all BOOTONCE without BOOTME flags into BOOTFAILED. * BOOTONCE without BOOTME means that we tried to boot from it, * but failed after leaving gptboot and machine was rebooted. * We don't want to leave partitions marked as BOOTONCE only, * because when we boot successfully start-up scripts should * find at most one partition with only BOOTONCE flag and this * will mean that we booted from that partition. */ if (hdr_primary_lba != 0) gptbootconv("primary", dskp, &hdr_primary, table_primary); if (hdr_backup_lba != 0) gptbootconv("backup", dskp, &hdr_backup, table_backup); if (hdr_primary_lba == 0 && hdr_backup_lba == 0) return (-1); return (0); } /* * Copyright (c) 2010 Pawel Jakub Dawidek * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 _GPT_H_ #define _GPT_H_ #include #include int gptread(const uuid_t *uuid, struct dsk *dskp, char *buf); int gptfind(const uuid_t *uuid, struct dsk *dskp, int part); void gptbootfailed(struct dsk *dskp); #endif /* !_GPT_H_ */ ################################################################################ # Thelp DDisplay command help help [topic [subtopic]] help index The help command displays help on commands and their usage. In command help, a term enclosed with <...> indicates a value as described by the term. A term enclosed with [...] is optional, and may not be required by all forms of the command. Some commands may not be available. Use the '?' command to list most available commands. ################################################################################ # T? DList available commands ? Lists all available commands. ################################################################################ # Tautoboot DBoot after a delay autoboot [ []] Displays or a default prompt, and counts down seconds before attempting to boot. If is not specified, the default value is 10. ################################################################################ # Tbeadm DList or switch Boot Environment beadm activate beName [] beadm list [] beadm activate unloads the currently loaded configuration and modules, sets currdev to and loads configuration from new device. Use lsdev to get available device names. ################################################################################ # Tboot DBoot immediately boot [] [- ...] Boot the system. If arguments are specified, they are added to the arguments for the kernel. If is specified, and a kernel has not already been loaded, it will be booted instead of the default kernel. ################################################################################ # Tbcachestat DGet disk block cache stats bcachestat Displays statistics about disk cache usage. For debugging only. ################################################################################ # Tconsole DOutput information about console devices console Display the currently active console device(s) and show information about available console devices. ################################################################################ # Tchain DChain load disk block chain disk: chain will read stage1 (MBR or VBR) boot block from specified device to address 0000:7C00 and attempts to run it. Use lsdev to get available device names. Disk name must end with colon. ################################################################################ # Techo DEcho arguments echo [-n] [] Emits , with no trailing newline if -n is specified. This is most useful in conjunction with scripts and the '@' line prefix. Variables are substituted by prefixing them with $, eg. echo Current device is $currdev will print the current device. ################################################################################ # Tframebuffer DManage framebuffer setup framebuffer on | off | get | list [depth] | set Switch framebuffer mode on or off, get current mode, list available modes or set mode by using either display resolution or framebuffer mode number. If the system does not provide display resolution via EDID, the default resolution will be set to 800x600. If depth is not specified, the best depth is used. ################################################################################ # Tload DLoad a kernel or module load [-t ] [arguments] Loads the module contained in into memory. If no other modules are loaded, must be a kernel or the command will fail. If -t is specified, the module is loaded as raw data of , for later use by the kernel or other modules. may be any string. Optional arguments will be set as module arguments. ################################################################################ # Tls DList files ls [-l] [] Displays a listing of files in the directory , or the root directory of the current device if is not specified. The -l argument displays file sizes as well; the process of obtaining file sizes on some media may be very slow. ################################################################################ # Tlsdev DList devices lsdev [-v] List all of the devices from which it may be possible to load modules. If -v is specified, print more details. ################################################################################ # Tlsmod DList modules lsmod [-v] List loaded modules. If [-v] is specified, print more details. ################################################################################ # Tmap-vdisk DMap virtual disk map-vdisk filename Map file as virtual disk. ################################################################################ # Tmore DPage files more [ ...] Show contents of text files. When displaying the contents of more, than one file, if the user elects to quit displaying a file, the remaining files will not be shown. ################################################################################ # Tpnpscan DScan for PnP devices pnpscan [-v] Scan for Plug-and-Play devices. This command is normally automatically run as part of the boot process, in order to dynamically load modules required for system operation. If the -v argument is specified, details on the devices found will be printed. ################################################################################ # Tset DSet a variable set set = The set command is used to set variables. ################################################################################ # Tsetprop DSet a variable setprop The setprop command is used to set variables. ################################################################################ # Tset Sautoboot_delay DSet the default autoboot delay set autoboot_delay= Sets the default delay for the autoboot command to seconds. Set value to -1 if you don't want to allow user to interrupt autoboot process and escape to the loader prompt. ################################################################################ # Tset Sbootfile DSet the default boot file set set bootfile=[;...] Sets the default set of kernel boot filename(s). It may be overridden by setting the bootfile variable to a semicolon-separated list of filenames, each of which will be searched for in the module_path directories. The default bootfile set is "unix". ################################################################################ # Tset Sboot_ask DPrompt for configuration information set boot_ask Instructs the kernel to prompt the user for the configuration information when the kernel is booted. ################################################################################ # Tset Sboot_drop_into_kmdb DDrop into the kernel debugger (kmdb) set boot_drop_into_kmdb Instructs the kernel to start in the kmdb debugger, rather than proceeding to initialize when booted. Can only be used when boot_kmdb is set. ################################################################################ # Tset Sboot_kmdb DStart the kernel debugger (kmdb) set boot_kmdb Instructs the kernel to start the kmdb debugger and then continue with normal boot. ################################################################################ # Tset Sboot_reconfigure DInitaiate reconfiguration boot set boot_reconfigure The system will probe all attached hardware devices and configure the logical namespace in /dev. ################################################################################ # Tset Sboot_multicons DUse multiple consoles set boot_multicons Enables multiple console support in the kernel early on boot. In a running system, console configuration can be manipulated by the conscontrol(8) utility. ################################################################################ # Tset Sboot_single DBoot into the single user mode set boot_single Boots only to init level 's'. ################################################################################ # Tset Sboot_verbose DBoot with verbose messages enabled set boot_verbose Without this setting, the messages are only logged in the system log. ################################################################################ # Tset Sconsole DSet the current console set console[=[,]] Sets the current console. If is omitted, a list of valid consoles will be displayed. ################################################################################ # Tset Scurrdev DSet the current device set currdev= Selects the default device. See lsdev for available devices. ################################################################################ # Tset Smodule_path DSet the module search path set module_path=[;...] Sets the list of directories which will be searched in for modules named in a load command or implicitly required by a dependency. The default module_path is "/boot/modules" with the kernel directory prepended. ################################################################################ # Tset Sprompt DSet the command prompt set prompt= The command prompt is displayed when the loader is waiting for input. Variable substitution is performed on the prompt. The default prompt can be set with: set prompt=\${interpret} ################################################################################ # Tset Sscreen-font DSet the framebuffer font Without the value, will list the currently available list of the fonts. ################################################################################ # Tset Srootdev DSet the root filesystem set rootdev= By default the value of $currdev is used to set the root filesystem when the kernel is booted. This can be overridden by setting $rootdev explicitly. ################################################################################ # Tshow DShow the values of variables show [] Displays the value of , or all variables if not specified. ################################################################################ # Tsifting DSearch for words containing a substring sifting Displays words in the search order list containing the provided . ################################################################################ # Tinclude DRead commands from a script file include [ ...] The entire contents of are read into memory before executing commands, so it is safe to source a file from removable media. ################################################################################ # Tread DRead input from the terminal read [-t ] [-p ] [] The read command reads a line of input from the terminal. If the -t argument is specified, it will return nothing if no input has been received after seconds. (Any keypress will cancel the timeout). If -p is specified, is printed before reading input. No newline is emitted after the prompt. If a variable name is supplied, the variable is set to the value read, less any terminating newline. ################################################################################ # Tunload DRemove all modules from memory unload This command removes any kernel and all loaded modules from memory. ################################################################################ # Tunmap-vdisk DUnmap virtual disk unmap-vdisk diskname Delete virtual disk mapping. ################################################################################ # Tunset DUnset a variable unset If allowed, the named variable's value is discarded and the variable is removed. ################################################################################ /* * Copyright (c) 1998 Michael Smith * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. * All rights reserved. * * 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. * * 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. */ #include /* * Simple commandline interpreter, toplevel and misc. * * XXX may be obsoleted by BootFORTH or some other, better, interpreter. */ #include #include #include "bootstrap.h" #ifdef BOOT_FORTH #include "ficl.h" #define RETURN(x) ficlStackPushInteger(ficlVmGetDataStack(bf_vm),!x); return(x) extern ficlVm *bf_vm; #else #define RETURN(x) return(x) #endif #include "linenoise/linenoise.h" #define MAXARGS 20 /* maximum number of arguments allowed */ static char *prompt(void); #ifndef BOOT_FORTH static int perform(int argc, char *argv[]); /* * Perform the command */ int perform(int argc, char *argv[]) { int result; struct bootblk_command **cmdp; bootblk_cmd_t *cmd; if (argc < 1) return(CMD_OK); /* set return defaults; a successful command will override these */ command_errmsg = command_errbuf; strcpy(command_errbuf, "no error message"); cmd = NULL; result = CMD_ERROR; /* search the command set for the command */ SET_FOREACH(cmdp, Xcommand_set) { if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name)) cmd = (*cmdp)->c_fn; } if (cmd != NULL) { result = (cmd)(argc, argv); } else { command_errmsg = "unknown command"; } RETURN(result); } #endif /* ! BOOT_FORTH */ /* * Interactive mode */ void interact(const char *rc) { char *input = NULL; bf_init((rc) ? "" : NULL); if (rc == NULL) { /* Read our default configuration. */ include("/boot/loader.rc"); } else if (*rc != '\0') include(rc); printf("\n"); /* * Before interacting, we might want to autoboot. */ autoboot_maybe(); /* * Not autobooting, go manual */ printf("\nType '?' for a list of commands, 'help' for more detailed help.\n"); if (getenv("prompt") == NULL) setenv("prompt", "${interpret}", 1); if (getenv("interpret") == NULL) setenv("interpret", "ok", 1); while ((input = linenoise(prompt())) != NULL) { bf_vm->sourceId.i = 0; bf_run(input); linenoiseHistoryAdd(input); free(input); } } /* * Read commands from a file, then execute them. * * We store the commands in memory and close the source file so that the media * holding it can safely go away while we are executing. * * Commands may be prefixed with '@' (so they aren't displayed) or '-' (so * that the script won't stop if they fail). */ COMMAND_SET(include, "include", "read commands from a file", command_include); static int command_include(int argc, char *argv[]) { int i; int res; char **argvbuf; /* * Since argv is static, we need to save it here. */ argvbuf = (char**) calloc((u_int)argc, sizeof(char*)); for (i = 0; i < argc; i++) argvbuf[i] = strdup(argv[i]); res=CMD_OK; for (i = 1; (i < argc) && (res == CMD_OK); i++) res = include(argvbuf[i]); for (i = 0; i < argc; i++) free(argvbuf[i]); free(argvbuf); return(res); } COMMAND_SET(sifting, "sifting", "find words", command_sifting); static int command_sifting(int argc, char *argv[]) { if (argc != 2) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } ficlPrimitiveSiftingImpl(bf_vm, argv[1]); return (CMD_OK); } /* * Header prepended to each line. The text immediately follows the header. * We try to make this short in order to save memory -- the loader has * limited memory available, and some of the forth files are very long. */ struct includeline { struct includeline *next; int line; char text[0]; }; /* * The PXE TFTP service allows opening exactly one connection at the time, * so we need to read included file into memory, then process line by line * as it may contain embedded include commands. */ int include(const char *filename) { struct includeline *script, *se, *sp; int res = CMD_OK; int prevsrcid, fd, line; char *cp, input[256]; /* big enough? */ if (((fd = open(filename, O_RDONLY)) == -1)) { snprintf(command_errbuf, sizeof (command_errbuf), "can't open '%s': %s", filename, strerror(errno)); return(CMD_ERROR); } /* * Read the script into memory. */ script = se = NULL; line = 0; while (fgetstr(input, sizeof(input), fd) >= 0) { line++; cp = input; /* Allocate script line structure and copy line, flags */ if (*cp == '\0') continue; /* ignore empty line, save memory */ if (cp[0] == '\\' && cp[1] == ' ') continue; /* ignore comment */ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1); /* On malloc failure (it happens!), free as much as possible and exit */ if (sp == NULL) { while (script != NULL) { se = script; script = script->next; free(se); } snprintf(command_errbuf, sizeof (command_errbuf), "file '%s' line %d: memory allocation failure - aborting", filename, line); close(fd); return (CMD_ERROR); } strcpy(sp->text, cp); sp->line = line; sp->next = NULL; if (script == NULL) { script = sp; } else { se->next = sp; } se = sp; } close(fd); /* * Execute the script */ prevsrcid = bf_vm->sourceId.i; bf_vm->sourceId.i = fd+1; /* 0 is user input device */ res = CMD_OK; for (sp = script; sp != NULL; sp = sp->next) { res = bf_run(sp->text); if (res != FICL_VM_STATUS_OUT_OF_TEXT) { snprintf(command_errbuf, sizeof (command_errbuf), "Error while including %s, in the line %d:\n%s", filename, sp->line, sp->text); res = CMD_ERROR; break; } else res = CMD_OK; } bf_vm->sourceId.i = -1; (void) bf_run(""); bf_vm->sourceId.i = prevsrcid; while(script != NULL) { se = script; script = script->next; free(se); } return(res); } /* * Emit the current prompt; use the same syntax as the parser * for embedding environment variables. */ static char * prompt(void) { static char promptbuf[20]; /* probably too large, but well... */ char *pr, *p, *cp, *ev; int n = 0; if ((cp = getenv("prompt")) == NULL) cp = (char *)(uintptr_t)">"; pr = p = strdup(cp); while (*p != 0) { if ((*p == '$') && (*(p+1) == '{')) { for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++) ; *cp = 0; ev = getenv(p + 2); if (ev != NULL) n = sprintf(promptbuf+n, "%s", ev); p = cp + 1; continue; } promptbuf[n++] = *p; p++; } if (promptbuf[n - 1] != ' ') promptbuf[n++] = ' '; promptbuf[n] = '\0'; free(pr); return (promptbuf); } /* * 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. * * Jordan K. Hubbard * 29 August 1998 * * Routine for doing backslash elimination. */ #include #include #include #include "bootstrap.h" #define DIGIT(x) \ (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') /* * backslash: Return malloc'd copy of str with all standard "backslash * processing" done on it. Original can be free'd if desired. */ char * backslash(char *str) { /* * Remove backslashes from the strings. Turn \040 etc. into a single * character (we allow eight bit values). Currently NUL is not * allowed. * * Turn "\n" and "\t" into '\n' and '\t' characters. Etc. * */ char *new_str; int seenbs = 0; int i = 0; if ((new_str = strdup(str)) == NULL) return (NULL); while (*str) { if (seenbs) { seenbs = 0; switch (*str) { case '\\': new_str[i++] = '\\'; str++; break; /* preserve backslashed quotes, dollar signs */ case '\'': case '"': case '$': new_str[i++] = '\\'; new_str[i++] = *str++; break; case 'b': new_str[i++] = '\b'; str++; break; case 'f': new_str[i++] = '\f'; str++; break; case 'r': new_str[i++] = '\r'; str++; break; case 'n': new_str[i++] = '\n'; str++; break; case 's': new_str[i++] = ' '; str++; break; case 't': new_str[i++] = '\t'; str++; break; case 'v': new_str[i++] = '\13'; str++; break; case 'z': str++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { char val; /* Three digit octal constant? */ if (*str >= '0' && *str <= '3' && *(str + 1) >= '0' && *(str + 1) <= '7' && *(str + 2) >= '0' && *(str + 2) <= '7') { val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) + DIGIT(*(str + 2)); /* * Allow null value if user really * wants to shoot at feet, but beware! */ new_str[i++] = val; str += 3; break; } /* * One or two digit hex constant? * If two are there they will both be taken. * Use \z to split them up if this is not * wanted. */ if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X') && isxdigit(*(str + 2))) { val = DIGIT(*(str + 2)); if (isxdigit(*(str + 3))) { val = (val << 4) + DIGIT(*(str + 3)); str += 4; } else str += 3; /* Yep, allow null value here too */ new_str[i++] = val; break; } } break; default: new_str[i++] = *str++; break; } } else { if (*str == '\\') { seenbs = 1; str++; } else new_str[i++] = *str++; } } if (seenbs) { /* * The final character was a '\'. * Put it in as a single backslash. */ new_str[i++] = '\\'; } new_str[i] = '\0'; return (new_str); } /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include #include /* to pick up __FreeBSD_version */ #include #include #include "bootstrap.h" #include "ficl.h" extern unsigned bootprog_rev; /* #define BFORTH_DEBUG */ #ifdef BFORTH_DEBUG #define DPRINTF(fmt, args...) printf("%s: " fmt "\n", __func__, ## args) #else #define DPRINTF(fmt, args...) ((void)0) #endif /* * Eventually, all builtin commands throw codes must be defined * elsewhere, possibly bootstrap.h. For now, just this code, used * just in this file, it is getting defined. */ #define BF_PARSE 100 /* * FreeBSD loader default dictionary cells */ #ifndef BF_DICTSIZE #define BF_DICTSIZE 30000 #endif /* * BootForth Interface to Ficl Forth interpreter. */ ficlSystemInformation *fsi; ficlSystem *bf_sys; ficlVm *bf_vm; /* * Shim for taking commands from BF and passing them out to 'standard' * argv/argc command functions. */ static void bf_command(ficlVm *vm) { char *name, *line, *tail, *cp; size_t len; struct bootblk_command **cmdp; bootblk_cmd_t *cmd; int nstrings, i; int argc, result; char **argv; /* Get the name of the current word */ name = vm->runningWord->name; /* Find our command structure */ cmd = NULL; SET_FOREACH(cmdp, Xcommand_set) { if (((*cmdp)->c_name != NULL) && strcmp(name, (*cmdp)->c_name) == 0) cmd = (*cmdp)->c_fn; } if (cmd == NULL) panic("callout for unknown command '%s'", name); /* Check whether we have been compiled or are being interpreted */ if (ficlStackPopInteger(ficlVmGetDataStack(vm))) { /* * Get parameters from stack, in the format: * an un ... a2 u2 a1 u1 n -- * Where n is the number of strings, a/u are pairs of * address/size for strings, and they will be concatenated * in LIFO order. */ nstrings = ficlStackPopInteger(ficlVmGetDataStack(vm)); for (i = 0, len = 0; i < nstrings; i++) { ficlStack *stack = ficlVmGetDataStack(vm); len += ficlStackFetch(stack, i * 2).i + 1; } line = malloc(strlen(name) + len + 1); strcpy(line, name); if (nstrings) for (i = 0; i < nstrings; i++) { ficlStack *stack = ficlVmGetDataStack(vm); len = ficlStackPopInteger(stack); cp = ficlStackPopPointer(stack); strcat(line, " "); strncat(line, cp, len); } } else { /* Get remainder of invocation */ tail = ficlVmGetInBuf(vm); len = 0; cp = tail; for (; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++) len++; line = malloc(strlen(name) + len + 2); strcpy(line, name); if (len > 0) { strcat(line, " "); strncat(line, tail, len); ficlVmUpdateTib(vm, tail + len); } } DPRINTF("cmd '%s'", line); command_errmsg = command_errbuf; command_errbuf[0] = 0; if (!parse(&argc, &argv, line)) { result = (cmd)(argc, argv); free(argv); } else { result = BF_PARSE; } switch (result) { case CMD_CRIT: printf("%s\n", command_errmsg); command_errmsg = NULL; break; case CMD_FATAL: panic("%s", command_errmsg); } free(line); /* * If there was error during nested ficlExec(), we may no longer have * valid environment to return. Throw all exceptions from here. */ if (result != CMD_OK) ficlVmThrow(vm, result); /* This is going to be thrown!!! */ ficlStackPushInteger(ficlVmGetDataStack(vm), result); } /* * Replace a word definition (a builtin command) with another * one that: * * - Throw error results instead of returning them on the stack * - Pass a flag indicating whether the word was compiled or is * being interpreted. * * There is one major problem with builtins that cannot be overcome * in anyway, except by outlawing it. We want builtins to behave * differently depending on whether they have been compiled or they * are being interpreted. Notice that this is *not* the interpreter's * current state. For example: * * : example ls ; immediate * : problem example ; \ "ls" gets executed while compiling * example \ "ls" gets executed while interpreting * * Notice that, though the current state is different in the two * invocations of "example", in both cases "ls" has been * *compiled in*, which is what we really want. * * The problem arises when you tick the builtin. For example: * * : example-1 ['] ls postpone literal ; immediate * : example-2 example-1 execute ; immediate * : problem example-2 ; * example-2 * * We have no way, when we get EXECUTEd, of knowing what our behavior * should be. Thus, our only alternative is to "outlaw" this. See RFI * 0007, and ANS Forth Standard's appendix D, item 6.7 for a related * problem, concerning compile semantics. * * The problem is compounded by the fact that "' builtin CATCH" is valid * and desirable. The only solution is to create an intermediary word. * For example: * * : my-ls ls ; * : example ['] my-ls catch ; * * So, with the below implementation, here is a summary of the behavior * of builtins: * * ls -l \ "interpret" behavior, ie, * \ takes parameters from TIB * : ex-1 s" -l" 1 ls ; \ "compile" behavior, ie, * \ takes parameters from the stack * : ex-2 ['] ls catch ; immediate \ undefined behavior * : ex-3 ['] ls catch ; \ undefined behavior * ex-2 ex-3 \ "interpret" behavior, * \ catch works * : ex-4 ex-2 ; \ "compile" behavior, * \ catch does not work * : ex-5 ex-3 ; immediate \ same as ex-2 * : ex-6 ex-3 ; \ same as ex-3 * : ex-7 ['] ex-1 catch ; \ "compile" behavior, * \ catch works * : ex-8 postpone ls ; immediate \ same as ex-2 * : ex-9 postpone ls ; \ same as ex-3 * * As the definition below is particularly tricky, and it's side effects * must be well understood by those playing with it, I'll be heavy on * the comments. * * (if you edit this definition, pay attention to trailing spaces after * each word -- I warned you! :-) ) */ #define BUILTIN_CONSTRUCTOR \ ": builtin: " \ ">in @ " /* save the tib index pointer */ \ "' " /* get next word's xt */ \ "swap >in ! " /* point again to next word */ \ "create " /* create a new definition of the next word */ \ ", " /* save previous definition's xt */ \ "immediate " /* make the new definition an immediate word */ \ \ "does> " /* Now, the *new* definition will: */ \ "state @ if " /* if in compiling state: */ \ "1 postpone literal " /* pass 1 flag to indicate compile */ \ "@ compile, " /* compile in previous definition */ \ "postpone throw " /* throw stack-returned result */ \ "else " /* if in interpreting state: */ \ "0 swap " /* pass 0 flag to indicate interpret */ \ "@ execute " /* call previous definition */ \ "throw " /* throw stack-returned result */ \ "then ; " /* * Initialise the Forth interpreter, create all our commands as words. */ void bf_init(char *rc) { struct bootblk_command **cmdp; char create_buf[41]; /* 31 characters-long builtins */ int fd, rv; ficlDictionary *dict; ficlDictionary *env; fsi = malloc(sizeof (ficlSystemInformation)); ficlSystemInformationInitialize(fsi); fsi->dictionarySize = BF_DICTSIZE; bf_sys = ficlSystemCreate(fsi); bf_vm = ficlSystemCreateVm(bf_sys); /* Put all private definitions in a "builtins" vocabulary */ rv = ficlVmEvaluate(bf_vm, "vocabulary builtins also builtins definitions"); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } /* Builtin constructor word */ rv = ficlVmEvaluate(bf_vm, BUILTIN_CONSTRUCTOR); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } /* make all commands appear as Forth words */ dict = ficlSystemGetDictionary(bf_sys); SET_FOREACH(cmdp, Xcommand_set) { ficlDictionaryAppendPrimitive(dict, (char *)(*cmdp)->c_name, bf_command, FICL_WORD_DEFAULT); rv = ficlVmEvaluate(bf_vm, "forth definitions builtins"); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } sprintf(create_buf, "builtin: %s", (*cmdp)->c_name); rv = ficlVmEvaluate(bf_vm, create_buf); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } rv = ficlVmEvaluate(bf_vm, "builtins definitions"); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } } rv = ficlVmEvaluate(bf_vm, "only forth definitions"); if (rv != FICL_VM_STATUS_OUT_OF_TEXT) { panic("error interpreting forth: %d", rv); } /* * Export some version numbers so that code can detect the loader/host * version */ env = ficlSystemGetEnvironment(bf_sys); ficlDictionarySetConstant(env, "loader_version", bootprog_rev); /* try to load and run init file if present */ if (rc == NULL) rc = "/boot/forth/boot.4th"; if (*rc != '\0') { fd = open(rc, O_RDONLY); if (fd != -1) { (void) ficlExecFD(bf_vm, fd); close(fd); } } } /* * Feed a line of user input to the Forth interpreter */ int bf_run(char *line) { int result; ficlString s; FICL_STRING_SET_FROM_CSTRING(s, line); result = ficlVmExecuteString(bf_vm, s); DPRINTF("ficlExec '%s' = %d", line, result); switch (result) { case FICL_VM_STATUS_OUT_OF_TEXT: case FICL_VM_STATUS_ABORTQ: case FICL_VM_STATUS_QUIT: case FICL_VM_STATUS_ERROR_EXIT: break; case FICL_VM_STATUS_USER_EXIT: printf("No where to leave to!\n"); break; case FICL_VM_STATUS_ABORT: printf("Aborted!\n"); break; case BF_PARSE: printf("Parse error!\n"); break; default: if (command_errmsg != NULL) { printf("%s\n", command_errmsg); command_errmsg = NULL; } } /* bye is same as reboot and will behave depending on platform */ if (result == FICL_VM_STATUS_USER_EXIT) bf_run("reboot"); setenv("interpret", bf_vm->state ? "" : "ok", 1); return (result); } /* * 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. * * Jordan K. Hubbard * 29 August 1998 * * The meat of the simple parser. */ #include #include #include #include "bootstrap.h" static void clean(void); static int insert(int *argcp, char *buf); static char *variable_lookup(char *name); #define PARSE_BUFSIZE 1024 /* maximum size of one element */ #define MAXARGS 20 /* maximum number of elements */ static char *args[MAXARGS]; /* * parse: accept a string of input and "parse" it for backslash * substitutions and environment variable expansions (${var}), * returning an argc/argv style vector of whitespace separated * arguments. Returns 0 on success, 1 on failure (ok, ok, so I * wimped-out on the error codes! :). * * Note that the argv array returned must be freed by the caller, but * we own the space allocated for arguments and will free that on next * invocation. This allows argv consumers to modify the array if * required. * * NB: environment variables that expand to more than one whitespace * separated token will be returned as a single argv[] element, not * split in turn. Expanded text is also immune to further backslash * elimination or expansion since this is a one-pass, non-recursive * parser. You didn't specify more than this so if you want more, ask * me. - jkh */ #define PARSE_FAIL(expr) \ if (expr) { \ printf("fail at line %d\n", __LINE__); \ clean(); \ free(copy); \ free(buf); \ return (1); \ } /* Accept the usual delimiters for a variable, returning counterpart */ static char isdelim(int ch) { if (ch == '{') return ('}'); else if (ch == '(') return (')'); return ('\0'); } static int isquote(int ch) { return (ch == '\''); } static int isdquote(int ch) { return (ch == '"'); } int parse(int *argc, char ***argv, char *str) { int ac; char *val, *p, *q, *copy = NULL; size_t i = 0; char token, tmp, quote, dquote, *buf; enum { STR, VAR, WHITE } state; ac = *argc = 0; dquote = quote = 0; if (!str || (p = copy = backslash(str)) == NULL) return (1); /* Initialize vector and state */ clean(); state = STR; buf = malloc(PARSE_BUFSIZE); token = 0; /* And awaaaaaaaaay we go! */ while (*p) { switch (state) { case STR: if ((*p == '\\') && p[1]) { p++; PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); buf[i++] = *p++; } else if (isquote(*p)) { quote = quote ? 0 : *p; if (dquote) { /* keep quote */ PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); buf[i++] = *p++; } else { ++p; } } else if (isdquote(*p)) { dquote = dquote ? 0 : *p; if (quote) { /* keep dquote */ PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); buf[i++] = *p++; } else { ++p; } } else if (isspace(*p) && !quote && !dquote) { state = WHITE; if (i) { buf[i] = '\0'; PARSE_FAIL(insert(&ac, buf)); i = 0; } ++p; } else if (*p == '$' && !quote) { token = isdelim(*(p + 1)); if (token) p += 2; else ++p; state = VAR; } else { PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); buf[i++] = *p++; } break; case WHITE: if (isspace(*p)) ++p; else state = STR; break; case VAR: if (token) { PARSE_FAIL((q = strchr(p, token)) == NULL); } else { q = p; while (*q && !isspace(*q)) ++q; } tmp = *q; *q = '\0'; if ((val = variable_lookup(p)) != NULL) { size_t len = strlen(val); strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1)); i += min(len, PARSE_BUFSIZE - 1); } *q = tmp; /* restore value */ p = q + (token ? 1 : 0); state = STR; break; } } /* missing terminating ' or " */ PARSE_FAIL(quote || dquote); /* If at end of token, add it */ if (i && state == STR) { buf[i] = '\0'; PARSE_FAIL(insert(&ac, buf)); } args[ac] = NULL; *argc = ac; *argv = malloc((sizeof (char *) * ac + 1)); bcopy(args, *argv, sizeof (char *) * ac + 1); free(buf); free(copy); return (0); } #define MAXARGS 20 /* Clean vector space */ static void clean(void) { int i; for (i = 0; i < MAXARGS; i++) { free(args[i]); args[i] = NULL; } } static int insert(int *argcp, char *buf) { if (*argcp >= MAXARGS) return (1); args[(*argcp)++] = strdup(buf); return (0); } static char * variable_lookup(char *name) { /* XXX search "special variable" space first? */ return (getenv(name)); } /* * Copyright (c) 1998, Michael Smith * Copyright (c) 1996, Sujal M. Patel * All rights reserved. * * 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. * * 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. */ #include /* * Machine-independant ISA PnP enumerator implementing a subset of the * ISA PnP specification. */ #include #include #include #include #define inb(x) (archsw.arch_isainb((x))) #define outb(x, y) (archsw.arch_isaoutb((x), (y))) static void isapnp_write(int d, int r); static void isapnp_send_Initiation_LFSR(void); static int isapnp_get_serial(uint8_t *p); static int isapnp_isolation_protocol(void); static void isapnp_enumerate(void); /* PnP read data port */ int isapnp_readport = 0; #define _PNP_ID_LEN 9 struct pnphandler isapnphandler = { "ISA bus", isapnp_enumerate }; static void isapnp_write(int d, int r) { outb(_PNP_ADDRESS, d); outb(_PNP_WRITE_DATA, r); } /* * Send Initiation LFSR as described in "Plug and Play ISA Specification", * Intel May 94. */ static void isapnp_send_Initiation_LFSR(void) { int cur, i; /* Reset the LSFR */ outb(_PNP_ADDRESS, 0); outb(_PNP_ADDRESS, 0); /* yes, we do need it twice! */ cur = 0x6a; outb(_PNP_ADDRESS, cur); for (i = 1; i < 32; i++) { cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff); outb(_PNP_ADDRESS, cur); } } /* * Get the device's serial number. Returns 1 if the serial is valid. */ static int isapnp_get_serial(uint8_t *data) { int i, bit, valid = 0, sum = 0x6a; bzero(data, _PNP_ID_LEN); outb(_PNP_ADDRESS, SERIAL_ISOLATION); for (i = 0; i < 72; i++) { bit = inb(isapnp_readport) == 0x55; delay(250); /* Delay 250 usec */ /* Can't Short Circuit the next evaluation, so 'and' is last */ bit = (inb(isapnp_readport) == 0xaa) && bit; delay(250); /* Delay 250 usec */ valid = valid || bit; if (i < 64) { sum = (sum >> 1) | (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff); } data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0); } valid = valid && (data[8] == sum); return (valid); } /* * Fills the buffer with resource info from the device. * Returns nonzero if the device fails to report */ static int isapnp_get_resource_info(uint8_t *buffer, int len) { int i, j; uchar_t temp; for (i = 0; i < len; i++) { outb(_PNP_ADDRESS, STATUS); for (j = 0; j < 100; j++) { if ((inb(isapnp_readport)) & 0x1) break; delay(1); } if (j == 100) { printf("PnP device failed to report resource data\n"); return (1); } outb(_PNP_ADDRESS, RESOURCE_DATA); temp = inb(isapnp_readport); if (buffer != NULL) buffer[i] = temp; } return (0); } /* * Scan Resource Data for useful information. * * We scan the resource data for compatible device IDs and * identifier strings; we only take the first identifier string * and assume it's for the card as a whole. * * Returns 0 if the scan completed OK, nonzero on error. */ static int isapnp_scan_resdata(struct pnpinfo *pi) { uchar_t tag, resinfo[8]; uint_t limit; size_t large_len; uchar_t *str; limit = 1000; while ((limit-- > 0) && !isapnp_get_resource_info(&tag, 1)) { if (PNP_RES_TYPE(tag) == 0) { /* Small resource */ switch (PNP_SRES_NUM(tag)) { case COMP_DEVICE_ID: /* Got a compatible device id resource */ if (isapnp_get_resource_info(resinfo, PNP_SRES_LEN(tag))) return (1); pnp_addident(pi, pnp_eisaformat(resinfo)); return (0); case END_TAG: return (0); default: /* Skip this resource */ if (isapnp_get_resource_info(NULL, PNP_SRES_LEN(tag))) return (1); break; } } else { /* Large resource */ if (isapnp_get_resource_info(resinfo, 2)) return (1); large_len = resinfo[1]; large_len = (large_len << 8) + resinfo[0]; switch (PNP_LRES_NUM(tag)) { case ID_STRING_ANSI: str = malloc(large_len + 1); if (isapnp_get_resource_info(str, (ssize_t)large_len)) { free(str); return (1); } str[large_len] = 0; if (pi->pi_desc == NULL) { pi->pi_desc = (char *)str; } else { free(str); } break; default: /* Large resource, skip it */ if (isapnp_get_resource_info(NULL, (ssize_t)large_len)) return (1); } } } return (1); } /* * Run the isolation protocol. Upon exiting, all cards are aware that * they should use isapnp_readport as the READ_DATA port. */ static int isapnp_isolation_protocol(void) { int csn; struct pnpinfo *pi; uint8_t cardid[_PNP_ID_LEN]; int ndevs; isapnp_send_Initiation_LFSR(); ndevs = 0; isapnp_write(CONFIG_CONTROL, 0x04); /* Reset CSN for All Cards */ for (csn = 1; ; csn++) { /* Wake up cards without a CSN (ie. all of them) */ isapnp_write(WAKE, 0); isapnp_write(SET_RD_DATA, (isapnp_readport >> 2)); outb(_PNP_ADDRESS, SERIAL_ISOLATION); delay(1000); /* Delay 1 msec */ if (isapnp_get_serial(cardid)) { isapnp_write(SET_CSN, csn); pi = pnp_allocinfo(); ndevs++; pnp_addident(pi, pnp_eisaformat(cardid)); /* * scan the card obtaining all the identifiers it holds */ if (isapnp_scan_resdata(pi)) { /* error getting data, ignore */ pnp_freeinfo(pi); } else { pnp_addinfo(pi); } } else { break; } } /* Move all cards to wait-for-key state */ while (--csn > 0) { isapnp_send_Initiation_LFSR(); isapnp_write(WAKE, csn); isapnp_write(CONFIG_CONTROL, 0x02); delay(1000); /* XXX is it really necessary ? */ csn--; } return (ndevs); } /* * Locate ISA-PnP devices and populate the supplied list. */ static void isapnp_enumerate(void) { int pnp_rd_port; /* Check for I/O port access */ if ((archsw.arch_isainb == NULL) || (archsw.arch_isaoutb == NULL)) return; /* * Validate a possibly-suggested read port value. If the autoscan failed * last time, this will return us to autoscan mode again. */ if ((isapnp_readport > 0) && (((isapnp_readport < 0x203) || (isapnp_readport > 0x3ff) || (isapnp_readport & 0x3) != 0x3))) { /* invalid, go look for ourselves */ isapnp_readport = 0; } if (isapnp_readport < 0) { /* someone is telling us there is no ISA in the system */ return; } else if (isapnp_readport > 0) { /* * Someone has told us where the port is/should be, * or we found one last time. */ isapnp_isolation_protocol(); } else { /* No clues, look for it ourselves */ for (pnp_rd_port = 0x80; pnp_rd_port < 0xff; pnp_rd_port += 0x10) { /* Look for something, quit when we find it */ isapnp_readport = (pnp_rd_port << 2) | 0x3; if (isapnp_isolation_protocol() > 0) break; } } } /* * Copyright (c) 1996, Sujal M. Patel * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Sujal M. Patel * 4. Neither the name of the author nor the names of any co-contributors * may 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 _I386_ISA_PNP_H_ #define _I386_ISA_PNP_H_ /* Maximum Number of PnP Devices. 8 should be plenty */ #define MAX_PNP_CARDS 8 /* * the following is the maximum number of PnP Logical devices that * userconfig can handle. */ #define MAX_PNP_LDN 20 /* Static ports to access PnP state machine */ #ifndef _KERNEL /* pnp.h is included from pnpinfo.c. */ #define _PNP_ADDRESS 0x279 #define _PNP_WRITE_DATA 0xa79 #endif /* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */ #define SET_RD_DATA 0x00 /*** Writing to this location modifies the address of the port used for reading from the Plug and Play ISA cards. Bits[7:0] become I/O read port address bits[9:2]. Reads from this register are ignored. ***/ #define SERIAL_ISOLATION 0x01 /*** A read to this register causes a Plug and Play cards in the Isolation state to compare one bit of the boards ID. This register is read only. ***/ #define CONFIG_CONTROL 0x02 /*** Bit[2] Reset CSN to 0 Bit[1] Return to the Wait for Key state Bit[0] Reset all logical devices and restore configuration registers to their power-up values. A write to bit[0] of this register performs a reset function on all logical devices. This resets the contents of configuration registers to their default state. All card's logical devices enter their default state and the CSN is preserved. A write to bit[1] of this register causes all cards to enter the Wait for Key state but all CSNs are preserved and logical devices are not affected. A write to bit[2] of this register causes all cards to reset their CSN to zero . This register is write-only. The values are not sticky, that is, hardware will automatically clear them and there is no need for software to clear the bits. ***/ #define WAKE 0x03 /*** A write to this port will cause all cards that have a CSN that matches the write data[7:0] to go from the Sleep state to the either the Isolation state if the write data for this command is zero or the Config state if the write data is not zero. Additionally, the pointer to the byte-serial device is reset. This register is writeonly. ***/ #define RESOURCE_DATA 0x04 /*** A read from this address reads the next byte of resource information. The Status register must be polled until bit[0] is set before this register may be read. This register is read only. ***/ #define STATUS 0x05 /*** Bit[0] when set indicates it is okay to read the next data byte from the Resource Data register. This register is readonly. ***/ #define SET_CSN 0x06 /*** A write to this port sets a card's CSN. The CSN is a value uniquely assigned to each ISA card after the serial identification process so that each card may be individually selected during a Wake[CSN] command. This register is read/write. ***/ #define SET_LDN 0x07 /*** Selects the current logical device. All reads and writes of memory, I/O, interrupt and DMA configuration information access the registers of the logical device written here. In addition, the I/O Range Check and Activate commands operate only on the selected logical device. This register is read/write. If a card has only 1 logical device, this location should be a read-only value of 0x00. ***/ /*** addresses 0x08 - 0x1F Card Level Reserved for future use ***/ /*** addresses 0x20 - 0x2F Card Level, Vendor Defined ***/ #define ACTIVATE 0x30 /*** For each logical device there is one activate register that controls whether or not the logical device is active on the ISA bus. Bit[0], if set, activates the logical device. Bits[7:1] are reserved and must return 0 on reads. This is a read/write register. Before a logical device is activated, I/O range check must be disabled. ***/ #define IO_RANGE_CHECK 0x31 /*** This register is used to perform a conflict check on the I/O port range programmed for use by a logical device. Bit[7:2] Reserved and must return 0 on reads Bit[1] Enable I/O Range check, if set then I/O Range Check is enabled. I/O range check is only valid when the logical device is inactive. Bit[0], if set, forces the logical device to respond to I/O reads of the logical device's assigned I/O range with a 0x55 when I/O range check is in operation. If clear, the logical device drives 0xAA. This register is read/write. ***/ /*** addr 0x32 - 0x37 Logical Device Control Reserved for future use ***/ /*** addr 0x38 - 0x3F Logical Device Control Vendor Define ***/ #define MEM_CONFIG 0x40 /*** Four memory resource registers per range, four ranges. Fill with 0 if no ranges are enabled. Offset 0: RW Memory base address bits[23:16] Offset 1: RW Memory base address bits[15:8] Offset 2: Memory control Bit[1] specifies 8/16-bit control. This bit is set to indicate 16-bit memory, and cleared to indicate 8-bit memory. Bit[0], if cleared, indicates the next field can be used as a range length for decode (implies range length and base alignment of memory descriptor are equal). Bit[0], if set, indicates the next field is the upper limit for the address. - - Bit[0] is read-only. Offset 3: RW upper limit or range len, bits[23:16] Offset 4: RW upper limit or range len, bits[15:8] Offset 5-Offset 7: filler, unused. ***/ #define IO_CONFIG_BASE 0x60 /*** Eight ranges, two bytes per range. Offset 0: I/O port base address bits[15:8] Offset 1: I/O port base address bits[7:0] ***/ #define IRQ_CONFIG 0x70 /*** Two entries, two bytes per entry. Offset 0: RW interrupt level (1..15, 0=unused). Offset 1: Bit[1]: level(1:hi, 0:low), Bit[0]: type (1:level, 0:edge) byte 1 can be readonly if 1 type of int is used. ***/ #define DRQ_CONFIG 0x74 /*** Two entries, one byte per entry. Bits[2:0] select which DMA channel is in use for DMA 0. Zero selects DMA channel 0, seven selects DMA channel 7. DMA channel 4, the cascade channel is used to indicate no DMA channel is active. ***/ /*** 32-bit memory accesses are at 0x76 ***/ /* Macros to parse Resource IDs */ #define PNP_RES_TYPE(a) (a >> 7) #define PNP_SRES_NUM(a) (a >> 3) #define PNP_SRES_LEN(a) (a & 0x07) #define PNP_LRES_NUM(a) (a & 0x7f) /* Small Resource Item names */ #define PNP_VERSION 0x1 #define LOG_DEVICE_ID 0x2 #define COMP_DEVICE_ID 0x3 #define IRQ_FORMAT 0x4 #define DMA_FORMAT 0x5 #define START_DEPEND_FUNC 0x6 #define END_DEPEND_FUNC 0x7 #define IO_PORT_DESC 0x8 #define FIXED_IO_PORT_DESC 0x9 #define SM_RES_RESERVED 0xa-0xd #define SM_VENDOR_DEFINED 0xe #define END_TAG 0xf /* Large Resource Item names */ #define MEMORY_RANGE_DESC 0x1 #define ID_STRING_ANSI 0x2 #define ID_STRING_UNICODE 0x3 #define LG_VENDOR_DEFINED 0x4 #define _32BIT_MEM_RANGE_DESC 0x5 #define _32BIT_FIXED_LOC_DESC 0x6 #define LG_RES_RESERVED 0x7-0x7f /* * pnp_cinfo contains Configuration Information. They are used * to communicate to the device driver the actual configuration * of the device, and also by the userconfig menu to let the * operating system override any configuration set by the bios. * */ struct pnp_cinfo { u_int vendor_id; /* board id */ u_int serial; /* Board's Serial Number */ u_long flags; /* OS-reserved flags */ u_char csn; /* assigned Card Select Number */ u_char ldn; /* Logical Device Number */ u_char enable; /* pnp enable */ u_char override; /* override bios parms (in userconfig) */ u_char irq[2]; /* IRQ Number */ u_char irq_type[2]; /* IRQ Type */ u_char drq[2]; u_short port[8]; /* The Base Address of the Port */ struct { u_long base; /* Memory Base Address */ int control; /* Memory Control Register */ u_long range; /* Memory Range *OR* Upper Limit */ } mem[4]; }; #ifdef _KERNEL struct pnp_device { char *pd_name; char * (*pd_probe ) (u_long csn, u_long vendor_id); void (*pd_attach ) (u_long csn, u_long vend_id, char * name, struct isa_device *dev); u_long *pd_count; u_int *imask ; }; struct _pnp_id { u_long vendor_id; u_long serial; u_char checksum; } ; struct pnp_dlist_node { struct pnp_device *pnp; struct isa_device dev; struct pnp_dlist_node *next; }; typedef struct _pnp_id pnp_id; extern struct pnp_dlist_node *pnp_device_list; extern pnp_id pnp_devices[MAX_PNP_CARDS]; extern struct pnp_cinfo pnp_ldn_overrides[MAX_PNP_LDN]; extern int pnp_overrides_valid; /* * these two functions are for use in drivers */ int read_pnp_parms(struct pnp_cinfo *d, int ldn); int write_pnp_parms(struct pnp_cinfo *d, int ldn); int enable_pnp_card(void); /* * used by autoconfigure to actually probe and attach drivers */ void pnp_configure(void); #endif /* _KERNEL */ #endif /* !_I386_ISA_PNP_H_ */ Copyright (c) 2010-2014, Salvatore Sanfilippo Copyright (c) 2010-2013, Pieter Noordhuis All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. linenoise linenoise_example: linenoise.h linenoise.c linenoise_example: linenoise.c example.c $(CC) -Wall -W -Os -g -o linenoise_example linenoise.c example.c clean: rm -f linenoise_example # Linenoise A minimal, zero-config, BSD licensed, readline replacement used in Redis, MongoDB, and Android. * Single and multi line editing mode with the usual key bindings implemented. * History handling. * Completion. * About 1,100 lines of BSD license source code. * Only uses a subset of VT100 escapes (ANSI.SYS compatible). ## Can a line editing library be 20k lines of code? Line editing with some support for history is a really important feature for command line utilities. Instead of retyping almost the same stuff again and again it's just much better to hit the up arrow and edit on syntax errors, or in order to try a slightly different command. But apparently code dealing with terminals is some sort of Black Magic: readline is 30k lines of code, libedit 20k. Is it reasonable to link small utilities to huge libraries just to get a minimal support for line editing? So what usually happens is either: * Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Real world example of this problem: Tclsh). * Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance). The result is a pollution of binaries without line editing support. So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to linenoise if not. ## Terminals, in 2010. Apparently almost every terminal you can happen to use today has some kind of support for basic VT100 escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it, and now can work even on ANSI.SYS compatible terminals, since no VT220 specific sequences are used anymore. The library is currently about 1100 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software. ## Tested with... * Linux text only console ($TERM = linux) * Linux KDE terminal application ($TERM = xterm) * Linux xterm ($TERM = xterm) * Linux Buildroot ($TERM = vt100) * Mac OS X iTerm ($TERM = xterm) * Mac OS X default Terminal.app ($TERM = xterm) * OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen) * IBM AIX 6.1 * FreeBSD xterm ($TERM = xterm) * ANSI.SYS Please test it everywhere you can and report back! ## Let's push this forward! Patches should be provided in the respect of linenoise sensibility for small easy to understand code. Send feedbacks to antirez at gmail #include #include #include #include "linenoise.h" void completion(const char *buf, linenoiseCompletions *lc) { if (buf[0] == 'h') { linenoiseAddCompletion(lc,"hello"); linenoiseAddCompletion(lc,"hello there"); } } int main(int argc, char **argv) { char *line; char *prgname = argv[0]; /* Parse options, with --multiline we enable multi line editing. */ while(argc > 1) { argc--; argv++; if (!strcmp(*argv,"--multiline")) { linenoiseSetMultiLine(1); printf("Multi-line mode enabled.\n"); } else if (!strcmp(*argv,"--keycodes")) { linenoisePrintKeyCodes(); exit(0); } else { fprintf(stderr, "Usage: %s [--multiline] [--keycodes]\n", prgname); exit(1); } } /* Set the completion callback. This will be called every time the * user uses the key. */ linenoiseSetCompletionCallback(completion); /* Load history from file. The history file is just a plain text file * where entries are separated by newlines. */ linenoiseHistoryLoad("history.txt"); /* Load the history at startup */ /* Now this is the main loop of the typical linenoise-based application. * The call to linenoise() will block as long as the user types something * and presses enter. * * The typed string is returned as a malloc() allocated string by * linenoise, so the user needs to free() it. */ while((line = linenoise("hello> ")) != NULL) { /* Do something with the string. */ if (line[0] != '\0' && line[0] != '/') { printf("echo: '%s'\n", line); linenoiseHistoryAdd(line); /* Add to the history. */ linenoiseHistorySave("history.txt"); /* Save the history on disk. */ } else if (!strncmp(line,"/historylen",11)) { /* The "/historylen" command will change the history len. */ int len = atoi(line+11); linenoiseHistorySetMaxLen(len); } else if (line[0] == '/') { printf("Unreconized command: %s\n", line); } free(line); } return 0; } /* linenoise.c -- VERSION 1.0 * * Guerrilla line editing library against the idea that a line editing lib * needs to be 20,000 lines of C code. * * You can find the latest source code at: * * http://github.com/antirez/linenoise * * Does a number of crazy assumptions that happen to be true in 99.9999% of * the 2010 UNIX computers around. * * ------------------------------------------------------------------------ * * Copyright (c) 2010-2014, Salvatore Sanfilippo * Copyright (c) 2010-2013, Pieter Noordhuis * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. * * ------------------------------------------------------------------------ * * References: * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html * * Todo list: * - Filter bogus Ctrl+ combinations. * - Win32 support * * Bloat: * - History search like Ctrl+r in readline? * * List of escape sequences used by this program, we do everything just * with three sequences. In order to be so cheap we may have some * flickering effect with some slow terminal, but the lesser sequences * the more compatible. * * EL (Erase Line) * Sequence: ESC [ n K * Effect: if n is 0 or missing, clear from cursor to end of line * Effect: if n is 1, clear from beginning of line to cursor * Effect: if n is 2, clear entire line * * CUF (CUrsor Forward) * Sequence: ESC [ n C * Effect: moves cursor forward n chars * * CUB (CUrsor Backward) * Sequence: ESC [ n D * Effect: moves cursor backward n chars * * The following is used to get the terminal width if getting * the width with the TIOCGWINSZ ioctl fails * * DSR (Device Status Report) * Sequence: ESC [ 6 n * Effect: reports the current cusor position as ESC [ n ; m R * where n is the row and m is the column * * When multi line mode is enabled, we also use an additional escape * sequence. However multi line editing is disabled by default. * * CUU (Cursor Up) * Sequence: ESC [ n A * Effect: moves cursor up of n chars. * * CUD (Cursor Down) * Sequence: ESC [ n B * Effect: moves cursor down of n chars. * * When linenoiseClearScreen() is called, two additional escape sequences * are used in order to clear the screen and position the cursor at home * position. * * CUP (Cursor position) * Sequence: ESC [ H * Effect: moves the cursor to upper left corner * * ED (Erase display) * Sequence: ESC [ 2 J * Effect: clear the whole screen * */ #include #include "linenoise.h" #include "bootstrap.h" #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_MAX_LINE 256 static linenoiseCompletionCallback *completionCallback = NULL; static int mlmode = 1; /* Multi line mode. Default is single line. */ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; static char **history = NULL; /* The linenoiseState structure represents the state during line editing. * We pass this state to functions implementing specific editing * functionalities. */ struct linenoiseState { char *buf; /* Edited line buffer. */ size_t buflen; /* Edited line buffer size. */ const char *prompt; /* Prompt to display. */ size_t plen; /* Prompt length. */ size_t pos; /* Current cursor position. */ size_t oldpos; /* Previous refresh cursor position. */ size_t len; /* Current edited line length. */ size_t cols; /* Number of columns in terminal. */ size_t maxrows; /* Maximum num of rows used so far (multiline mode) */ int history_index; /* The history index we are currently editing. */ }; enum KEY_ACTION{ KEY_NULL = 0, /* NULL */ CTRL_A = 1, /* Ctrl+a */ CTRL_B = 2, /* Ctrl-b */ CTRL_C = 3, /* Ctrl-c */ CTRL_D = 4, /* Ctrl-d */ CTRL_E = 5, /* Ctrl-e */ CTRL_F = 6, /* Ctrl-f */ CTRL_H = 8, /* Ctrl-h */ TAB = 9, /* Tab */ CTRL_K = 11, /* Ctrl+k */ CTRL_L = 12, /* Ctrl+l */ ENTER = 13, /* Enter */ CTRL_N = 14, /* Ctrl-n */ CTRL_P = 16, /* Ctrl-p */ CTRL_T = 20, /* Ctrl-t */ CTRL_U = 21, /* Ctrl+u */ CTRL_W = 23, /* Ctrl+w */ ESC = 27, /* Escape */ BACKSPACE = 127 /* Backspace */ }; static void refreshLine(struct linenoiseState *l); /* ======================= Low level terminal handling ====================== */ static int put_bytes(const char *s, int len) { int i; if (s == NULL) return -1; for (i = 0; i < len; i++) putchar(s[i]); return (i); } /* Set if to use or not the multi line mode. */ void linenoiseSetMultiLine(int ml) { mlmode = ml; } /* Clear the screen. Used to handle ctrl+l */ void linenoiseClearScreen(void) { if (put_bytes("\x1b[H\x1b[J", 6) <= 0) { /* nothing to do, just to avoid warning. */ } } static int getColumns(void) { char *columns = getenv("screen-#cols"); if (columns == NULL) return (80); return (strtol(columns, NULL, 0)); } /* Beep, used for completion when there is nothing to complete or when all * the choices were already shown. */ static void linenoiseBeep(void) { put_bytes("\x7", 1); } /* ============================== Completion ================================ */ /* Free a list of completion option populated by linenoiseAddCompletion(). */ static void freeCompletions(linenoiseCompletions *lc) { size_t i; for (i = 0; i < lc->len; i++) free(lc->cvec[i]); if (lc->cvec != NULL) free(lc->cvec); } /* This is an helper function for linenoiseEdit() and is called when the * user types the key in order to complete the string currently in the * input. * * The state of the editing is encapsulated into the pointed linenoiseState * structure as described in the structure definition. */ static int completeLine(struct linenoiseState *ls) { linenoiseCompletions lc = { 0, NULL }; int nwritten; char c = 0; completionCallback(ls->buf,&lc); if (lc.len == 0) { linenoiseBeep(); } else { size_t stop = 0, i = 0; while(!stop) { /* Show completion or original buffer */ if (i < lc.len) { struct linenoiseState saved = *ls; ls->len = ls->pos = strlen(lc.cvec[i]); ls->buf = lc.cvec[i]; refreshLine(ls); ls->len = saved.len; ls->pos = saved.pos; ls->buf = saved.buf; } else { refreshLine(ls); } c = getchar(); if (c <= 0) { freeCompletions(&lc); return -1; } switch(c) { case 9: /* tab */ i = (i+1) % (lc.len+1); if (i == lc.len) linenoiseBeep(); break; case 27: /* escape */ /* Re-show original buffer */ if (i < lc.len) refreshLine(ls); stop = 1; break; default: /* Update buffer and return */ if (i < lc.len) { nwritten = snprintf(ls->buf,ls->buflen,"%s",lc.cvec[i]); ls->len = ls->pos = nwritten; } stop = 1; break; } } } freeCompletions(&lc); return c; /* Return last read character */ } /* Register a callback function to be called for tab-completion. */ void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) { completionCallback = fn; } /* This function is used by the callback function registered by the user * in order to add completion options given the input string when the * user typed . See the example.c source code for a very easy to * understand example. */ void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) { size_t len = strlen(str); char *copy, **cvec; copy = malloc(len+1); if (copy == NULL) return; memcpy(copy,str,len+1); cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1)); if (cvec == NULL) { free(copy); return; } lc->cvec = cvec; lc->cvec[lc->len++] = copy; } /* =========================== Line editing ================================= */ /* We define a very simple "append buffer" structure, that is an heap * allocated string where we can append to. This is useful in order to * write all the escape sequences in a buffer and flush them to the standard * output in a single call, to avoid flickering effects. */ struct abuf { char *b; int len; }; static void abInit(struct abuf *ab) { ab->b = NULL; ab->len = 0; } static void abAppend(struct abuf *ab, const char *s, int len) { char *new = malloc(ab->len+len); if (new == NULL) return; memcpy(new, ab->b, ab->len); memcpy(new+ab->len,s,len); free(ab->b); ab->b = new; ab->len += len; } static void abFree(struct abuf *ab) { free(ab->b); } /* Single line low level line refresh. * * Rewrite the currently edited line accordingly to the buffer content, * cursor position, and number of columns of the terminal. */ static void refreshSingleLine(struct linenoiseState *l) { char seq[64]; size_t plen = strlen(l->prompt); char *buf = l->buf; size_t len = l->len; size_t pos = l->pos; struct abuf ab; while((plen+pos) >= l->cols) { buf++; len--; pos--; } while (plen+len > l->cols) { len--; } abInit(&ab); /* Cursor to left edge */ snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); /* Write the prompt and the current buffer content */ abAppend(&ab,l->prompt,strlen(l->prompt)); abAppend(&ab,buf,len); /* Erase to right */ snprintf(seq,64,"\x1b[K"); abAppend(&ab,seq,strlen(seq)); /* Move cursor to original position. */ snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen)); abAppend(&ab,seq,strlen(seq)); put_bytes(ab.b, ab.len); abFree(&ab); } /* Multi line low level line refresh. * * Rewrite the currently edited line accordingly to the buffer content, * cursor position, and number of columns of the terminal. */ static void refreshMultiLine(struct linenoiseState *l) { char seq[64]; int plen = strlen(l->prompt); int rows = (plen+l->len+l->cols)/l->cols; /* rows used by current buf. */ int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */ int rpos2; /* rpos after refresh. */ int col; /* colum position, zero-based. */ int old_rows = l->maxrows; int j; struct abuf ab; /* Update maxrows if needed. */ if (rows > (int)l->maxrows) l->maxrows = rows; /* First step: clear all the lines used before. To do so start by * going to the last row. */ abInit(&ab); if (old_rows-rpos > 0) { snprintf(seq,64,"\x1b[%dB", old_rows-rpos); abAppend(&ab,seq,strlen(seq)); } /* Now for every row clear it, go up. */ for (j = 0; j < old_rows-1; j++) { snprintf(seq,64,"\r\x1b[0K\x1b[1A"); abAppend(&ab,seq,strlen(seq)); } /* Clean the top line. */ snprintf(seq,64,"\r\x1b[0K"); abAppend(&ab,seq,strlen(seq)); /* Write the prompt and the current buffer content */ abAppend(&ab,l->prompt,strlen(l->prompt)); abAppend(&ab,l->buf,l->len); /* If we are at the very end of the screen with our prompt, we need to * emit a newline and move the prompt to the first column. */ if (l->pos && l->pos == l->len && (l->pos+plen) % l->cols == 0) { abAppend(&ab,"\n",1); snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); rows++; if (rows > (int)l->maxrows) l->maxrows = rows; } /* Move cursor to right position. */ rpos2 = (plen+l->pos+l->cols)/l->cols; /* current cursor relative row. */ /* Go up till we reach the expected positon. */ if (rows-rpos2 > 0) { snprintf(seq,64,"\x1b[%dA", rows-rpos2); abAppend(&ab,seq,strlen(seq)); } /* Set column. */ col = (plen+(int)l->pos) % (int)l->cols; if (col) snprintf(seq,64,"\r\x1b[%dC", col); else snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); l->oldpos = l->pos; put_bytes(ab.b, ab.len); abFree(&ab); } /* Calls the two low level functions refreshSingleLine() or * refreshMultiLine() according to the selected mode. */ static void refreshLine(struct linenoiseState *l) { if (mlmode) refreshMultiLine(l); else refreshSingleLine(l); } /* Insert the character 'c' at cursor current position. * * On error writing to the terminal -1 is returned, otherwise 0. */ static int linenoiseEditInsert(struct linenoiseState *l, char c) { if (l->len < l->buflen) { if (l->len == l->pos) { l->buf[l->pos] = c; l->pos++; l->len++; l->buf[l->len] = '\0'; if ((!mlmode && l->plen+l->len < l->cols) /* || mlmode */) { /* Avoid a full update of the line in the * trivial case. */ putchar(c); } else { refreshLine(l); } } else { memmove(l->buf+l->pos+1,l->buf+l->pos,l->len-l->pos); l->buf[l->pos] = c; l->len++; l->pos++; l->buf[l->len] = '\0'; refreshLine(l); } } return 0; } /* Move cursor on the left. */ static void linenoiseEditMoveLeft(struct linenoiseState *l) { if (l->pos > 0) { l->pos--; refreshLine(l); } } /* Move cursor on the right. */ static void linenoiseEditMoveRight(struct linenoiseState *l) { if (l->pos != l->len) { l->pos++; refreshLine(l); } } /* Move cursor to the start of the line. */ static void linenoiseEditMoveHome(struct linenoiseState *l) { if (l->pos != 0) { l->pos = 0; refreshLine(l); } } /* Move cursor to the end of the line. */ static void linenoiseEditMoveEnd(struct linenoiseState *l) { if (l->pos != l->len) { l->pos = l->len; refreshLine(l); } } /* Substitute the currently edited line with the next or previous history * entry as specified by 'dir'. */ #define LINENOISE_HISTORY_NEXT 0 #define LINENOISE_HISTORY_PREV 1 static void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) { if (history_len > 1) { /* Update the current history entry before to * overwrite it with the next one. */ free(history[history_len - 1 - l->history_index]); history[history_len - 1 - l->history_index] = strdup(l->buf); /* Show the new entry */ l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1; if (l->history_index < 0) { l->history_index = 0; return; } else if (l->history_index >= history_len) { l->history_index = history_len-1; return; } strncpy(l->buf,history[history_len - 1 - l->history_index],l->buflen); l->buf[l->buflen-1] = '\0'; l->len = l->pos = strlen(l->buf); refreshLine(l); } } /* Delete the character at the right of the cursor without altering the cursor * position. Basically this is what happens with the "Delete" keyboard key. */ static void linenoiseEditDelete(struct linenoiseState *l) { if (l->len > 0 && l->pos < l->len) { memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1); l->len--; l->buf[l->len] = '\0'; refreshLine(l); } } /* Backspace implementation. */ static void linenoiseEditBackspace(struct linenoiseState *l) { if (l->pos > 0 && l->len > 0) { memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos); l->pos--; l->len--; l->buf[l->len] = '\0'; refreshLine(l); } } /* Delete the previosu word, maintaining the cursor at the start of the * current word. */ static void linenoiseEditDeletePrevWord(struct linenoiseState *l) { size_t old_pos = l->pos; size_t diff; while (l->pos > 0 && l->buf[l->pos-1] == ' ') l->pos--; while (l->pos > 0 && l->buf[l->pos-1] != ' ') l->pos--; diff = old_pos - l->pos; memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1); l->len -= diff; refreshLine(l); } /* This function is the core of the line editing capability of linenoise. * It expects 'fd' to be already in "raw mode" so that every key pressed * will be returned ASAP to read(). * * The resulting string is put into 'buf' when the user type enter, or * when ctrl+d is typed. * * The function returns the length of the current buffer. */ static int linenoiseEdit(char *buf, size_t buflen, const char *prompt) { struct linenoiseState l; /* Populate the linenoise state that we pass to functions implementing * specific editing functionalities. */ l.buf = buf; l.buflen = buflen; l.prompt = prompt; l.plen = strlen(prompt); l.oldpos = l.pos = 0; l.len = 0; l.cols = getColumns(); l.maxrows = 0; l.history_index = 0; /* Buffer starts empty. */ l.buf[0] = '\0'; l.buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); printf ("%s", prompt); while(1) { char c; char seq[3]; c = getchar(); if (c == -1) continue; /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == 9 && completionCallback != NULL) { c = completeLine(&l); /* Return on errors */ if (c < 0) return l.len; /* Read next character when 0 */ if (c == 0) continue; } switch(c) { case ENTER: /* enter */ history_len--; free(history[history_len]); if (mlmode) linenoiseEditMoveEnd(&l); return (int)l.len; case CTRL_C: /* ctrl-c */ buf[0] = '\0'; l.pos = l.len = 0; refreshLine(&l); break; case BACKSPACE: /* backspace */ case 8: /* ctrl-h */ linenoiseEditBackspace(&l); break; case CTRL_D: /* ctrl-d, remove char at right of cursor. */ if (l.len > 0) { linenoiseEditDelete(&l); } break; case CTRL_T: /* ctrl-t, swaps current character with previous. */ if (l.pos > 0 && l.pos < l.len) { int aux = buf[l.pos-1]; buf[l.pos-1] = buf[l.pos]; buf[l.pos] = aux; if (l.pos != l.len-1) l.pos++; refreshLine(&l); } break; case CTRL_B: /* ctrl-b */ linenoiseEditMoveLeft(&l); break; case CTRL_F: /* ctrl-f */ linenoiseEditMoveRight(&l); break; case CTRL_P: /* ctrl-p */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); break; case CTRL_N: /* ctrl-n */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); break; case ESC: /* escape sequence */ /* Read the next two bytes representing the escape sequence. * Use two calls to handle slow terminals returning the two * chars at different times. */ seq[0] = getchar(); seq[1] = getchar(); /* ESC [ sequences. */ if (seq[0] == '[') { if (seq[1] >= '0' && seq[1] <= '9') { /* Extended escape, read additional byte. */ seq[2] = getchar(); if (seq[2] == '~') { switch(seq[1]) { case '3': /* Delete key. */ linenoiseEditDelete(&l); break; } } } else { switch(seq[1]) { case 'A': /* Up */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); break; case 'B': /* Down */ linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); break; case 'C': /* Right */ linenoiseEditMoveRight(&l); break; case 'D': /* Left */ linenoiseEditMoveLeft(&l); break; case 'H': /* Home */ linenoiseEditMoveHome(&l); break; case 'F': /* End*/ linenoiseEditMoveEnd(&l); break; } } } /* ESC O sequences. */ else if (seq[0] == 'O') { switch(seq[1]) { case 'H': /* Home */ linenoiseEditMoveHome(&l); break; case 'F': /* End*/ linenoiseEditMoveEnd(&l); break; } } break; default: if (linenoiseEditInsert(&l,c)) return -1; break; case CTRL_U: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; l.pos = l.len = 0; refreshLine(&l); break; case CTRL_K: /* Ctrl+k, delete from current to end of line. */ buf[l.pos] = '\0'; l.len = l.pos; refreshLine(&l); break; case CTRL_A: /* Ctrl+a, go to the start of the line */ linenoiseEditMoveHome(&l); break; case CTRL_E: /* ctrl+e, go to the end of the line */ linenoiseEditMoveEnd(&l); break; case CTRL_L: /* ctrl+l, clear screen */ linenoiseClearScreen(); refreshLine(&l); break; case CTRL_W: /* ctrl+w, delete previous word */ linenoiseEditDeletePrevWord(&l); break; } } return l.len; } /* The high level function that is the main API of the linenoise library. * This function checks if the terminal has basic capabilities, just checking * for a blacklist of stupid terminals, and later either calls the line * editing function or uses dummy fgets() so that you will be able to type * something even in the most desperate of the conditions. */ char *linenoise(const char *prompt) { char buf[LINENOISE_MAX_LINE]; int count; cons_mode(C_MODERAW); count = linenoiseEdit(buf,LINENOISE_MAX_LINE,prompt); cons_mode(0); printf("\n"); if (count == -1) return NULL; return strdup(buf); } /* ================================ History ================================= */ /* This is the API call to add a new entry in the linenoise history. * It uses a fixed array of char pointers that are shifted (memmoved) * when the history max length is reached in order to remove the older * entry and make room for the new one, so it is not exactly suitable for huge * histories, but will work well for a few hundred of entries. * * Using a circular buffer is smarter, but a bit more complex to handle. */ int linenoiseHistoryAdd(const char *line) { char *linecopy; if (history_max_len == 0) return 0; /* Initialization on first call. */ if (history == NULL) { history = malloc(sizeof(char*)*history_max_len); if (history == NULL) return 0; memset(history,0,(sizeof(char*)*history_max_len)); } /* Don't add duplicated lines. */ if (history_len && !strcmp(history[history_len-1], line)) return 0; /* Add an heap allocated copy of the line in the history. * If we reached the max length, remove the older line. */ linecopy = strdup(line); if (!linecopy) return 0; if (history_len == history_max_len) { free(history[0]); memmove(history,history+1,sizeof(char*)*(history_max_len-1)); history_len--; } history[history_len] = linecopy; history_len++; return 1; } /* Set the maximum length for the history. This function can be called even * if there is already some history, the function will make sure to retain * just the latest 'len' elements if the new history length value is smaller * than the amount of items already inside the history. */ int linenoiseHistorySetMaxLen(int len) { char **new; if (len < 1) return 0; if (history) { int tocopy = history_len; new = malloc(sizeof(char*)*len); if (new == NULL) return 0; /* If we can't copy everything, free the elements we'll not use. */ if (len < tocopy) { int j; for (j = 0; j < tocopy-len; j++) free(history[j]); tocopy = len; } memset(new,0,sizeof(char*)*len); memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy); free(history); history = new; } history_max_len = len; if (history_len > history_max_len) history_len = history_max_len; return 1; } /* linenoise.h -- VERSION 1.0 * * Guerrilla line editing library against the idea that a line editing lib * needs to be 20,000 lines of C code. * * See linenoise.c for more information. * * ------------------------------------------------------------------------ * * Copyright (c) 2010-2014, Salvatore Sanfilippo * Copyright (c) 2010-2013, Pieter Noordhuis * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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 __LINENOISE_H #define __LINENOISE_H #ifdef __cplusplus extern "C" { #endif typedef struct linenoiseCompletions { size_t len; char **cvec; } linenoiseCompletions; typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); void linenoiseAddCompletion(linenoiseCompletions *, const char *); char *linenoise(const char *prompt); int linenoiseHistoryAdd(const char *line); int linenoiseHistorySetMaxLen(int len); int linenoiseHistorySave(const char *filename); int linenoiseHistoryLoad(const char *filename); void linenoiseClearScreen(void); void linenoiseSetMultiLine(int ml); void linenoisePrintKeyCodes(void); #ifdef __cplusplus } #endif #endif /* __LINENOISE_H */ /* * Copyright (c) 1998 Michael Smith * Copyright (c) 1998 Peter Wemm * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #define FREEBSD_ELF #include #include "bootstrap.h" #define COPYOUT(s, d, l) archsw.arch_copyout((vm_offset_t)(s), d, l) #if defined(__i386__) && __ELF_WORD_SIZE == 64 #undef ELF_TARG_CLASS #undef ELF_TARG_MACH #define ELF_TARG_CLASS ELFCLASS64 #define ELF_TARG_MACH EM_X86_64 #endif typedef struct elf_file { Elf_Phdr *ph; Elf_Ehdr *ehdr; Elf_Sym *symtab; Elf_Hashelt *hashtab; Elf_Hashelt nbuckets; Elf_Hashelt nchains; Elf_Hashelt *buckets; Elf_Hashelt *chains; Elf_Rel *rel; size_t relsz; Elf_Rela *rela; size_t relasz; char *strtab; size_t strsz; int fd; caddr_t firstpage; size_t firstlen; int kernel; uint64_t off; } *elf_file_t; static int __elfN(loadimage)(struct preloaded_file *, elf_file_t, uint64_t); static int __elfN(lookup_symbol)(struct preloaded_file *, elf_file_t, const char *, Elf_Sym *); static int __elfN(reloc_ptr)(struct preloaded_file *, elf_file_t, Elf_Addr, void *, size_t); static int __elfN(parse_modmetadata)(struct preloaded_file *, elf_file_t, Elf_Addr, Elf_Addr); static symaddr_fn __elfN(symaddr); static char *fake_modname(const char *); const char *__elfN(kerneltype) = "elf kernel"; const char *__elfN(moduletype) = "elf module"; uint64_t __elfN(relocation_offset) = 0; static int __elfN(load_elf_header)(char *filename, elf_file_t ef) { ssize_t bytes_read; Elf_Ehdr *ehdr; int err; /* * Open the image, read and validate the ELF header */ if (filename == NULL) /* can't handle nameless */ return (EFTYPE); if ((ef->fd = open(filename, O_RDONLY)) == -1) return (errno); ef->firstpage = malloc(PAGE_SIZE); if (ef->firstpage == NULL) { close(ef->fd); return (ENOMEM); } bytes_read = read(ef->fd, ef->firstpage, PAGE_SIZE); ef->firstlen = (size_t)bytes_read; if (bytes_read < 0 || ef->firstlen <= sizeof (Elf_Ehdr)) { err = EFTYPE; /* could be EIO, but may be small file */ goto error; } ehdr = ef->ehdr = (Elf_Ehdr *)ef->firstpage; /* Is it ELF? */ if (!IS_ELF(*ehdr)) { err = EFTYPE; goto error; } if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || ehdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */ ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */ err = EFTYPE; goto error; } return (0); error: if (ef->firstpage != NULL) { free(ef->firstpage); ef->firstpage = NULL; } if (ef->fd != -1) { close(ef->fd); ef->fd = -1; } return (err); } /* * Attempt to load the file (file) as an ELF module. It will be stored at * (dest), and a pointer to a module structure describing the loaded object * will be saved in (result). */ int __elfN(loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) { return (__elfN(loadfile_raw)(filename, dest, result, 0)); } int __elfN(loadfile_raw)(char *filename, uint64_t dest, struct preloaded_file **result, int multiboot) { struct preloaded_file *fp, *kfp; struct elf_file ef; Elf_Ehdr *ehdr; int err; fp = NULL; bzero(&ef, sizeof (struct elf_file)); ef.fd = -1; err = __elfN(load_elf_header)(filename, &ef); if (err != 0) return (err); ehdr = ef.ehdr; /* * Check to see what sort of module we are. */ kfp = file_findfile(NULL, __elfN(kerneltype)); #ifdef __powerpc__ /* * Kernels can be ET_DYN, so just assume the first loaded object is the * kernel. This assumption will be checked later. */ if (kfp == NULL) ef.kernel = 1; #endif if (ef.kernel || ehdr->e_type == ET_EXEC) { /* Looks like a kernel */ if (kfp != NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); err = EPERM; goto oerr; } /* * Calculate destination address based on kernel entrypoint. * * For ARM, the destination address is independent of any * values in the elf header (an ARM kernel can be loaded at * any 2MB boundary), so we leave dest set to the value * calculated by archsw.arch_loadaddr() and passed in to * this function. */ #ifndef __arm__ if (ehdr->e_type == ET_EXEC) dest = (ehdr->e_entry & ~PAGE_MASK); #endif if ((ehdr->e_entry & ~PAGE_MASK) == 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); err = EPERM; goto oerr; } ef.kernel = 1; } else if (ehdr->e_type == ET_DYN) { /* Looks like a kld module */ if (multiboot != 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n"); err = EPERM; goto oerr; } if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } if (strcmp(__elfN(kerneltype), kfp->f_type)) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with " "kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } /* Looks OK, got ahead */ ef.kernel = 0; } else { err = EFTYPE; goto oerr; } if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); else dest = roundup(dest, PAGE_SIZE); /* * Ok, we think we should handle this. */ fp = file_alloc(); if (fp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } if (ef.kernel == 1 && multiboot == 0) setenv("kernelname", filename, 1); fp->f_name = strdup(filename); if (multiboot == 0) { fp->f_type = strdup(ef.kernel ? __elfN(kerneltype) : __elfN(moduletype)); } else { if (multiboot == 1) fp->f_type = strdup("elf multiboot kernel"); else fp->f_type = strdup("elf multiboot2 kernel"); } #ifdef ELF_VERBOSE if (ef.kernel) printf("%s entry at 0x%jx\n", filename, (uintmax_t)ehdr->e_entry); #else printf("%s ", filename); #endif fp->f_size = __elfN(loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof (*ehdr), ehdr); /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: file_discard(fp); out: if (ef.firstpage) free(ef.firstpage); if (ef.fd != -1) close(ef.fd); return (err); } /* * With the file (fd) open on the image, and (ehdr) containing * the Elf header, load the image at (off) */ static int __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off) { int i; uint_t j; Elf_Ehdr *ehdr; Elf_Phdr *phdr, *php; Elf_Shdr *shdr; char *shstr; int ret; vm_offset_t firstaddr; vm_offset_t lastaddr; size_t chunk; ssize_t result; Elf_Addr ssym, esym; Elf_Dyn *dp; Elf_Addr adp; Elf_Addr ctors; int ndp; int symstrindex; int symtabindex; Elf_Size size; uint_t fpcopy; Elf_Sym sym; Elf_Addr p_start, p_end; dp = NULL; shdr = NULL; ret = 0; firstaddr = lastaddr = 0; ehdr = ef->ehdr; if (ehdr->e_type == ET_EXEC) { #if defined(__i386__) || defined(__amd64__) #if __ELF_WORD_SIZE == 64 /* x86_64 relocates after locore */ off = - (off & 0xffffffffff000000ull); #else /* i386 relocates after locore */ off = - (off & 0xff000000u); #endif #elif defined(__powerpc__) /* * On the purely virtual memory machines like e500, the kernel * is linked against its final VA range, which is most often * not available at the loader stage, but only after kernel * initializes and completes its VM settings. In such cases * we cannot use p_vaddr field directly to load ELF segments, * but put them at some 'load-time' locations. */ if (off & 0xf0000000u) { off = -(off & 0xf0000000u); /* * XXX the physical load address should not be * hardcoded. Note that the Book-E kernel assumes * that it's loaded at a 16MB boundary for now... */ off += 0x01000000; ehdr->e_entry += off; #ifdef ELF_VERBOSE printf("Converted entry 0x%08x\n", ehdr->e_entry); #endif } else { off = 0; } #elif defined(__arm__) && !defined(EFI) /* * The elf headers in arm kernels specify virtual addresses * in all header fields, even the ones that should be physical * addresses. * We assume the entry point is in the first page, and masking * the page offset will leave us with the virtual address the * kernel was linked at. We subtract that from the load offset, * making 'off' into the value which, when added to a virtual * address in an elf header, translates it to a physical * address. We do the va->pa conversion on the entry point * address in the header now, so that later we can * launch the kernel by just jumping to that address. * * When booting from UEFI the copyin and copyout functions * handle adjusting the location relative to the first virtual * address. Because of this there is no need to adjust the * offset or entry point address as these will both be handled * by the efi code. */ off -= ehdr->e_entry & ~PAGE_MASK; ehdr->e_entry += off; #ifdef ELF_VERBOSE printf("ehdr->e_entry 0x%08x, va<->pa off %llx\n", ehdr->e_entry, off); #endif #else off = 0; /* other archs use direct mapped kernels */ #endif } ef->off = off; if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { /* use entry address from header */ fp->f_addr = ehdr->e_entry; } if (ef->kernel) __elfN(relocation_offset) = off; if ((ehdr->e_phoff + ehdr->e_phnum * sizeof (*phdr)) > ef->firstlen) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: program header not within first page\n"); goto out; } phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { /* We want to load PT_LOAD segments only.. */ if (phdr[i].p_type != PT_LOAD) continue; #ifdef ELF_VERBOSE if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", (long)phdr[i].p_filesz, (long)phdr[i].p_offset, (long)(phdr[i].p_paddr + off), (long)(phdr[i].p_paddr + off + phdr[i].p_memsz - 1)); } else { printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx", (long)phdr[i].p_filesz, (long)phdr[i].p_offset, (long)(phdr[i].p_vaddr + off), (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); } #else if ((phdr[i].p_flags & PF_W) == 0) { printf("text=0x%lx ", (long)phdr[i].p_filesz); } else { printf("data=0x%lx", (long)phdr[i].p_filesz); if (phdr[i].p_filesz < phdr[i].p_memsz) printf("+0x%lx", (long)(phdr[i].p_memsz -phdr[i].p_filesz)); printf(" "); } #endif fpcopy = 0; if (ef->firstlen > phdr[i].p_offset) { fpcopy = ef->firstlen - phdr[i].p_offset; if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, phdr[i].p_paddr + off, fpcopy); } else { archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, phdr[i].p_vaddr + off, fpcopy); } } if (phdr[i].p_filesz > fpcopy) { if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { if (kern_pread(ef->fd, phdr[i].p_paddr + off + fpcopy, phdr[i].p_filesz - fpcopy, phdr[i].p_offset + fpcopy) != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: read failed\n"); goto out; } } else { if (kern_pread(ef->fd, phdr[i].p_vaddr + off + fpcopy, phdr[i].p_filesz - fpcopy, phdr[i].p_offset + fpcopy) != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: read failed\n"); goto out; } } } /* clear space from oversized segments; eg: bss */ if (phdr[i].p_filesz < phdr[i].p_memsz) { #ifdef ELF_VERBOSE if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { printf(" (bss: 0x%lx-0x%lx)", (long)(phdr[i].p_paddr + off + phdr[i].p_filesz), (long)(phdr[i].p_paddr + off + phdr[i].p_memsz - 1)); } else { printf(" (bss: 0x%lx-0x%lx)", (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz), (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1)); } #endif if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { kern_bzero(phdr[i].p_paddr + off + phdr[i].p_filesz, phdr[i].p_memsz - phdr[i].p_filesz); } else { kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz, phdr[i].p_memsz - phdr[i].p_filesz); } } #ifdef ELF_VERBOSE printf("\n"); #endif if (archsw.arch_loadseg != NULL) archsw.arch_loadseg(ehdr, phdr + i, off); if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) { if (firstaddr == 0 || firstaddr > (phdr[i].p_paddr + off)) firstaddr = phdr[i].p_paddr + off; if (lastaddr == 0 || lastaddr < (phdr[i].p_paddr + off + phdr[i].p_memsz)) lastaddr = phdr[i].p_paddr + off + phdr[i].p_memsz; } else { if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off)) firstaddr = phdr[i].p_vaddr + off; if (lastaddr == 0 || lastaddr < (phdr[i].p_vaddr + off + phdr[i].p_memsz)) lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz; } } lastaddr = roundup(lastaddr, sizeof (long)); /* * Get the section headers. We need this for finding the .ctors * section as well as for loading any symbols. Both may be hard * to do if reading from a .gz file as it involves seeking. I * think the rule is going to have to be that you must strip a * file to remove symbols before gzipping it. */ chunk = ehdr->e_shnum * ehdr->e_shentsize; if (chunk == 0 || ehdr->e_shoff == 0) goto nosyms; shdr = alloc_pread(ef->fd, ehdr->e_shoff, chunk); if (shdr == NULL) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: failed to read section headers"); goto nosyms; } file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); /* * Read the section string table and look for the .ctors section. * We need to tell the kernel where it is so that it can call the * ctors. */ chunk = shdr[ehdr->e_shstrndx].sh_size; if (chunk) { shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, chunk); if (shstr) { for (i = 0; i < ehdr->e_shnum; i++) { if (strcmp(shstr + shdr[i].sh_name, ".ctors") != 0) continue; ctors = shdr[i].sh_addr; file_addmetadata(fp, MODINFOMD_CTORS_ADDR, sizeof (ctors), &ctors); size = shdr[i].sh_size; file_addmetadata(fp, MODINFOMD_CTORS_SIZE, sizeof (size), &size); break; } free(shstr); } } /* * Now load any symbols. */ symtabindex = -1; symstrindex = -1; for (i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_type != SHT_SYMTAB) continue; for (j = 0; j < ehdr->e_phnum; j++) { if (phdr[j].p_type != PT_LOAD) continue; if (shdr[i].sh_offset >= phdr[j].p_offset && (shdr[i].sh_offset + shdr[i].sh_size <= phdr[j].p_offset + phdr[j].p_filesz)) { shdr[i].sh_offset = 0; shdr[i].sh_size = 0; break; } } if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0) continue; /* alread loaded in a PT_LOAD above */ /* Save it for loading below */ symtabindex = i; symstrindex = shdr[i].sh_link; } if (symtabindex < 0 || symstrindex < 0) goto nosyms; /* Ok, committed to a load. */ #ifndef ELF_VERBOSE printf("syms=["); #endif ssym = lastaddr; for (i = symtabindex; i >= 0; i = symstrindex) { #ifdef ELF_VERBOSE char *secname; switch (shdr[i].sh_type) { case SHT_SYMTAB: /* Symbol table */ secname = "symtab"; break; case SHT_STRTAB: /* String table */ secname = "strtab"; break; default: secname = "WHOA!!"; break; } #endif size = shdr[i].sh_size; archsw.arch_copyin(&size, lastaddr, sizeof (size)); lastaddr += sizeof (size); #ifdef ELF_VERBOSE printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname, (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset, (uintmax_t)lastaddr, (uintmax_t)(lastaddr + shdr[i].sh_size)); #else if (i == symstrindex) printf("+"); printf("0x%lx+0x%lx", (long)sizeof (size), (long)size); #endif if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage:" " could not seek for symbols - skipped!"); lastaddr = ssym; ssym = 0; goto nosyms; } result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); if (result < 0 || (size_t)result != shdr[i].sh_size) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: " "could not read symbols - skipped! (%ju != %ju)", (uintmax_t)result, (uintmax_t)shdr[i].sh_size); lastaddr = ssym; ssym = 0; goto nosyms; } /* Reset offsets relative to ssym */ lastaddr += shdr[i].sh_size; lastaddr = roundup(lastaddr, sizeof (size)); if (i == symtabindex) symtabindex = -1; else if (i == symstrindex) symstrindex = -1; } esym = lastaddr; #ifndef ELF_VERBOSE printf("]"); #endif file_addmetadata(fp, MODINFOMD_SSYM, sizeof (ssym), &ssym); file_addmetadata(fp, MODINFOMD_ESYM, sizeof (esym), &esym); nosyms: printf("\n"); ret = lastaddr - firstaddr; if (ehdr->e_ident[EI_OSABI] != ELFOSABI_SOLARIS) fp->f_addr = firstaddr; php = NULL; for (i = 0; i < ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_DYNAMIC) { php = phdr + i; adp = php->p_vaddr; file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof (adp), &adp); break; } } if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ goto out; ndp = php->p_filesz / sizeof (Elf_Dyn); if (ndp == 0) goto out; dp = malloc(php->p_filesz); if (dp == NULL) goto out; if (ehdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) archsw.arch_copyout(php->p_paddr + off, dp, php->p_filesz); else archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); ef->strsz = 0; for (i = 0; i < ndp; i++) { if (dp[i].d_tag == 0) break; switch (dp[i].d_tag) { case DT_HASH: ef->hashtab = (Elf_Hashelt*)(uintptr_t) (dp[i].d_un.d_ptr + off); break; case DT_STRTAB: ef->strtab = (char *)(uintptr_t) (dp[i].d_un.d_ptr + off); break; case DT_STRSZ: ef->strsz = dp[i].d_un.d_val; break; case DT_SYMTAB: ef->symtab = (Elf_Sym*)(uintptr_t) (dp[i].d_un.d_ptr + off); break; case DT_REL: ef->rel = (Elf_Rel *)(uintptr_t) (dp[i].d_un.d_ptr + off); break; case DT_RELSZ: ef->relsz = dp[i].d_un.d_val; break; case DT_RELA: ef->rela = (Elf_Rela *)(uintptr_t) (dp[i].d_un.d_ptr + off); break; case DT_RELASZ: ef->relasz = dp[i].d_un.d_val; break; default: break; } } if (ef->hashtab == NULL || ef->symtab == NULL || ef->strtab == NULL || ef->strsz == 0) goto out; COPYOUT(ef->hashtab, &ef->nbuckets, sizeof (ef->nbuckets)); COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof (ef->nchains)); ef->buckets = ef->hashtab + 2; ef->chains = ef->buckets + ef->nbuckets; if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0) return (0); p_start = sym.st_value + ef->off; if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) return (ENOENT); p_end = sym.st_value + ef->off; if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0) goto out; if (ef->kernel) /* kernel must not depend on anything */ goto out; out: free(dp); free(shdr); return (ret); } static char invalid_name[] = "bad"; char * fake_modname(const char *name) { const char *sp, *ep; char *fp; size_t len; sp = strrchr(name, '/'); if (sp) sp++; else sp = name; ep = strrchr(name, '.'); if (ep) { if (ep == name) { sp = invalid_name; ep = invalid_name + sizeof (invalid_name) - 1; } } else { ep = name + strlen(name); } len = ep - sp; fp = malloc(len + 1); if (fp == NULL) return (NULL); memcpy(fp, sp, len); fp[len] = '\0'; return (fp); } #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 struct mod_metadata64 { int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ uint64_t md_data; /* specific data */ uint64_t md_cval; /* common string label */ }; #endif #if defined(__amd64__) && __ELF_WORD_SIZE == 32 struct mod_metadata32 { int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ uint32_t md_data; /* specific data */ uint32_t md_cval; /* common string label */ }; #endif int __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest) { struct elf_file ef; int err, i, j; Elf_Shdr *sh_meta, *shdr = NULL; Elf_Shdr *sh_data[2]; char *shstrtab = NULL; size_t size; Elf_Addr p_start, p_end; bzero(&ef, sizeof (struct elf_file)); ef.fd = -1; err = __elfN(load_elf_header)(fp->f_name, &ef); if (err != 0) goto out; if (ef.kernel == 1 || ef.ehdr->e_type == ET_EXEC) { ef.kernel = 1; } else if (ef.ehdr->e_type != ET_DYN) { err = EFTYPE; goto out; } size = ef.ehdr->e_shnum * ef.ehdr->e_shentsize; shdr = alloc_pread(ef.fd, ef.ehdr->e_shoff, size); if (shdr == NULL) { err = ENOMEM; goto out; } /* Load shstrtab. */ shstrtab = alloc_pread(ef.fd, shdr[ef.ehdr->e_shstrndx].sh_offset, shdr[ef.ehdr->e_shstrndx].sh_size); if (shstrtab == NULL) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: unable to load shstrtab\n"); err = EFTYPE; goto out; } /* Find set_modmetadata_set and data sections. */ sh_data[0] = sh_data[1] = sh_meta = NULL; for (i = 0, j = 0; i < ef.ehdr->e_shnum; i++) { if (strcmp(&shstrtab[shdr[i].sh_name], "set_modmetadata_set") == 0) { sh_meta = &shdr[i]; } if ((strcmp(&shstrtab[shdr[i].sh_name], ".data") == 0) || (strcmp(&shstrtab[shdr[i].sh_name], ".rodata") == 0)) { sh_data[j++] = &shdr[i]; } } if (sh_meta == NULL || sh_data[0] == NULL || sh_data[1] == NULL) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: " "unable to find set_modmetadata_set or data sections\n"); err = EFTYPE; goto out; } /* Load set_modmetadata_set into memory */ err = kern_pread(ef.fd, dest, sh_meta->sh_size, sh_meta->sh_offset); if (err != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: " "unable to load set_modmetadata_set: %d\n", err); goto out; } p_start = dest; p_end = dest + sh_meta->sh_size; dest += sh_meta->sh_size; /* Load data sections into memory. */ err = kern_pread(ef.fd, dest, sh_data[0]->sh_size, sh_data[0]->sh_offset); if (err != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: unable to load data: %d\n", err); goto out; } /* * We have to increment the dest, so that the offset is the same into * both the .rodata and .data sections. */ ef.off = -(sh_data[0]->sh_addr - dest); dest += (sh_data[1]->sh_addr - sh_data[0]->sh_addr); err = kern_pread(ef.fd, dest, sh_data[1]->sh_size, sh_data[1]->sh_offset); if (err != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: unable to load data: %d\n", err); goto out; } err = __elfN(parse_modmetadata)(fp, &ef, p_start, p_end); if (err != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "load_modmetadata: unable to parse metadata: %d\n", err); goto out; } out: if (shstrtab != NULL) free(shstrtab); if (shdr != NULL) free(shdr); if (ef.firstpage != NULL) free(ef.firstpage); if (ef.fd != -1) close(ef.fd); return (err); } int __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef, Elf_Addr p_start, Elf_Addr p_end) { struct mod_metadata md; #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 struct mod_metadata64 md64; #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 struct mod_metadata32 md32; #endif struct mod_depend *mdepend; struct mod_version mver; char *s; int error, modcnt, minfolen; Elf_Addr v, p; modcnt = 0; p = p_start; while (p < p_end) { COPYOUT(p, &v, sizeof (v)); error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof (v)); if (error == EOPNOTSUPP) v += ef->off; else if (error != 0) return (error); #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 COPYOUT(v, &md64, sizeof (md64)); error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof (md64)); if (error == EOPNOTSUPP) { md64.md_cval += ef->off; md64.md_data += ef->off; } else if (error != 0) return (error); md.md_version = md64.md_version; md.md_type = md64.md_type; md.md_cval = (const char *)(uintptr_t)md64.md_cval; md.md_data = (void *)(uintptr_t)md64.md_data; #elif defined(__amd64__) && __ELF_WORD_SIZE == 32 COPYOUT(v, &md32, sizeof (md32)); error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof (md32)); if (error == EOPNOTSUPP) { md32.md_cval += ef->off; md32.md_data += ef->off; } else if (error != 0) return (error); md.md_version = md32.md_version; md.md_type = md32.md_type; md.md_cval = (const char *)(uintptr_t)md32.md_cval; md.md_data = (void *)(uintptr_t)md32.md_data; #else COPYOUT(v, &md, sizeof (md)); error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof (md)); if (error == EOPNOTSUPP) { md.md_cval += ef->off; md.md_data = (void *)((uintptr_t)md.md_data + (uintptr_t)ef->off); } else if (error != 0) return (error); #endif p += sizeof (Elf_Addr); switch (md.md_type) { case MDT_DEPEND: if (ef->kernel) /* kernel must not depend on anything */ break; s = strdupout((vm_offset_t)md.md_cval); minfolen = sizeof (*mdepend) + strlen(s) + 1; mdepend = malloc(minfolen); if (mdepend == NULL) return (ENOMEM); COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof (*mdepend)); strcpy((char *)(mdepend + 1), s); free(s); file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend); free(mdepend); break; case MDT_VERSION: s = strdupout((vm_offset_t)md.md_cval); COPYOUT((vm_offset_t)md.md_data, &mver, sizeof (mver)); file_addmodule(fp, s, mver.mv_version, NULL); free(s); modcnt++; break; } } if (modcnt == 0) { s = fake_modname(fp->f_name); file_addmodule(fp, s, 1, NULL); free(s); } return (0); } static unsigned long elf_hash(const char *name) { const unsigned char *p = (const unsigned char *) name; unsigned long h = 0; unsigned long g; while (*p != '\0') { h = (h << 4) + *p++; if ((g = h & 0xf0000000) != 0) h ^= g >> 24; h &= ~g; } return (h); } static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) "_lookup_symbol: corrupt symbol table\n"; int __elfN(lookup_symbol)(struct preloaded_file *fp __unused, elf_file_t ef, const char *name, Elf_Sym *symp) { Elf_Hashelt symnum; Elf_Sym sym; char *strp; unsigned long hash; hash = elf_hash(name); COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof (symnum)); while (symnum != STN_UNDEF) { if (symnum >= ef->nchains) { printf(__elfN(bad_symtable)); return (ENOENT); } COPYOUT(ef->symtab + symnum, &sym, sizeof (sym)); if (sym.st_name == 0) { printf(__elfN(bad_symtable)); return (ENOENT); } strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); if (strcmp(name, strp) == 0) { free(strp); if (sym.st_shndx != SHN_UNDEF || (sym.st_value != 0 && ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { *symp = sym; return (0); } return (ENOENT); } free(strp); COPYOUT(&ef->chains[symnum], &symnum, sizeof (symnum)); } return (ENOENT); } /* * Apply any intra-module relocations to the value. p is the load address * of the value and val/len is the value to be modified. This does NOT modify * the image in-place, because this is done by kern_linker later on. * * Returns EOPNOTSUPP if no relocation method is supplied. */ static int __elfN(reloc_ptr)(struct preloaded_file *mp __unused, elf_file_t ef, Elf_Addr p, void *val, size_t len) { size_t n; Elf_Rela a; Elf_Rel r; int error; /* * The kernel is already relocated, but we still want to apply * offset adjustments. */ if (ef->kernel) return (EOPNOTSUPP); for (n = 0; n < ef->relsz / sizeof (r); n++) { COPYOUT(ef->rel + n, &r, sizeof (r)); error = __elfN(reloc)(ef, __elfN(symaddr), &r, ELF_RELOC_REL, ef->off, p, val, len); if (error != 0) return (error); } for (n = 0; n < ef->relasz / sizeof (a); n++) { COPYOUT(ef->rela + n, &a, sizeof (a)); error = __elfN(reloc)(ef, __elfN(symaddr), &a, ELF_RELOC_RELA, ef->off, p, val, len); if (error != 0) return (error); } return (0); } static Elf_Addr __elfN(symaddr)(struct elf_file *ef __unused, Elf_Size symidx __unused) { /* Symbol lookup by index not required here. */ return (0); } #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 32 #define _MACHINE_ELF_WANT_32BIT #include "load_elf.c" #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 32 #define _MACHINE_ELF_WANT_32BIT #include "load_elf_obj.c" #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include "load_elf.c" #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include "load_elf_obj.c" /*- * Copyright (c) 2004 Ian Dowse * Copyright (c) 1998 Michael Smith * Copyright (c) 1998 Peter Wemm * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #define FREEBSD_ELF #include #include "bootstrap.h" #define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) #if defined(__i386__) && __ELF_WORD_SIZE == 64 #undef ELF_TARG_CLASS #undef ELF_TARG_MACH #define ELF_TARG_CLASS ELFCLASS64 #define ELF_TARG_MACH EM_X86_64 #endif typedef struct elf_file { Elf_Ehdr hdr; Elf_Shdr *e_shdr; int symtabindex; /* Index of symbol table */ int shstrindex; /* Index of section name string table */ int fd; vm_offset_t off; } *elf_file_t; static int __elfN(obj_loadimage)(struct preloaded_file *mp, elf_file_t ef, u_int64_t loadaddr); static int __elfN(obj_lookup_set)(struct preloaded_file *mp, elf_file_t ef, const char *name, Elf_Addr *startp, Elf_Addr *stopp, int *countp); static int __elfN(obj_reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, Elf_Addr p, void *val, size_t len); static int __elfN(obj_parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef); static Elf_Addr __elfN(obj_symaddr)(struct elf_file *ef, Elf_Size symidx); const char *__elfN(obj_kerneltype) = "elf kernel"; const char *__elfN(obj_moduletype) = "elf obj module"; /* * Attempt to load the file (file) as an ELF module. It will be stored at * (dest), and a pointer to a module structure describing the loaded object * will be saved in (result). */ int __elfN(obj_loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) { struct preloaded_file *fp, *kfp; struct elf_file ef; Elf_Ehdr *hdr; int err; ssize_t bytes_read; fp = NULL; bzero(&ef, sizeof(struct elf_file)); /* * Open the image, read and validate the ELF header */ if (filename == NULL) /* can't handle nameless */ return(EFTYPE); if ((ef.fd = open(filename, O_RDONLY)) == -1) return(errno); hdr = &ef.hdr; bytes_read = read(ef.fd, hdr, sizeof(*hdr)); if (bytes_read != sizeof(*hdr)) { err = EFTYPE; /* could be EIO, but may be small file */ goto oerr; } /* Is it ELF? */ if (!IS_ELF(*hdr)) { err = EFTYPE; goto oerr; } if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ hdr->e_ident[EI_DATA] != ELF_TARG_DATA || hdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */ hdr->e_version != EV_CURRENT || hdr->e_machine != ELF_TARG_MACH || /* Machine ? */ hdr->e_type != ET_REL) { err = EFTYPE; goto oerr; } if (hdr->e_shnum * hdr->e_shentsize == 0 || hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) { err = EFTYPE; goto oerr; } kfp = file_findfile(NULL, __elfN(obj_kerneltype)); if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest); else dest = roundup(dest, PAGE_SIZE); /* * Ok, we think we should handle this. */ fp = file_alloc(); if (fp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } fp->f_name = strdup(filename); fp->f_type = strdup(__elfN(obj_moduletype)); printf("%s ", filename); fp->f_size = __elfN(obj_loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*hdr), hdr); /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: file_discard(fp); out: close(ef.fd); if (ef.e_shdr != NULL) free(ef.e_shdr); return(err); } /* * With the file (fd) open on the image, and (ehdr) containing * the Elf header, load the image at (off) */ static int __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) { Elf_Ehdr *hdr; Elf_Shdr *shdr, *cshdr, *lshdr; vm_offset_t firstaddr, lastaddr; int i, nsym, res, ret, shdrbytes, symstrindex; ret = 0; firstaddr = lastaddr = (vm_offset_t)off; hdr = &ef->hdr; ef->off = (vm_offset_t)off; /* Read in the section headers. */ shdrbytes = hdr->e_shnum * hdr->e_shentsize; shdr = alloc_pread(ef->fd, (off_t)hdr->e_shoff, shdrbytes); if (shdr == NULL) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: read section headers failed\n"); goto out; } ef->e_shdr = shdr; /* * Decide where to load everything, but don't read it yet. * We store the load address as a non-zero sh_addr value. * Start with the code/data and bss. */ for (i = 0; i < hdr->e_shnum; i++) shdr[i].sh_addr = 0; for (i = 0; i < hdr->e_shnum; i++) { if (shdr[i].sh_size == 0) continue; switch (shdr[i].sh_type) { case SHT_PROGBITS: case SHT_NOBITS: lastaddr = roundup(lastaddr, shdr[i].sh_addralign); shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; break; } } /* Symbols. */ nsym = 0; for (i = 0; i < hdr->e_shnum; i++) { switch (shdr[i].sh_type) { case SHT_SYMTAB: nsym++; ef->symtabindex = i; shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; break; } } if (nsym != 1) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: file has no valid symbol table\n"); goto out; } lastaddr = roundup(lastaddr, shdr[ef->symtabindex].sh_addralign); shdr[ef->symtabindex].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[ef->symtabindex].sh_size; symstrindex = shdr[ef->symtabindex].sh_link; if (symstrindex < 0 || symstrindex >= hdr->e_shnum || shdr[symstrindex].sh_type != SHT_STRTAB) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: file has invalid symbol strings\n"); goto out; } lastaddr = roundup(lastaddr, shdr[symstrindex].sh_addralign); shdr[symstrindex].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[symstrindex].sh_size; /* Section names. */ if (hdr->e_shstrndx == 0 || hdr->e_shstrndx >= hdr->e_shnum || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: file has no section names\n"); goto out; } ef->shstrindex = hdr->e_shstrndx; lastaddr = roundup(lastaddr, shdr[ef->shstrindex].sh_addralign); shdr[ef->shstrindex].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[ef->shstrindex].sh_size; /* Relocation tables. */ for (i = 0; i < hdr->e_shnum; i++) { switch (shdr[i].sh_type) { case SHT_REL: case SHT_RELA: lastaddr = roundup(lastaddr, shdr[i].sh_addralign); shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; break; } } /* Clear the whole area, including bss regions. */ kern_bzero(firstaddr, lastaddr - firstaddr); /* Figure section with the lowest file offset we haven't loaded yet. */ for (cshdr = NULL; /* none */; /* none */) { /* * Find next section to load. The complexity of this loop is * O(n^2), but with the number of sections being typically * small, we do not care. */ lshdr = cshdr; for (i = 0; i < hdr->e_shnum; i++) { if (shdr[i].sh_addr == 0 || shdr[i].sh_type == SHT_NOBITS) continue; /* Skip sections that were loaded already. */ if (lshdr != NULL && lshdr->sh_offset >= shdr[i].sh_offset) continue; /* Find section with smallest offset. */ if (cshdr == lshdr || cshdr->sh_offset > shdr[i].sh_offset) cshdr = &shdr[i]; } if (cshdr == lshdr) break; if (kern_pread(ef->fd, (vm_offset_t)cshdr->sh_addr, cshdr->sh_size, (off_t)cshdr->sh_offset) != 0) { printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadimage: read failed\n"); goto out; } } file_addmetadata(fp, MODINFOMD_SHDR, shdrbytes, shdr); res = __elfN(obj_parse_modmetadata)(fp, ef); if (res != 0) goto out; ret = lastaddr - firstaddr; fp->f_addr = firstaddr; printf("size 0x%lx at 0x%lx", (u_long)ret, (u_long)firstaddr); out: printf("\n"); return ret; } #if defined(__i386__) && __ELF_WORD_SIZE == 64 struct mod_metadata64 { int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ u_int64_t md_data; /* specific data */ u_int64_t md_cval; /* common string label */ }; #endif int __elfN(obj_parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) { struct mod_metadata md; #if defined(__i386__) && __ELF_WORD_SIZE == 64 struct mod_metadata64 md64; #endif struct mod_depend *mdepend; struct mod_version mver; char *s; int error, modcnt, minfolen; Elf_Addr v, p, p_stop; if (__elfN(obj_lookup_set)(fp, ef, "modmetadata_set", &p, &p_stop, &modcnt) != 0) return 0; modcnt = 0; while (p < p_stop) { COPYOUT(p, &v, sizeof(v)); error = __elfN(obj_reloc_ptr)(fp, ef, p, &v, sizeof(v)); if (error != 0) return (error); #if defined(__i386__) && __ELF_WORD_SIZE == 64 COPYOUT(v, &md64, sizeof(md64)); error = __elfN(obj_reloc_ptr)(fp, ef, v, &md64, sizeof(md64)); if (error != 0) return (error); md.md_version = md64.md_version; md.md_type = md64.md_type; md.md_cval = (const char *)(uintptr_t)md64.md_cval; md.md_data = (void *)(uintptr_t)md64.md_data; #else COPYOUT(v, &md, sizeof(md)); error = __elfN(obj_reloc_ptr)(fp, ef, v, &md, sizeof(md)); if (error != 0) return (error); #endif p += sizeof(Elf_Addr); switch(md.md_type) { case MDT_DEPEND: s = strdupout((vm_offset_t)md.md_cval); minfolen = sizeof(*mdepend) + strlen(s) + 1; mdepend = malloc(minfolen); if (mdepend == NULL) return ENOMEM; COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof(*mdepend)); strcpy((char*)(mdepend + 1), s); free(s); file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend); free(mdepend); break; case MDT_VERSION: s = strdupout((vm_offset_t)md.md_cval); COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); file_addmodule(fp, s, mver.mv_version, NULL); free(s); modcnt++; break; case MDT_MODULE: case MDT_PNP_INFO: break; default: printf("unknown type %d\n", md.md_type); break; } } return 0; } static int __elfN(obj_lookup_set)(struct preloaded_file *fp __unused, elf_file_t ef, const char* name, Elf_Addr *startp, Elf_Addr *stopp, int *countp) { Elf_Ehdr *hdr; Elf_Shdr *shdr; char *p; vm_offset_t shstrtab; int i; hdr = &ef->hdr; shdr = ef->e_shdr; shstrtab = shdr[ef->shstrindex].sh_addr; for (i = 0; i < hdr->e_shnum; i++) { if (shdr[i].sh_type != SHT_PROGBITS) continue; if (shdr[i].sh_name == 0) continue; p = strdupout(shstrtab + shdr[i].sh_name); if (strncmp(p, "set_", 4) == 0 && strcmp(p + 4, name) == 0) { *startp = shdr[i].sh_addr; *stopp = shdr[i].sh_addr + shdr[i].sh_size; *countp = (*stopp - *startp) / sizeof(Elf_Addr); free(p); return (0); } free(p); } return (ESRCH); } /* * Apply any intra-module relocations to the value. p is the load address * of the value and val/len is the value to be modified. This does NOT modify * the image in-place, because this is done by kern_linker later on. */ static int __elfN(obj_reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, Elf_Addr p, void *val, size_t len) { Elf_Ehdr *hdr; Elf_Shdr *shdr; Elf_Addr off = p; Elf_Addr base; Elf_Rela a, *abase; Elf_Rel r, *rbase; int error, i, j, nrel, nrela; (void)mp; hdr = &ef->hdr; shdr = ef->e_shdr; for (i = 0; i < hdr->e_shnum; i++) { if (shdr[i].sh_type != SHT_RELA && shdr[i].sh_type != SHT_REL) continue; base = shdr[shdr[i].sh_info].sh_addr; if (base == 0 || shdr[i].sh_addr == 0) continue; if (off < base || off + len > base + shdr[shdr[i].sh_info].sh_size) continue; switch (shdr[i].sh_type) { case SHT_RELA: abase = (Elf_Rela *)(intptr_t)shdr[i].sh_addr; nrela = shdr[i].sh_size / sizeof(Elf_Rela); for (j = 0; j < nrela; j++) { COPYOUT(abase + j, &a, sizeof(a)); error = __elfN(reloc)(ef, __elfN(obj_symaddr), &a, ELF_RELOC_RELA, base, off, val, len); if (error != 0) return (error); } break; case SHT_REL: rbase = (Elf_Rel *)(intptr_t)shdr[i].sh_addr; nrel = shdr[i].sh_size / sizeof(Elf_Rel); for (j = 0; j < nrel; j++) { COPYOUT(rbase + j, &r, sizeof(r)); error = __elfN(reloc)(ef, __elfN(obj_symaddr), &r, ELF_RELOC_REL, base, off, val, len); if (error != 0) return (error); } break; } } return (0); } /* Look up the address of a specified symbol. */ static Elf_Addr __elfN(obj_symaddr)(struct elf_file *ef, Elf_Size symidx) { Elf_Sym sym; Elf_Addr base; if (symidx >= ef->e_shdr[ef->symtabindex].sh_size / sizeof(Elf_Sym)) return (0); COPYOUT(ef->e_shdr[ef->symtabindex].sh_addr + symidx * sizeof(Elf_Sym), &sym, sizeof(sym)); if (sym.st_shndx == SHN_UNDEF || sym.st_shndx >= ef->hdr.e_shnum) return (0); base = ef->e_shdr[sym.st_shndx].sh_addr; if (base == 0) return (0); return (base + sym.st_value); } /* * $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * Copyright (c) 1996 * Matthias Drochner. All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include #include #include #include #include #include "bootstrap.h" static char typestr[] = "?fc?d?b? ?l?s?w"; static int ls_getdir(char **pathp); COMMAND_SET(ls, "ls", "list files", command_ls); static int command_ls(int argc, char *argv[]) { int fd; struct stat sb; struct dirent *d; char *buf, *path; char lbuf[128]; /* one line */ int result, ch; int verbose; result = CMD_OK; fd = -1; verbose = 0; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "l")) != -1) { switch (ch) { case 'l': verbose = 1; break; case '?': default: /* getopt has already reported an error */ return (CMD_OK); } } argv += (optind - 1); argc -= (optind - 1); if (argc < 2) { path = ""; } else { path = argv[1]; } if (stat(path, &sb) == 0 && !S_ISDIR(sb.st_mode)) { if (verbose) { printf(" %c %8d %s\n", typestr[sb.st_mode >> 12], (int)sb.st_size, path); } else { printf(" %c %s\n", typestr[sb.st_mode >> 12], path); } return (CMD_OK); } fd = ls_getdir(&path); if (fd == -1) { result = CMD_ERROR; goto out; } pager_open(); pager_output(path); pager_output("\n"); while ((d = readdirfd(fd)) != NULL) { if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) { if (d->d_type == 0 || verbose) { /* stat the file, if possible */ sb.st_size = 0; sb.st_mode = 0; /* Avoid double '/' */ if (strcmp(path, "/") == 0) { (void) asprintf(&buf, "/%s", d->d_name); } else { (void) asprintf(&buf, "%s/%s", path, d->d_name); } if (buf != NULL) { /* * ignore return, could be symlink, etc. */ if (stat(buf, &sb) != 0) { sb.st_size = 0; sb.st_mode = 0; } free(buf); } } if (verbose) { snprintf(lbuf, sizeof (lbuf), " %c %8d %s\n", typestr[d->d_type ? d->d_type:sb.st_mode >> 12], (int)sb.st_size, d->d_name); } else { snprintf(lbuf, sizeof (lbuf), " %c %s\n", typestr[d->d_type ? d->d_type:sb.st_mode >> 12], d->d_name); } if (pager_output(lbuf)) goto out; } } out: pager_close(); if (fd != -1) close(fd); free(path); /* ls_getdir() did allocate path */ return (result); } /* * Given (path) containing a vaguely reasonable path specification, return an fd * on the directory, and an allocated copy of the path to the directory. */ static int ls_getdir(char **pathp) { struct stat sb; int fd; const char *cp; char *path; fd = -1; /* one extra byte for a possible trailing slash required */ path = malloc(strlen(*pathp) + 2); if (path == NULL) { snprintf(command_errbuf, sizeof (command_errbuf), "out of memory"); goto out; } strcpy(path, *pathp); /* Make sure the path is respectable to begin with */ if (archsw.arch_getdev(NULL, path, &cp)) { snprintf(command_errbuf, sizeof (command_errbuf), "bad path '%s'", path); goto out; } /* If there's no path on the device, assume '/' */ if (*cp == 0) strcat(path, "/"); fd = open(path, O_RDONLY); if (fd < 0) { snprintf(command_errbuf, sizeof (command_errbuf), "open '%s' failed: %s", path, strerror(errno)); goto out; } if (fstat(fd, &sb) < 0) { snprintf(command_errbuf, sizeof (command_errbuf), "stat failed: %s", strerror(errno)); goto out; } if (!S_ISDIR(sb.st_mode)) { snprintf(command_errbuf, sizeof (command_errbuf), "%s: %s", path, strerror(ENOTDIR)); goto out; } *pathp = path; return (fd); out: free(path); *pathp = NULL; if (fd != -1) close(fd); return (-1); } /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2018 Toomas Soome */ .file "mb_header.S" /* * Provide fake multiboot header to support versioning and partition * start. The fake MB header is used by versioning code located in * usr/src/cmd/boot/common. Since the BIOS bootblock is stored on raw disk, * this fake header is used to store the location of the version info block. * Additionally we use it to store partition start_sector, so we can identify * our root file system partition. Note we are using LBA64 here. */ #define ASM_FILE #include .globl mb_header, start_sector .text .align 4 mb_header: .long MULTIBOOT_HEADER_MAGIC .long MULTIBOOT_AOUT_KLUDGE .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_AOUT_KLUDGE) .long 0 /* header_addr */ .long 0 /* load_addr */ .long 0 /* load_end_addr */ start_sector: .long 0 /* partition LBA */ .long 0 /*- * Copyright (c) 2009 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "bootstrap.h" #define MD_BLOCK_SIZE 512 #ifndef MD_IMAGE_SIZE #error Must be compiled with MD_IMAGE_SIZE defined #endif #if (MD_IMAGE_SIZE == 0 || MD_IMAGE_SIZE % MD_BLOCK_SIZE) #error Image size must be a multiple of 512. #endif /* * Preloaded image gets put here. * Applications that patch the object with the image can determine * the size looking at the start and end markers (strings), * so we want them contiguous. */ static struct { u_char start[MD_IMAGE_SIZE]; u_char end[128]; } md_image = { .start = "MFS Filesystem goes here", .end = "MFS Filesystem had better STOP here", }; /* devsw I/F */ static int md_init(void); static int md_strategy(void *, int, daddr_t, size_t, char *, size_t *); static int md_open(struct open_file *, ...); static int md_close(struct open_file *); static int md_print(int); struct devsw md_dev = { "md", DEVT_DISK, md_init, md_strategy, md_open, md_close, noioctl, md_print }; static int md_init(void) { return (0); } static int md_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct devdesc *dev = (struct devdesc *)devdata; size_t ofs; if (dev->d_unit != 0) return (ENXIO); if (blk < 0 || blk >= (MD_IMAGE_SIZE / MD_BLOCK_SIZE)) return (EIO); if (size % MD_BLOCK_SIZE) return (EIO); ofs = blk * MD_BLOCK_SIZE; if ((ofs + size) > MD_IMAGE_SIZE) size = MD_IMAGE_SIZE - ofs; if (rsize != 0) *rsize = size; switch (rw & F_MASK) { case F_READ: bcopy(md_image.start + ofs, buf, size); return (0); case F_WRITE: bcopy(buf, md_image.start + ofs, size); return (0); } return (ENODEV); } static int md_open(struct open_file *f, ...) { va_list ap; struct devdesc *dev; va_start(ap, f); dev = va_arg(ap, struct devdesc *); va_end(ap); if (dev->d_unit != 0) return (ENXIO); return (0); } static int md_close(struct open_file *f) { struct devdesc *dev; dev = (struct devdesc *)(f->f_devdata); return ((dev->d_unit != 0) ? ENXIO : 0); } static int md_print(int verbose) { printf("%s devices:", md_dev.dv_name); if (pager_output("\n") != 0) return (1); printf("MD (%u bytes)", MD_IMAGE_SIZE); return (pager_output("\n")); } #!/usr/bin/awk -f # # $FreeBSD$ # # Merge two boot loader help files for FreeBSD 3.0 # Joe Abley BEGIN \ { state = 0; first = -1; ind = 0; } # beginning of first command /^###/ && (state == 0) \ { state = 1; next; } # entry header /^# T[[:graph:]]+ (S[[:graph:]]+ )*D[[:graph:]][[:print:]]*$/ && (state == 1) \ { match($0, " T[[:graph:]]+"); T = substr($0, RSTART + 2, RLENGTH - 2); match($0, " S[[:graph:]]+"); SSTART = RSTART S = (RLENGTH == -1) ? "" : substr($0, RSTART + 2, RLENGTH - 2); match($0, " D[[:graph:]][[:print:]]*$"); D = substr($0, RSTART + 2); if (SSTART > RSTART) S = ""; # find a suitable place to store this one... ind++; if (ind == 1) { first = ind; help[ind, "T"] = T; help[ind, "S"] = S; help[ind, "link"] = -1; } else { i = first; j = -1; while (help[i, "T"] help[i, "S"] < T S) { j = i; i = help[i, "link"]; if (i == -1) break; } if (i == -1) { help[j, "link"] = ind; help[ind, "link"] = -1; } else { help[ind, "link"] = i; if (j == -1) first = ind; else help[j, "link"] = ind; } } help[ind, "T"] = T; help[ind, "S"] = S; help[ind, "D"] = D; # set our state state = 2; help[ind, "text"] = 0; next; } # end of last command, beginning of next one /^###/ && (state == 2) \ { state = 1; } (state == 2) \ { sub("[[:blank:]]+$", ""); if (help[ind, "text"] == 0 && $0 ~ /^[[:blank:]]*$/) next; help[ind, "text", help[ind, "text"]] = $0; help[ind, "text"]++; next; } # show them what we have (it's already sorted in help[]) END \ { node = first; while (node != -1) { printf "################################################################################\n"; printf "# T%s ", help[node, "T"]; if (help[node, "S"] != "") printf "S%s ", help[node, "S"]; printf "D%s\n\n", help[node, "D"]; for (i = 0; i < help[node, "text"]; i++) printf "%s\n", help[node, "text", i]; node = help[node, "link"]; } printf "################################################################################\n"; } /*- * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include #include #include #include #ifndef BOOT2 #include #include "ficl.h" #endif /* * Concatenate the (argc) elements of (argv) into a single string, and return * a copy of same. */ char * unargv(int argc, char *argv[]) { size_t hlong; int i; char *cp; for (i = 0, hlong = 0; i < argc; i++) hlong += strlen(argv[i]) + 2; if(hlong == 0) return(NULL); cp = malloc(hlong); cp[0] = 0; for (i = 0; i < argc; i++) { strcat(cp, argv[i]); if (i < (argc - 1)) strcat(cp, " "); } return(cp); } /* * Get the length of a string in kernel space */ size_t strlenout(vm_offset_t src) { char c; size_t len; for (len = 0; ; len++) { archsw.arch_copyout(src++, &c, 1); if (c == 0) break; } return(len); } /* * Make a duplicate copy of a string in kernel space */ char * strdupout(vm_offset_t str) { char *result, *cp; result = malloc(strlenout(str) + 1); for (cp = result; ;cp++) { archsw.arch_copyout(str++, cp, 1); if (*cp == 0) break; } return(result); } /* Zero a region in kernel space. */ void kern_bzero(vm_offset_t dest, size_t len) { char buf[256]; size_t chunk, resid; bzero(buf, sizeof(buf)); resid = len; while (resid > 0) { chunk = min(sizeof(buf), resid); archsw.arch_copyin(buf, dest, chunk); resid -= chunk; dest += chunk; } } /* * Read the specified part of a file to kernel space. Unlike regular * pread, the file pointer is advanced to the end of the read data, * and it just returns 0 if successful. */ int kern_pread(int fd, vm_offset_t dest, size_t len, off_t off) { if (lseek(fd, off, SEEK_SET) == -1) { #ifdef DEBUG printf("\nlseek failed\n"); #endif return (-1); } if ((size_t)archsw.arch_readin(fd, dest, len) != len) { #ifdef DEBUG printf("\nreadin failed\n"); #endif return (-1); } return (0); } /* * Read the specified part of a file to a malloced buffer. The file * pointer is advanced to the end of the read data. */ void * alloc_pread(int fd, off_t off, size_t len) { void *buf; buf = malloc(len); if (buf == NULL) { #ifdef DEBUG printf("\nmalloc(%d) failed\n", (int)len); #endif return (NULL); } if (lseek(fd, off, SEEK_SET) == -1) { #ifdef DEBUG printf("\nlseek failed\n"); #endif free(buf); return (NULL); } if ((size_t)read(fd, buf, len) != len) { #ifdef DEBUG printf("\nread failed\n"); #endif free(buf); return (NULL); } return (buf); } /* * Display a region in traditional hexdump format. */ void hexdump(caddr_t region, size_t len) { caddr_t line; int x, c; char lbuf[80]; #define emit(fmt, args...) {sprintf(lbuf, fmt , ## args); pager_output(lbuf);} pager_open(); for (line = region; line < (region + len); line += 16) { emit("%08lx ", (long) line); for (x = 0; x < 16; x++) { if ((line + x) < (region + len)) { emit("%02x ", *(u_int8_t *)(line + x)); } else { emit("-- "); } if (x == 7) emit(" "); } emit(" |"); for (x = 0; x < 16; x++) { if ((line + x) < (region + len)) { c = *(u_int8_t *)(line + x); if ((c < ' ') || (c > '~')) /* !isprint(c) */ c = '.'; emit("%c", c); } else { emit(" "); } } emit("|\n"); } pager_close(); } void dev_cleanup(void) { int i; /* Call cleanup routines */ for (i = 0; devsw[i] != NULL; ++i) if (devsw[i]->dv_cleanup != NULL) (devsw[i]->dv_cleanup)(); } #ifndef BOOT2 /* * outb ( port# c -- ) * Store a byte to I/O port number port# */ static void ficlOutb(ficlVm *pVM) { uint8_t c; uint32_t port; port = ficlStackPopUnsigned(ficlVmGetDataStack(pVM)); c = ficlStackPopInteger(ficlVmGetDataStack(pVM)); outb(port, c); } /* * inb ( port# -- c ) * Fetch a byte from I/O port number port# */ static void ficlInb(ficlVm *pVM) { uint8_t c; uint32_t port; port = ficlStackPopUnsigned(ficlVmGetDataStack(pVM)); c = inb(port); ficlStackPushInteger(ficlVmGetDataStack(pVM), c); } static void ficlCompileCpufunc(ficlSystem *pSys) { ficlDictionary *dp = ficlSystemGetDictionary(pSys); FICL_SYSTEM_ASSERT(pSys, dp); (void) ficlDictionarySetPrimitive(dp, "outb", ficlOutb, FICL_WORD_DEFAULT); (void) ficlDictionarySetPrimitive(dp, "inb", ficlInb, FICL_WORD_DEFAULT); } FICL_COMPILE_SET(ficlCompileCpufunc); #endif /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include /* * file/module function dispatcher, support, etc. */ #include #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" #if defined(EFI) #define PTOV(pa) ((void *)pa) #else #include "../i386/btx/lib/btxv86.h" #endif #define MDIR_REMOVED 0x0001 #define MDIR_NOHINTS 0x0002 struct moduledir { char *d_path; /* path of modules directory */ uchar_t *d_hints; /* content of linker.hints file */ int d_hintsz; /* size of hints data */ int d_flags; STAILQ_ENTRY(moduledir) d_link; }; static int file_load(char *, vm_offset_t, struct preloaded_file **); static int file_load_dependencies(struct preloaded_file *); static char *file_search(const char *, const char **); static struct kernel_module *file_findmodule(struct preloaded_file *, char *, struct mod_depend *); static int file_havepath(const char *); static char *mod_searchmodule(char *, struct mod_depend *); static void file_insert_tail(struct preloaded_file *); static void file_remove(struct preloaded_file *); struct file_metadata *metadata_next(struct file_metadata *, int); static void moduledir_readhints(struct moduledir *); static void moduledir_rebuild(void); /* load address should be tweaked by first module loaded (kernel) */ static vm_offset_t loadaddr = 0; #if defined(LOADER_FDT_SUPPORT) static const char *default_searchpath = "/boot/kernel;/boot/modules;/boot/dtb"; #else static const char *default_searchpath = "/kernel"; #endif static STAILQ_HEAD(, moduledir) moduledir_list = STAILQ_HEAD_INITIALIZER(moduledir_list); struct preloaded_file *preloaded_files = NULL; static const char *kld_ext_list[] = { ".ko", "", ".debug", NULL }; /* * load an object, either a disk file or code module. * * To load a file, the syntax is: * * load -t * * code modules are loaded as: * * load */ COMMAND_SET(load, "load", "load a kernel or module", command_load); static int command_load(int argc, char *argv[]) { char *typestr; int dofile, dokld, ch, error; dokld = dofile = 0; optind = 1; optreset = 1; typestr = NULL; if (argc == 1) { command_errmsg = "no filename specified"; return (CMD_CRIT); } while ((ch = getopt(argc, argv, "kt:")) != -1) { switch (ch) { case 'k': dokld = 1; break; case 't': typestr = optarg; dofile = 1; break; case '?': default: /* getopt has already reported an error */ return (CMD_OK); } } argv += (optind - 1); argc -= (optind - 1); printf("Loading %s...\n", argv[1]); /* * Request to load a raw file? */ if (dofile) { struct preloaded_file *fp; if ((typestr == NULL) || (*typestr == 0)) { command_errmsg = "invalid load type"; return (CMD_CRIT); } if (file_findfile(argv[1], typestr) != NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "warning: file '%s' already loaded", argv[1]); return (CMD_WARN); } fp = file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1); if (fp != NULL) return (CMD_OK); /* Failing to load mfs_root is never going to end well! */ if (strcmp("mfs_root", typestr) == 0) return (CMD_FATAL); return (CMD_ERROR); } /* * Do we have explicit KLD load ? */ if (dokld || file_havepath(argv[1])) { error = mod_loadkld(argv[1], argc - 2, argv + 2); if (error == EEXIST) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "warning: KLD '%s' already loaded", argv[1]); return (CMD_WARN); } return (error == 0 ? CMD_OK : CMD_CRIT); } /* * Looks like a request for a module. */ error = mod_load(argv[1], NULL, argc - 2, argv + 2); if (error == EEXIST) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "warning: module '%s' already loaded", argv[1]); return (CMD_WARN); } return (error == 0 ? CMD_OK : CMD_CRIT); } void unload(void) { struct preloaded_file *fp; while (preloaded_files != NULL) { fp = preloaded_files; preloaded_files = preloaded_files->f_next; file_discard(fp); } loadaddr = 0; (void) unsetenv("kernelname"); } COMMAND_SET(unload, "unload", "unload all modules", command_unload); static int command_unload(int argc __unused, char *argv[] __unused) { unload(); return (CMD_OK); } COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod); static int command_lsmod(int argc, char *argv[]) { struct preloaded_file *fp; struct kernel_module *mp; struct file_metadata *md; char lbuf[80]; int ch, verbose, hash, ret = 0; verbose = 0; hash = 0; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "vs")) != -1) { switch (ch) { case 'v': verbose = 1; break; case 's': hash = 1; break; case '?': default: /* getopt has already reported an error */ return (CMD_OK); } } pager_open(); for (fp = preloaded_files; fp; fp = fp->f_next) { (void) snprintf(lbuf, sizeof (lbuf), " %p: ", (void *) fp->f_addr); (void) pager_output(lbuf); (void) pager_output(fp->f_name); (void) snprintf(lbuf, sizeof (lbuf), " (%s, 0x%lx)\n", fp->f_type, (long)fp->f_size); if (pager_output(lbuf)) break; if (fp->f_args != NULL) { (void) pager_output(" args: "); (void) pager_output(fp->f_args); if (pager_output("\n")) break; if (strcmp(fp->f_type, "hash") == 0) { size_t dsize; (void) pager_output(" contents: "); dsize = fp->f_size + 1; if (sizeof (lbuf) < dsize) dsize = sizeof (lbuf); (void) strlcpy(lbuf, ptov(fp->f_addr), dsize); if (pager_output(lbuf)) break; } } if (hash == 1) { void *ptr = PTOV(fp->f_addr); (void) pager_output(" hash: "); sha1(ptr, fp->f_size, (uint8_t *)lbuf); for (int i = 0; i < SHA1_DIGEST_LENGTH; i++) printf("%02x", (int)(lbuf[i] & 0xff)); if (pager_output("\n")) break; } if (fp->f_modules) { (void) pager_output(" modules: "); for (mp = fp->f_modules; mp; mp = mp->m_next) { (void) snprintf(lbuf, sizeof (lbuf), "%s.%d ", mp->m_name, mp->m_version); (void) pager_output(lbuf); } if (pager_output("\n")) break; } if (verbose) { /* * XXX could add some formatting smarts here to * display some better */ for (md = fp->f_metadata; md != NULL; md = md->md_next) { (void) snprintf(lbuf, sizeof (lbuf), " 0x%04x, 0x%lx\n", md->md_type, (long)md->md_size); if ((ret = pager_output(lbuf))) break; } } if (ret != 0) break; } pager_close(); return (CMD_OK); } /* * File level interface, functions file_* */ int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) { static int last_file_format = 0; struct preloaded_file *fp; int error; int i; if (preloaded_files == NULL) last_file_format = 0; if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest); error = EFTYPE; for (i = last_file_format, fp = NULL; file_formats[i] && fp == NULL; i++) { error = (file_formats[i]->l_load)(filename, dest, &fp); if (error == 0) { /* remember the loader */ fp->f_loader = last_file_format = i; *result = fp; break; } else if (last_file_format == i && i != 0) { /* Restart from the beginning */ i = -1; last_file_format = 0; fp = NULL; continue; } if (error == EFTYPE) continue; /* Unknown to this handler? */ if (error) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "can't load file '%s': %s", filename, strerror(error)); break; } } return (error); } static int file_load_dependencies(struct preloaded_file *base_file) { struct file_metadata *md; struct preloaded_file *fp; struct mod_depend *verinfo; struct kernel_module *mp; char *dmodname; int error; md = file_findmetadata(base_file, MODINFOMD_DEPLIST); if (md == NULL) return (0); error = 0; do { verinfo = (struct mod_depend *)md->md_data; dmodname = (char *)(verinfo + 1); if (file_findmodule(NULL, dmodname, verinfo) == NULL) { printf("loading required module '%s'\n", dmodname); error = mod_load(dmodname, verinfo, 0, NULL); if (error) break; /* * If module loaded via kld name which isn't listed * in the linker.hints file, we should check if it have * required version. */ mp = file_findmodule(NULL, dmodname, verinfo); if (mp == NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "module '%s' exists but with wrong version", dmodname); error = ENOENT; break; } } md = metadata_next(md, MODINFOMD_DEPLIST); } while (md); if (!error) return (0); /* Load failed; discard everything */ while (base_file != NULL) { fp = base_file; base_file = base_file->f_next; file_discard(fp); } return (error); } /* * Calculate the size of the environment module. * The environment is list of name=value C strings, ending with a '\0' byte. */ static size_t env_get_size(void) { size_t size = 0; struct env_var *ep; /* Traverse the environment. */ for (ep = environ; ep != NULL; ep = ep->ev_next) { size += strlen(ep->ev_name); size++; /* "=" */ if (ep->ev_value != NULL) size += strlen(ep->ev_value); size++; /* nul byte */ } size++; /* nul byte */ return (size); } static void module_hash(struct preloaded_file *fp, void *addr, size_t size) { uint8_t hash[SHA1_DIGEST_LENGTH]; char ascii[2 * SHA1_DIGEST_LENGTH + 1]; int i; sha1(addr, size, hash); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { (void) snprintf(ascii + 2 * i, sizeof (ascii) - 2 * i, "%02x", hash[i] & 0xff); } /* Out of memory here is not fatal issue. */ (void) asprintf(&fp->f_args, "hash=%s", ascii); } /* * Create virtual module for environment variables. * This module should be created as late as possible before executing * the OS kernel, or we may miss some environment variable updates. */ void build_environment_module(void) { struct preloaded_file *fp; size_t size; char *name = "environment"; vm_offset_t laddr; /* We can't load first */ if (file_findfile(NULL, NULL) == NULL) { printf("Can not load environment module: %s\n", "the kernel is not loaded"); return; } if (file_findfile(name, name) != NULL) { printf("warning: '%s' is already loaded\n", name); return; } tem_save_state(); /* Ask tem to save it's state in env. */ size = env_get_size(); fp = file_alloc(); if (fp != NULL) { fp->f_name = strdup(name); fp->f_type = strdup(name); } if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) { printf("Can not load environment module: %s\n", "out of memory"); file_discard(fp); return; } if (archsw.arch_loadaddr != NULL) loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr); if (loadaddr == 0) { printf("Can not load environment module: %s\n", "out of memory"); file_discard(fp); return; } laddr = bi_copyenv(loadaddr); /* Looks OK so far; populate control structure */ module_hash(fp, PTOV(loadaddr), laddr - loadaddr); fp->f_loader = -1; fp->f_addr = loadaddr; fp->f_size = laddr - loadaddr; /* recognise space consumption */ loadaddr = laddr; file_insert_tail(fp); } void build_font_module(void) { bitmap_data_t *bd; struct font *fd; struct preloaded_file *fp; size_t size; uint32_t checksum; int i; char *name = "console-font"; vm_offset_t laddr; struct font_info fi; struct fontlist *fl; if (STAILQ_EMPTY(&fonts)) return; /* We can't load first */ if (file_findfile(NULL, NULL) == NULL) { printf("Can not load font module: %s\n", "the kernel is not loaded"); return; } if (file_findfile(name, name) != NULL) { printf("warning: '%s' is already loaded\n", name); return; } /* helper pointers */ bd = NULL; STAILQ_FOREACH(fl, &fonts, font_next) { if (tems.ts_font.vf_width == fl->font_data->width && tems.ts_font.vf_height == fl->font_data->height) { /* * Kernel does have better built in font. */ if (fl->font_flags == FONT_BUILTIN) return; bd = fl->font_data; break; } } if (bd == NULL) return; fd = bd->font; fi.fi_width = fd->vf_width; checksum = fi.fi_width; fi.fi_height = fd->vf_height; checksum += fi.fi_height; fi.fi_bitmap_size = bd->uncompressed_size; checksum += fi.fi_bitmap_size; size = roundup2(sizeof (struct font_info), 8); for (i = 0; i < VFNT_MAPS; i++) { fi.fi_map_count[i] = fd->vf_map_count[i]; checksum += fi.fi_map_count[i]; size += fd->vf_map_count[i] * sizeof (struct font_map); size += roundup2(size, 8); } size += bd->uncompressed_size; fi.fi_checksum = -checksum; fp = file_alloc(); if (fp != NULL) { fp->f_name = strdup(name); fp->f_type = strdup(name); } if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) { printf("Can not load font module: %s\n", "out of memory"); file_discard(fp); return; } if (archsw.arch_loadaddr != NULL) loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr); if (loadaddr == 0) { printf("Can not load font module: %s\n", "out of memory"); file_discard(fp); return; } laddr = loadaddr; laddr += archsw.arch_copyin(&fi, laddr, sizeof (struct font_info)); laddr = roundup2(laddr, 8); /* Copy maps. */ for (i = 0; i < VFNT_MAPS; i++) { if (fd->vf_map_count[i] != 0) { laddr += archsw.arch_copyin(fd->vf_map[i], laddr, fd->vf_map_count[i] * sizeof (struct font_map)); laddr = roundup2(laddr, 8); } } /* Copy the bitmap. */ laddr += archsw.arch_copyin(fd->vf_bytes, laddr, fi.fi_bitmap_size); /* Looks OK so far; populate control structure */ module_hash(fp, PTOV(loadaddr), laddr - loadaddr); fp->f_loader = -1; fp->f_addr = loadaddr; fp->f_size = laddr - loadaddr; /* recognise space consumption */ loadaddr = laddr; file_insert_tail(fp); } /* * We've been asked to load (fname) as (type), so just suck it in, * no arguments or anything. */ struct preloaded_file * file_loadraw(const char *fname, char *type, int argc, char **argv, int insert) { struct preloaded_file *fp; char *name; int fd; ssize_t got; struct stat st; /* We can't load first */ if ((file_findfile(NULL, NULL)) == NULL) { command_errmsg = "can't load file before kernel"; return (NULL); } /* locate the file on the load path */ name = file_search(fname, NULL); if (name == NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "can't find '%s'", fname); return (NULL); } if ((fd = open(name, O_RDONLY)) < 0) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "can't open '%s': %s", name, strerror(errno)); free(name); return (NULL); } if (fstat(fd, &st) < 0) { (void) close(fd); (void) snprintf(command_errbuf, sizeof (command_errbuf), "stat error '%s': %s", name, strerror(errno)); free(name); return (NULL); } if (archsw.arch_loadaddr != NULL) loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr); if (loadaddr == 0) { (void) close(fd); (void) snprintf(command_errbuf, sizeof (command_errbuf), "no memory to load %s", name); free(name); return (NULL); } got = archsw.arch_readin(fd, loadaddr, st.st_size); if ((size_t)got != st.st_size) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "error reading '%s': %s", name, strerror(errno)); free(name); (void) close(fd); if (archsw.arch_free_loadaddr != NULL && st.st_size != 0) { archsw.arch_free_loadaddr(loadaddr, (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12)); } return (NULL); } /* Looks OK so far; create & populate control structure */ fp = file_alloc(); if (fp == NULL) { if (archsw.arch_free_loadaddr != NULL && st.st_size != 0) archsw.arch_free_loadaddr(loadaddr, (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12)); (void) snprintf(command_errbuf, sizeof (command_errbuf), "no memory to load %s", name); free(name); (void) close(fd); return (NULL); } fp->f_name = name; fp->f_args = unargv(argc, argv); fp->f_type = strdup(type); fp->f_metadata = NULL; fp->f_loader = -1; fp->f_addr = loadaddr; fp->f_size = st.st_size; if (fp->f_type == NULL || (argc != 0 && fp->f_args == NULL)) { (void) close(fd); (void) snprintf(command_errbuf, sizeof (command_errbuf), "no memory to load %s", name); file_discard(fp); return (NULL); } /* recognise space consumption */ loadaddr += st.st_size; /* Add to the list of loaded files */ if (insert != 0) file_insert_tail(fp); (void) close(fd); return (fp); } /* * Load the module (name), pass it (argc),(argv), add container file * to the list of loaded files. * If module is already loaded just assign new argc/argv. */ int mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[]) { struct kernel_module *mp; int err; char *filename; if (file_havepath(modname)) { printf("Warning: mod_load() called instead of mod_loadkld() " "for module '%s'\n", modname); return (mod_loadkld(modname, argc, argv)); } /* see if module is already loaded */ mp = file_findmodule(NULL, modname, verinfo); if (mp != NULL) { free(mp->m_args); mp->m_args = unargv(argc, argv); (void) snprintf(command_errbuf, sizeof (command_errbuf), "warning: module '%s' already loaded", mp->m_name); return (0); } /* locate file with the module on the search path */ filename = mod_searchmodule(modname, verinfo); if (filename == NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "can't find '%s'", modname); return (ENOENT); } err = mod_loadkld(filename, argc, argv); free(filename); return (err); } /* * Load specified KLD. If path is omitted, then try to locate it via * search path. */ int mod_loadkld(const char *kldname, int argc, char *argv[]) { struct preloaded_file *fp; int err; char *filename; vm_offset_t loadaddr_saved; /* * Get fully qualified KLD name */ filename = file_search(kldname, kld_ext_list); if (filename == NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "can't find '%s'", kldname); return (ENOENT); } /* * Check if KLD already loaded */ fp = file_findfile(filename, NULL); if (fp != NULL) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "warning: KLD '%s' already loaded", filename); free(filename); return (0); } do { err = file_load(filename, loadaddr, &fp); if (err) break; fp->f_args = unargv(argc, argv); loadaddr_saved = loadaddr; loadaddr = fp->f_addr + fp->f_size; file_insert_tail(fp); /* Add to the list of loaded files */ if (file_load_dependencies(fp) != 0) { err = ENOENT; file_remove(fp); loadaddr = loadaddr_saved; fp = NULL; break; } } while (0); if (err == EFTYPE) { (void) snprintf(command_errbuf, sizeof (command_errbuf), "don't know how to load module '%s'", filename); } if (err) file_discard(fp); free(filename); return (err); } /* * Find a file matching (name) and (type). * NULL may be passed as a wildcard to either. */ struct preloaded_file * file_findfile(const char *name, const char *type) { struct preloaded_file *fp; for (fp = preloaded_files; fp != NULL; fp = fp->f_next) { if (((name == NULL) || strcmp(name, fp->f_name) == 0) && ((type == NULL) || strcmp(type, fp->f_type) == 0)) break; } return (fp); } /* * Find a module matching (name) inside of given file. * NULL may be passed as a wildcard. */ struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo) { struct kernel_module *mp, *best; int bestver, mver; if (fp == NULL) { for (fp = preloaded_files; fp; fp = fp->f_next) { mp = file_findmodule(fp, modname, verinfo); if (mp != NULL) return (mp); } return (NULL); } best = NULL; bestver = 0; for (mp = fp->f_modules; mp; mp = mp->m_next) { if (strcmp(modname, mp->m_name) == 0) { if (verinfo == NULL) return (mp); mver = mp->m_version; if (mver == verinfo->md_ver_preferred) return (mp); if (mver >= verinfo->md_ver_minimum && mver <= verinfo->md_ver_maximum && mver > bestver) { best = mp; bestver = mver; } } } return (best); } /* * Make a copy of (size) bytes of data from (p), and associate them as * metadata of (type) to the module (mp). */ void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p) { struct file_metadata *md; md = malloc(sizeof (struct file_metadata) - sizeof (md->md_data) + size); if (md != NULL) { md->md_size = size; md->md_type = type; bcopy(p, md->md_data, size); md->md_next = fp->f_metadata; } fp->f_metadata = md; } /* * Find a metadata object of (type) associated with the file (fp) */ struct file_metadata * file_findmetadata(struct preloaded_file *fp, int type) { struct file_metadata *md; for (md = fp->f_metadata; md != NULL; md = md->md_next) if (md->md_type == type) break; return (md); } struct file_metadata * metadata_next(struct file_metadata *md, int type) { if (md == NULL) return (NULL); while ((md = md->md_next) != NULL) if (md->md_type == type) break; return (md); } static const char *emptyextlist[] = { "", NULL }; /* * Check if the given file is in place and return full path to it. */ static char * file_lookup(const char *path, const char *name, int namelen, const char **extlist) { struct stat st; char *result, *cp; const char **cpp; int pathlen, extlen, len; pathlen = strlen(path); extlen = 0; if (extlist == NULL) extlist = emptyextlist; for (cpp = extlist; *cpp; cpp++) { len = strlen(*cpp); if (len > extlen) extlen = len; } result = malloc(pathlen + namelen + extlen + 2); if (result == NULL) return (NULL); bcopy(path, result, pathlen); if (pathlen > 0 && result[pathlen - 1] != '/') result[pathlen++] = '/'; cp = result + pathlen; bcopy(name, cp, namelen); cp += namelen; for (cpp = extlist; *cpp; cpp++) { (void) strcpy(cp, *cpp); if (stat(result, &st) == 0 && S_ISREG(st.st_mode)) return (result); } free(result); return (NULL); } /* * Check if file name have any qualifiers */ static int file_havepath(const char *name) { const char *cp; (void) archsw.arch_getdev(NULL, name, &cp); return (cp != name || strchr(name, '/') != NULL); } /* * Attempt to find the file (name) on the module searchpath. * If (name) is qualified in any way, we simply check it and * return it or NULL. If it is not qualified, then we attempt * to construct a path using entries in the environment variable * module_path. * * The path we return a pointer to need never be freed, as we manage * it internally. */ static char * file_search(const char *name, const char **extlist) { struct moduledir *mdp; struct stat sb; char *result; int namelen; /* Don't look for nothing */ if (name == NULL) return (NULL); if (*name == '\0') return (strdup(name)); if (file_havepath(name)) { /* Qualified, so just see if it exists */ if (stat(name, &sb) == 0) return (strdup(name)); return (NULL); } moduledir_rebuild(); result = NULL; namelen = strlen(name); STAILQ_FOREACH(mdp, &moduledir_list, d_link) { result = file_lookup(mdp->d_path, name, namelen, extlist); if (result != NULL) break; } return (result); } #define INT_ALIGN(base, ptr) ptr = \ (base) + (((ptr) - (base) + sizeof (int) - 1) & ~(sizeof (int) - 1)) static char * mod_search_hints(struct moduledir *mdp, const char *modname, struct mod_depend *verinfo) { uchar_t *cp, *recptr, *bufend, *best; char *result; int *intp, bestver, blen, clen, ival, modnamelen, reclen; bool found; moduledir_readhints(mdp); modnamelen = strlen(modname); found = false; result = NULL; bestver = 0; if (mdp->d_hints == NULL) goto bad; recptr = mdp->d_hints; bufend = recptr + mdp->d_hintsz; clen = blen = 0; best = cp = NULL; while (recptr < bufend && !found) { intp = (int *)recptr; reclen = *intp++; ival = *intp++; cp = (uchar_t *)intp; switch (ival) { case MDT_VERSION: clen = *cp++; if (clen != modnamelen || bcmp(cp, modname, clen) != 0) break; cp += clen; INT_ALIGN(mdp->d_hints, cp); ival = *(int *)cp; cp += sizeof (int); clen = *cp++; if (verinfo == NULL || ival == verinfo->md_ver_preferred) { found = true; break; } if (ival >= verinfo->md_ver_minimum && ival <= verinfo->md_ver_maximum && ival > bestver) { bestver = ival; best = cp; blen = clen; } break; default: break; } recptr += reclen + sizeof (int); } /* * Finally check if KLD is in the place */ if (found) result = file_lookup(mdp->d_path, (char *)cp, clen, NULL); else if (best) result = file_lookup(mdp->d_path, (char *)best, blen, NULL); bad: /* * If nothing found or hints is absent - fallback to the old way * by using "kldname[.ko]" as module name. */ if (!found && bestver == 0 && result == NULL) { result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list); } return (result); } /* * Attempt to locate the file containing the module (name) */ static char * mod_searchmodule(char *name, struct mod_depend *verinfo) { struct moduledir *mdp; char *result; moduledir_rebuild(); /* * Now we ready to lookup module in the given directories */ result = NULL; STAILQ_FOREACH(mdp, &moduledir_list, d_link) { result = mod_search_hints(mdp, name, verinfo); if (result != NULL) break; } return (result); } int file_addmodule(struct preloaded_file *fp, char *modname, int version, struct kernel_module **newmp) { struct kernel_module *mp; struct mod_depend mdepend; bzero(&mdepend, sizeof (mdepend)); mdepend.md_ver_preferred = version; mp = file_findmodule(fp, modname, &mdepend); if (mp != NULL) return (EEXIST); mp = calloc(1, sizeof (struct kernel_module)); if (mp == NULL) return (ENOMEM); mp->m_name = strdup(modname); if (mp->m_name == NULL) { free(mp); return (ENOMEM); } mp->m_version = version; mp->m_fp = fp; mp->m_next = fp->f_modules; fp->f_modules = mp; if (newmp) *newmp = mp; return (0); } /* * Throw a file away */ void file_discard(struct preloaded_file *fp) { struct file_metadata *md, *md1; struct kernel_module *mp, *mp1; if (fp == NULL) return; if (archsw.arch_free_loadaddr != NULL && fp->f_addr && fp->f_size != 0) { archsw.arch_free_loadaddr(fp->f_addr, (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12)); } md = fp->f_metadata; while (md != NULL) { md1 = md; md = md->md_next; free(md1); } mp = fp->f_modules; while (mp != NULL) { free(mp->m_name); mp1 = mp; mp = mp->m_next; free(mp1); } free(fp->f_name); free(fp->f_type); free(fp->f_args); free(fp); } /* * Allocate a new file; must be used instead of malloc() * to ensure safe initialisation. */ struct preloaded_file * file_alloc(void) { return (calloc(1, sizeof (struct preloaded_file))); } /* * Add a module to the chain */ static void file_insert_tail(struct preloaded_file *fp) { struct preloaded_file *cm; /* Append to list of loaded file */ fp->f_next = NULL; if (preloaded_files == NULL) { preloaded_files = fp; } else { for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) ; cm->f_next = fp; } } /* * Remove module from the chain */ static void file_remove(struct preloaded_file *fp) { struct preloaded_file *cm; if (preloaded_files == NULL) return; if (preloaded_files == fp) { preloaded_files = fp->f_next; return; } for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) { if (cm->f_next == fp) { cm->f_next = fp->f_next; return; } } } static char * moduledir_fullpath(struct moduledir *mdp, const char *fname) { char *cp; cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2); if (cp == NULL) return (NULL); strcpy(cp, mdp->d_path); strcat(cp, "/"); strcat(cp, fname); return (cp); } /* * Read linker.hints file into memory performing some sanity checks. */ static void moduledir_readhints(struct moduledir *mdp) { struct stat st; char *path; int fd, size, version; if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS)) return; path = moduledir_fullpath(mdp, "linker.hints"); if (stat(path, &st) != 0 || st.st_size < (ssize_t)(sizeof (version) + sizeof (int)) || st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) { free(path); mdp->d_flags |= MDIR_NOHINTS; return; } free(path); size = read(fd, &version, sizeof (version)); if (size != sizeof (version) || version != LINKER_HINTS_VERSION) goto bad; size = st.st_size - size; mdp->d_hints = malloc(size); if (mdp->d_hints == NULL) goto bad; if (read(fd, mdp->d_hints, size) != size) goto bad; mdp->d_hintsz = size; (void) close(fd); return; bad: (void) close(fd); free(mdp->d_hints); mdp->d_hints = NULL; mdp->d_flags |= MDIR_NOHINTS; } /* * Extract directories from the ';' separated list, remove duplicates. */ static void moduledir_rebuild(void) { struct moduledir *mdp, *mtmp; const char *path, *cp, *ep; size_t cplen; path = getenv("module_path"); if (path == NULL) path = default_searchpath; /* * Rebuild list of module directories if it changed */ STAILQ_FOREACH(mdp, &moduledir_list, d_link) mdp->d_flags |= MDIR_REMOVED; for (ep = path; *ep != 0; ep++) { cp = ep; for (; *ep != 0 && *ep != ';'; ep++) ; /* * Ignore trailing slashes */ for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--) ; STAILQ_FOREACH(mdp, &moduledir_list, d_link) { if (strlen(mdp->d_path) != cplen || bcmp(cp, mdp->d_path, cplen) != 0) continue; mdp->d_flags &= ~MDIR_REMOVED; break; } if (mdp == NULL) { mdp = malloc(sizeof (*mdp) + cplen + 1); if (mdp == NULL) return; mdp->d_path = (char *)(mdp + 1); bcopy(cp, mdp->d_path, cplen); mdp->d_path[cplen] = 0; mdp->d_hints = NULL; mdp->d_flags = 0; STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link); } if (*ep == '\0') break; } /* * Delete unused directories if any */ mdp = STAILQ_FIRST(&moduledir_list); while (mdp) { if ((mdp->d_flags & MDIR_REMOVED) == 0) { mdp = STAILQ_NEXT(mdp, d_link); } else { free(mdp->d_hints); mtmp = mdp; mdp = STAILQ_NEXT(mdp, d_link); STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link); free(mtmp); } } } /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2017 Toomas Soome * Copyright 2019, Joyent, Inc. */ /* * This module adds support for loading and booting illumos multiboot2 * kernel. This code is only built to support the illumos kernel, it does * not support xen. */ #include #include #include #include #include #include #include #include #include #include #include #include "libzfs.h" #include "bootstrap.h" #include #include #include #define SUPPORT_DHCP #include #if !defined(EFI) #include "../i386/btx/lib/btxv86.h" #include "libi386.h" #include "vbe.h" #else #include #include #include "loader_efi.h" static void (*trampoline)(uint32_t, struct relocator *, uint64_t); static UINTN efi_map_size; /* size of efi memory map */ #endif #include "platform/acfreebsd.h" #include "acconfig.h" #define ACPI_SYSTEM_XFACE #include "actypes.h" #include "actbl.h" extern ACPI_TABLE_RSDP *rsdp; /* MB data heap pointer. */ static vm_offset_t last_addr; static int multiboot2_loadfile(char *, uint64_t, struct preloaded_file **); static int multiboot2_exec(struct preloaded_file *); struct file_format multiboot2 = { multiboot2_loadfile, multiboot2_exec }; static bool keep_bs = false; static bool have_framebuffer = false; static vm_offset_t load_addr; static vm_offset_t entry_addr; bool has_boot_services = true; /* * Validate tags in info request. This function is provided just to * recognize the current tag list and only serves as a limited * safe guard against possibly corrupt information. */ static bool is_info_request_valid(multiboot_header_tag_information_request_t *rtag) { int i; /* * If the tag is optional and we do not support it, we do not * have to do anything special, so we skip optional tags. */ if (rtag->mbh_flags & MULTIBOOT_HEADER_TAG_OPTIONAL) return (true); for (i = 0; i < (rtag->mbh_size - sizeof (*rtag)) / sizeof (rtag->mbh_requests[0]); i++) switch (rtag->mbh_requests[i]) { case MULTIBOOT_TAG_TYPE_END: case MULTIBOOT_TAG_TYPE_CMDLINE: case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: case MULTIBOOT_TAG_TYPE_MODULE: case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: case MULTIBOOT_TAG_TYPE_BOOTDEV: case MULTIBOOT_TAG_TYPE_MMAP: case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: case MULTIBOOT_TAG_TYPE_APM: case MULTIBOOT_TAG_TYPE_EFI32: case MULTIBOOT_TAG_TYPE_EFI64: case MULTIBOOT_TAG_TYPE_ACPI_OLD: case MULTIBOOT_TAG_TYPE_ACPI_NEW: case MULTIBOOT_TAG_TYPE_NETWORK: case MULTIBOOT_TAG_TYPE_EFI_MMAP: case MULTIBOOT_TAG_TYPE_EFI_BS: case MULTIBOOT_TAG_TYPE_EFI32_IH: case MULTIBOOT_TAG_TYPE_EFI64_IH: case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: break; default: printf("unsupported information tag: 0x%x\n", rtag->mbh_requests[i]); return (false); } return (true); } static int multiboot2_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int fd, error; uint32_t i; struct stat st; caddr_t header_search; multiboot2_header_t *header; multiboot_header_tag_t *tag; multiboot_header_tag_address_t *addr_tag = NULL; multiboot_header_tag_entry_address_t *entry_tag = NULL; struct preloaded_file *fp; /* This allows to check other file formats from file_formats array. */ error = EFTYPE; if (filename == NULL) return (error); /* is kernel already loaded? */ fp = file_findfile(NULL, NULL); if (fp != NULL) return (error); if ((fd = open(filename, O_RDONLY)) == -1) return (errno); /* * Read MULTIBOOT_SEARCH size in order to search for the * multiboot magic header. */ header_search = malloc(MULTIBOOT_SEARCH); if (header_search == NULL) { close(fd); return (ENOMEM); } if (read(fd, header_search, MULTIBOOT_SEARCH) != MULTIBOOT_SEARCH) goto out; header = NULL; for (i = 0; i <= (MULTIBOOT_SEARCH - sizeof (multiboot2_header_t)); i += MULTIBOOT_HEADER_ALIGN) { header = (multiboot2_header_t *)(header_search + i); /* Do we have match on magic? */ if (header->mb2_magic != MULTIBOOT2_HEADER_MAGIC) { header = NULL; continue; } /* * Validate checksum, the sum of magic + architecture + * header_length + checksum must equal 0. */ if (header->mb2_magic + header->mb2_architecture + header->mb2_header_length + header->mb2_checksum != 0) { header = NULL; continue; } /* * Finally, the entire header must fit within MULTIBOOT_SEARCH. */ if (i + header->mb2_header_length > MULTIBOOT_SEARCH) { header = NULL; continue; } break; } if (header == NULL) goto out; have_framebuffer = false; for (tag = header->mb2_tags; tag->mbh_type != MULTIBOOT_TAG_TYPE_END; tag = (multiboot_header_tag_t *)((uintptr_t)tag + roundup2(tag->mbh_size, MULTIBOOT_TAG_ALIGN))) { switch (tag->mbh_type) { case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST: if (is_info_request_valid((void*)tag) == false) goto out; break; case MULTIBOOT_HEADER_TAG_ADDRESS: addr_tag = (multiboot_header_tag_address_t *)tag; break; case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS: entry_tag = (multiboot_header_tag_entry_address_t *)tag; break; case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS: break; case MULTIBOOT_HEADER_TAG_FRAMEBUFFER: have_framebuffer = true; break; case MULTIBOOT_HEADER_TAG_MODULE_ALIGN: /* we always align modules */ break; case MULTIBOOT_HEADER_TAG_EFI_BS: keep_bs = true; break; default: if (!(tag->mbh_flags & MULTIBOOT_HEADER_TAG_OPTIONAL)) { printf("unsupported tag: 0x%x\n", tag->mbh_type); goto out; } } } /* * We must have addr_tag and entry_tag to load a 64-bit kernel. * If these tags are missing, we either have a 32-bit kernel, or * this is not our kernel at all. */ if (addr_tag != NULL && entry_tag != NULL) { fp = file_alloc(); if (fp == NULL) { error = ENOMEM; goto out; } if (lseek(fd, 0, SEEK_SET) == -1) { printf("lseek failed\n"); error = EIO; file_discard(fp); goto out; } if (fstat(fd, &st) < 0) { printf("fstat failed\n"); error = EIO; file_discard(fp); goto out; } load_addr = addr_tag->mbh_load_addr; entry_addr = entry_tag->mbh_entry_addr; fp->f_addr = archsw.arch_loadaddr(LOAD_KERN, filename, addr_tag->mbh_load_addr); if (fp->f_addr == 0) { error = ENOMEM; file_discard(fp); goto out; } fp->f_size = archsw.arch_readin(fd, fp->f_addr, st.st_size); if (fp->f_size != st.st_size) { printf("error reading %s: %s\n", filename, strerror(errno)); file_discard(fp); error = EIO; goto out; } fp->f_name = strdup(filename); fp->f_type = strdup("aout multiboot2 kernel"); if (fp->f_name == NULL || fp->f_type == NULL) { error = ENOMEM; file_discard(fp); goto out; } fp->f_metadata = NULL; error = 0; } else { #if defined(EFI) /* 32-bit kernel is not yet supported for EFI */ printf("32-bit kernel is not supported by UEFI loader\n"); error = ENOTSUP; goto out; #endif /* elf32_loadfile_raw will fill the attributes in fp. */ error = elf32_loadfile_raw(filename, dest, &fp, 2); if (error != 0) { printf("elf32_loadfile_raw failed: %d unable to " "load multiboot2 kernel\n", error); goto out; } entry_addr = fp->f_addr; /* * We want the load_addr to have some legal value, * so we set it same as the entry_addr. * The distinction is important with UEFI, but not * with BIOS version, because BIOS version does not use * staging area. */ load_addr = fp->f_addr; } setenv("kernelname", fp->f_name, 1); #if defined(EFI) efi_addsmapdata(fp); #else bios_addsmapdata(fp); #endif *result = fp; out: free(header_search); close(fd); return (error); } /* * Search the command line for named property. * * Return codes: * 0 The name is found, we return the data in value and len. * ENOENT The name is not found. * EINVAL The provided command line is badly formed. */ static int find_property_value(const char *cmd, const char *name, const char **value, size_t *len) { const char *namep, *valuep; size_t name_len, value_len; int quoted; *value = NULL; *len = 0; if (cmd == NULL) return (ENOENT); while (*cmd != '\0') { if (cmd[0] != '-' || cmd[1] != 'B') { cmd++; continue; } cmd += 2; /* Skip -B */ while (cmd[0] == ' ' || cmd[0] == '\t') cmd++; /* Skip whitespaces. */ while (*cmd != '\0' && cmd[0] != ' ' && cmd[0] != '\t') { namep = cmd; valuep = strchr(cmd, '='); if (valuep == NULL) break; name_len = valuep - namep; valuep++; value_len = 0; quoted = 0; for (;; ++value_len) { if (valuep[value_len] == '\0') break; /* Is this value quoted? */ if (value_len == 0 && (valuep[0] == '\'' || valuep[0] == '"')) { quoted = valuep[0]; ++value_len; } /* * In the quote accept any character, * but look for ending quote. */ if (quoted != 0) { if (valuep[value_len] == quoted) quoted = 0; continue; } /* A comma or white space ends the value. */ if (valuep[value_len] == ',' || valuep[value_len] == ' ' || valuep[value_len] == '\t') break; } if (quoted != 0) { printf("Missing closing '%c' in \"%s\"\n", quoted, valuep); return (EINVAL); } if (value_len != 0) { if (strncmp(namep, name, name_len) == 0) { *value = valuep; *len = value_len; return (0); } } cmd = valuep + value_len; while (*cmd == ',') cmd++; } } return (ENOENT); } /* * If command line has " -B ", insert property after "-B ", otherwise * append to command line. */ static char * insert_cmdline(const char *head, const char *prop) { const char *prop_opt = " -B "; char *cmdline, *tail; int len = 0; tail = strstr(head, prop_opt); if (tail != NULL) { ptrdiff_t diff; tail += strlen(prop_opt); diff = tail - head; if (diff >= INT_MAX) return (NULL); len = (int)diff; } if (tail == NULL) asprintf(&cmdline, "%s%s%s", head, prop_opt, prop); else asprintf(&cmdline, "%.*s%s,%s", len, head, prop, tail); return (cmdline); } /* * Since we have no way to pass the environment to the mb1 kernel other than * through arguments, we need to take care of console setup. * * If the console is in mirror mode, set the kernel console from $os_console. * If it's unset, use first item from $console. * If $console is "ttyX", also pass $ttyX-mode, since it may have been set by * the user. * * In case of memory allocation errors, just return the original command line * so we have a chance of booting. * * On success, cl will be freed and a new, allocated command line string is * returned. * * For the mb2 kernel, we only set command line console if os_console is set. * We can not overwrite console in the environment, as it can disrupt the * loader console messages, and we do not want to deal with the os_console * in the kernel. */ static char * update_cmdline(char *cl, bool mb2) { char *os_console = getenv("os_console"); char *ttymode = NULL; char mode[10]; char *tmp; const char *prop; size_t plen; int rv; if (mb2 == true && os_console == NULL) return (cl); if (os_console == NULL) { tmp = strdup(getenv("console")); os_console = strsep(&tmp, ", "); } else { os_console = strdup(os_console); } if (os_console == NULL) return (cl); if (mb2 == false && strncmp(os_console, "tty", 3) == 0) { snprintf(mode, sizeof (mode), "%s-mode", os_console); /* * The ttyX-mode variable is set by our serial console * driver for ttya-ttyd. However, since the os_console * values are not verified, it is possible we get bogus * name and no mode variable. If so, we do not set console * property and let the kernel use defaults. */ if ((ttymode = getenv(mode)) == NULL) return (cl); } rv = find_property_value(cl, "console", &prop, &plen); if (rv != 0 && rv != ENOENT) { free(os_console); return (cl); } /* If console is set and this is MB2 boot, we are done. */ if (rv == 0 && mb2 == true) { free(os_console); return (cl); } /* If console is set, do we need to set tty mode? */ if (rv == 0) { const char *ttyp = NULL; size_t ttylen; free(os_console); os_console = NULL; *mode = '\0'; if (strncmp(prop, "tty", 3) == 0 && plen == 4) { strncpy(mode, prop, plen); mode[plen] = '\0'; strncat(mode, "-mode", 5); find_property_value(cl, mode, &ttyp, &ttylen); } if (*mode != '\0' && ttyp == NULL) ttymode = getenv(mode); else return (cl); } /* Build updated command line. */ if (os_console != NULL) { char *propstr; asprintf(&propstr, "console=%s", os_console); free(os_console); if (propstr == NULL) { return (cl); } tmp = insert_cmdline(cl, propstr); free(propstr); if (tmp == NULL) return (cl); free(cl); cl = tmp; } if (ttymode != NULL) { char *propstr; asprintf(&propstr, "%s=\"%s\"", mode, ttymode); if (propstr == NULL) return (cl); tmp = insert_cmdline(cl, propstr); free(propstr); if (tmp == NULL) return (cl); free(cl); cl = tmp; } return (cl); } /* * Build the kernel command line. Shared function between MB1 and MB2. * * In both cases, if fstype is set and is not zfs, we do not set up * zfs-bootfs property. But we set kernel file name and options. * * For the MB1, we only can pass properties on command line, so * we will set console, ttyX-mode (for serial console) and zfs-bootfs. * * For the MB2, we can pass properties in environment, but if os_console * is set in environment, we need to add console property on the kernel * command line. * * The console properties are managed in update_cmdline(). */ int mb_kernel_cmdline(struct preloaded_file *fp, struct devdesc *rootdev, char **line) { const char *fs = getenv("fstype"); char *cmdline; size_t len; bool zfs_root = false; bool mb2; int rv; /* * With multiple console devices and "os_console" variable not * set, set os_console to last input device. */ rv = cons_inputdev(); if (rv != -1) (void) setenv("os_console", consoles[rv]->c_name, 0); /* * 64-bit kernel has aout header, 32-bit kernel is elf, and the * type strings are different. Lets just search for "multiboot2". */ if (strstr(fp->f_type, "multiboot2") == NULL) mb2 = false; else mb2 = true; if (rootdev->d_dev->dv_type == DEVT_ZFS) zfs_root = true; /* If we have fstype set in env, reset zfs_root if needed. */ if (fs != NULL && strcmp(fs, "zfs") != 0) zfs_root = false; /* * If we have fstype set on the command line, * reset zfs_root if needed. */ rv = find_property_value(fp->f_args, "fstype", &fs, &len); if (rv != 0 && rv != ENOENT) return (rv); if (fs != NULL && strncmp(fs, "zfs", len) != 0) zfs_root = false; /* zfs_bootfs() will set the environment, it must be called. */ if (zfs_root == true) fs = zfs_bootfs(rootdev); if (fp->f_args == NULL) cmdline = strdup(fp->f_name); else asprintf(&cmdline, "%s %s", fp->f_name, fp->f_args); if (cmdline == NULL) return (ENOMEM); /* Append zfs-bootfs for MB1 command line. */ if (mb2 == false && zfs_root == true) { char *tmp; tmp = insert_cmdline(cmdline, fs); free(cmdline); if (tmp == NULL) return (ENOMEM); cmdline = tmp; } *line = update_cmdline(cmdline, mb2); return (0); } /* * Returns allocated virtual address from MB info area. */ static vm_offset_t mb_malloc(size_t n) { vm_offset_t ptr = last_addr; last_addr = roundup(last_addr + n, MULTIBOOT_TAG_ALIGN); return (ptr); } /* * Calculate size for module tag list. */ static size_t module_size(struct preloaded_file *fp) { size_t len, size; struct preloaded_file *mfp; size = 0; for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) { len = strlen(mfp->f_name) + 1; len += strlen(mfp->f_type) + 5 + 1; /* 5 is for "type=" */ if (mfp->f_args != NULL) len += strlen(mfp->f_args) + 1; size += sizeof (multiboot_tag_module_t) + len; size = roundup(size, MULTIBOOT_TAG_ALIGN); } return (size); } #if defined(EFI) /* * Calculate size for UEFI memory map tag. */ #define EFI_EXTRA_PAGES 3 static int efimemmap_size(void) { UINTN size, cur_size, desc_size; EFI_MEMORY_DESCRIPTOR *mmap; EFI_STATUS ret; size = EFI_PAGE_SIZE; /* Start with 4k. */ while (1) { cur_size = size; mmap = malloc(cur_size); if (mmap == NULL) return (0); ret = BS->GetMemoryMap(&cur_size, mmap, NULL, &desc_size, NULL); free(mmap); if (ret == EFI_SUCCESS) break; if (ret == EFI_BUFFER_TOO_SMALL) { if (size < cur_size) size = cur_size; size += (EFI_PAGE_SIZE); } else return (0); } /* EFI MMAP will grow when we allocate MBI, set some buffer. */ size += (EFI_EXTRA_PAGES << EFI_PAGE_SHIFT); size = roundup2(size, EFI_PAGE_SIZE); efi_map_size = size; /* Record the calculated size. */ return (sizeof (multiboot_tag_efi_mmap_t) + size); } #endif /* * Calculate size for bios smap tag. */ static size_t biossmap_size(struct preloaded_file *fp) { int num; struct file_metadata *md; md = file_findmetadata(fp, MODINFOMD_SMAP); if (md == NULL) return (0); num = md->md_size / sizeof (struct bios_smap); /* number of entries */ return (sizeof (multiboot_tag_mmap_t) + num * sizeof (multiboot_mmap_entry_t)); } static size_t mbi_size(struct preloaded_file *fp, char *cmdline) { size_t size; #if !defined(EFI) extern multiboot_tag_framebuffer_t gfx_fb; #endif size = sizeof (uint32_t) * 2; /* first 2 fields from MBI header */ size += sizeof (multiboot_tag_string_t) + strlen(cmdline) + 1; size = roundup2(size, MULTIBOOT_TAG_ALIGN); size += sizeof (multiboot_tag_string_t) + strlen(bootprog_info) + 1; size = roundup2(size, MULTIBOOT_TAG_ALIGN); #if !defined(EFI) size += sizeof (multiboot_tag_basic_meminfo_t); size = roundup2(size, MULTIBOOT_TAG_ALIGN); #endif size += module_size(fp); size = roundup2(size, MULTIBOOT_TAG_ALIGN); #if defined(EFI) size += sizeof (multiboot_tag_efi64_t); size = roundup2(size, MULTIBOOT_TAG_ALIGN); size += efimemmap_size(); size = roundup2(size, MULTIBOOT_TAG_ALIGN); if (have_framebuffer == true) { size += sizeof (multiboot_tag_framebuffer_t); size = roundup2(size, MULTIBOOT_TAG_ALIGN); } #endif size += biossmap_size(fp); size = roundup2(size, MULTIBOOT_TAG_ALIGN); #if !defined(EFI) if (gfx_fb.framebuffer_common.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED) { size += sizeof (struct multiboot_tag_framebuffer_common); size += CMAP_SIZE * sizeof (multiboot_color_t); } else { size += sizeof (multiboot_tag_framebuffer_t); } size = roundup2(size, MULTIBOOT_TAG_ALIGN); size += sizeof (multiboot_tag_vbe_t); size = roundup2(size, MULTIBOOT_TAG_ALIGN); #endif if (bootp_response != NULL) { size += sizeof (multiboot_tag_network_t) + bootp_response_size; size = roundup2(size, MULTIBOOT_TAG_ALIGN); } if (rsdp != NULL) { if (rsdp->Revision == 0) { size += sizeof (multiboot_tag_old_acpi_t) + sizeof (ACPI_RSDP_COMMON); } else { size += sizeof (multiboot_tag_new_acpi_t) + rsdp->Length; } size = roundup2(size, MULTIBOOT_TAG_ALIGN); } size += sizeof (multiboot_tag_t); return (size); } #if defined(EFI) static bool overlaps(uintptr_t start1, size_t size1, uintptr_t start2, size_t size2) { if (start1 < start2 + size2 && start1 + size1 >= start2) { printf("overlaps: %zx-%zx, %zx-%zx\n", start1, start1 + size1, start2, start2 + size2); return (true); } return (false); } #endif static int multiboot2_exec(struct preloaded_file *fp) { multiboot2_info_header_t *mbi = NULL; struct preloaded_file *mfp; char *cmdline = NULL; struct devdesc *rootdev; struct file_metadata *md; int i, error, num; int rootfs = 0; size_t size; struct bios_smap *smap; #if defined(EFI) multiboot_tag_module_t *module, *mp; struct relocator *relocator = NULL; EFI_MEMORY_DESCRIPTOR *map; UINTN map_size, desc_size; struct chunk_head *head; struct chunk *chunk; vm_offset_t tmp; efi_getdev((void **)(&rootdev), NULL, NULL); /* * We need 5 pages for relocation. We'll allocate from the heap: while * it's possible that our heap got placed low down enough to be in the * way of where we're going to relocate our kernel, it's hopefully not * likely. */ if ((relocator = malloc(EFI_PAGE_SIZE * 5)) == NULL) { printf("relocator malloc failed!\n"); error = ENOMEM; goto error; } if (overlaps((uintptr_t)relocator, EFI_PAGE_SIZE * 5, load_addr, fp->f_size)) { printf("relocator pages overlap the kernel!\n"); error = EINVAL; goto error; } #else i386_getdev((void **)(&rootdev), NULL, NULL); if (have_framebuffer == false) { /* make sure we have text mode */ bios_set_text_mode(VGA_TEXT_MODE); } #endif error = EINVAL; if (rootdev == NULL) { printf("can't determine root device\n"); goto error; } /* * Set the image command line. */ if (fp->f_args == NULL) { cmdline = getenv("boot-args"); if (cmdline != NULL) { fp->f_args = strdup(cmdline); if (fp->f_args == NULL) { error = ENOMEM; goto error; } } } error = mb_kernel_cmdline(fp, rootdev, &cmdline); if (error != 0) goto error; /* mb_kernel_cmdline() updates the environment. */ build_environment_module(); /* Pass the loaded console font for kernel. */ build_font_module(); size = mbi_size(fp, cmdline); /* Get the size for MBI. */ /* Set up the base for mb_malloc. */ i = 0; for (mfp = fp; mfp->f_next != NULL; mfp = mfp->f_next) i++; #if defined(EFI) /* We need space for kernel + MBI + # modules */ num = (EFI_PAGE_SIZE - offsetof(struct relocator, rel_chunklist)) / sizeof (struct chunk); if (i + 2 >= num) { printf("Too many modules, do not have space for relocator.\n"); error = ENOMEM; goto error; } last_addr = efi_loadaddr(LOAD_MEM, &size, mfp->f_addr + mfp->f_size); mbi = (multiboot2_info_header_t *)last_addr; if (mbi == NULL) { error = ENOMEM; goto error; } last_addr = (vm_offset_t)mbi->mbi_tags; #else /* Start info block from the new page. */ last_addr = i386_loadaddr(LOAD_MEM, &size, mfp->f_addr + mfp->f_size); /* Do we have space for multiboot info? */ if (last_addr + size >= memtop_copyin) { error = ENOMEM; goto error; } mbi = (multiboot2_info_header_t *)PTOV(last_addr); last_addr = (vm_offset_t)mbi->mbi_tags; #endif /* EFI */ { multiboot_tag_string_t *tag; i = sizeof (multiboot_tag_string_t) + strlen(cmdline) + 1; tag = (multiboot_tag_string_t *)mb_malloc(i); tag->mb_type = MULTIBOOT_TAG_TYPE_CMDLINE; tag->mb_size = i; memcpy(tag->mb_string, cmdline, strlen(cmdline) + 1); free(cmdline); cmdline = NULL; } { multiboot_tag_string_t *tag; i = sizeof (multiboot_tag_string_t) + strlen(bootprog_info) + 1; tag = (multiboot_tag_string_t *)mb_malloc(i); tag->mb_type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME; tag->mb_size = i; memcpy(tag->mb_string, bootprog_info, strlen(bootprog_info) + 1); } #if !defined(EFI) /* Only set in case of BIOS. */ { multiboot_tag_basic_meminfo_t *tag; tag = (multiboot_tag_basic_meminfo_t *) mb_malloc(sizeof (*tag)); tag->mb_type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO; tag->mb_size = sizeof (*tag); tag->mb_mem_lower = bios_basemem / 1024; tag->mb_mem_upper = bios_extmem / 1024; } #endif num = 0; for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) { num++; if (mfp->f_type != NULL && strcmp(mfp->f_type, "rootfs") == 0) rootfs++; } if (num == 0 || rootfs == 0) { /* We need at least one module - rootfs. */ printf("No rootfs module provided, aborting\n"); error = EINVAL; goto error; } /* * Set the stage for physical memory layout: * - We have kernel at load_addr. * - Modules are aligned to page boundary. * - MBI is aligned to page boundary. * - Set the tmp to point to physical address of the first module. * - tmp != mfp->f_addr only in case of EFI. */ #if defined(EFI) tmp = roundup2(load_addr + fp->f_size + 1, MULTIBOOT_MOD_ALIGN); module = (multiboot_tag_module_t *)last_addr; #endif for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) { multiboot_tag_module_t *tag; num = strlen(mfp->f_name) + 1; num += strlen(mfp->f_type) + 5 + 1; if (mfp->f_args != NULL) { num += strlen(mfp->f_args) + 1; } cmdline = malloc(num); if (cmdline == NULL) { error = ENOMEM; goto error; } if (mfp->f_args != NULL) snprintf(cmdline, num, "%s type=%s %s", mfp->f_name, mfp->f_type, mfp->f_args); else snprintf(cmdline, num, "%s type=%s", mfp->f_name, mfp->f_type); tag = (multiboot_tag_module_t *)mb_malloc(sizeof (*tag) + num); tag->mb_type = MULTIBOOT_TAG_TYPE_MODULE; tag->mb_size = sizeof (*tag) + num; #if defined(EFI) /* * We can assign module addresses only after BS have been * switched off. */ tag->mb_mod_start = 0; tag->mb_mod_end = mfp->f_size; #else tag->mb_mod_start = mfp->f_addr; tag->mb_mod_end = mfp->f_addr + mfp->f_size; #endif memcpy(tag->mb_cmdline, cmdline, num); free(cmdline); cmdline = NULL; } md = file_findmetadata(fp, MODINFOMD_SMAP); if (md == NULL) { printf("no memory smap\n"); error = EINVAL; goto error; } smap = (struct bios_smap *)md->md_data; num = md->md_size / sizeof (struct bios_smap); /* number of entries */ { multiboot_tag_mmap_t *tag; multiboot_mmap_entry_t *mmap_entry; tag = (multiboot_tag_mmap_t *) mb_malloc(sizeof (*tag) + num * sizeof (multiboot_mmap_entry_t)); tag->mb_type = MULTIBOOT_TAG_TYPE_MMAP; tag->mb_size = sizeof (*tag) + num * sizeof (multiboot_mmap_entry_t); tag->mb_entry_size = sizeof (multiboot_mmap_entry_t); tag->mb_entry_version = 0; mmap_entry = (multiboot_mmap_entry_t *)tag->mb_entries; for (i = 0; i < num; i++) { mmap_entry[i].mmap_addr = smap[i].base; mmap_entry[i].mmap_len = smap[i].length; mmap_entry[i].mmap_type = smap[i].type; mmap_entry[i].mmap_reserved = 0; } } if (bootp_response != NULL) { multiboot_tag_network_t *tag; tag = (multiboot_tag_network_t *) mb_malloc(sizeof (*tag) + bootp_response_size); tag->mb_type = MULTIBOOT_TAG_TYPE_NETWORK; tag->mb_size = sizeof (*tag) + bootp_response_size; memcpy(tag->mb_dhcpack, bootp_response, bootp_response_size); } #if !defined(EFI) multiboot_tag_vbe_t *tag; extern multiboot_tag_vbe_t vbestate; if (VBE_VALID_MODE(vbestate.vbe_mode)) { tag = (multiboot_tag_vbe_t *)mb_malloc(sizeof (*tag)); memcpy(tag, &vbestate, sizeof (*tag)); tag->mb_type = MULTIBOOT_TAG_TYPE_VBE; tag->mb_size = sizeof (*tag); } #endif if (rsdp != NULL) { multiboot_tag_new_acpi_t *ntag; multiboot_tag_old_acpi_t *otag; uint32_t tsize; if (rsdp->Revision == 0) { tsize = sizeof (*otag) + sizeof (ACPI_RSDP_COMMON); otag = (multiboot_tag_old_acpi_t *)mb_malloc(tsize); otag->mb_type = MULTIBOOT_TAG_TYPE_ACPI_OLD; otag->mb_size = tsize; memcpy(otag->mb_rsdp, rsdp, sizeof (ACPI_RSDP_COMMON)); } else { tsize = sizeof (*ntag) + rsdp->Length; ntag = (multiboot_tag_new_acpi_t *)mb_malloc(tsize); ntag->mb_type = MULTIBOOT_TAG_TYPE_ACPI_NEW; ntag->mb_size = tsize; memcpy(ntag->mb_rsdp, rsdp, rsdp->Length); } } #if defined(EFI) #ifdef __LP64__ { multiboot_tag_efi64_t *tag; tag = (multiboot_tag_efi64_t *) mb_malloc(sizeof (*tag)); tag->mb_type = MULTIBOOT_TAG_TYPE_EFI64; tag->mb_size = sizeof (*tag); tag->mb_pointer = (uint64_t)(uintptr_t)ST; } #else { multiboot_tag_efi32_t *tag; tag = (multiboot_tag_efi32_t *) mb_malloc(sizeof (*tag)); tag->mb_type = MULTIBOOT_TAG_TYPE_EFI32; tag->mb_size = sizeof (*tag); tag->mb_pointer = (uint32_t)ST; } #endif /* __LP64__ */ #endif /* EFI */ if (have_framebuffer == true) { multiboot_tag_framebuffer_t *tag; extern multiboot_tag_framebuffer_t gfx_fb; #if defined(EFI) tag = (multiboot_tag_framebuffer_t *)mb_malloc(sizeof (*tag)); memcpy(tag, &gfx_fb, sizeof (*tag)); tag->framebuffer_common.mb_type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; tag->framebuffer_common.mb_size = sizeof (*tag); #else extern multiboot_color_t *cmap; uint32_t size; if (gfx_fb.framebuffer_common.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED) { uint16_t nc; nc = gfx_fb.u.fb1.framebuffer_palette_num_colors; size = sizeof (struct multiboot_tag_framebuffer_common) + sizeof (nc) + nc * sizeof (multiboot_color_t); } else { size = sizeof (gfx_fb); } tag = (multiboot_tag_framebuffer_t *)mb_malloc(size); memcpy(tag, &gfx_fb, sizeof (*tag)); tag->framebuffer_common.mb_type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; tag->framebuffer_common.mb_size = size; if (gfx_fb.framebuffer_common.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED) { gfx_fb.u.fb1.framebuffer_palette_num_colors = CMAP_SIZE; memcpy(tag->u.fb1.framebuffer_palette, cmap, sizeof (multiboot_color_t) * CMAP_SIZE); } #endif /* EFI */ } #if defined(EFI) /* Leave EFI memmap last as we will also switch off the BS. */ { multiboot_tag_efi_mmap_t *tag; UINTN key; EFI_STATUS status; tag = (multiboot_tag_efi_mmap_t *) mb_malloc(sizeof (*tag)); map_size = 0; status = BS->GetMemoryMap(&map_size, (EFI_MEMORY_DESCRIPTOR *)tag->mb_efi_mmap, &key, &desc_size, &tag->mb_descr_vers); if (status != EFI_BUFFER_TOO_SMALL) { error = EINVAL; goto error; } map_size = roundup2(map_size, EFI_PAGE_SIZE); i = 2; /* Attempts to ExitBootServices() */ while (map_size <= efi_map_size && i > 0) { status = BS->GetMemoryMap(&map_size, (EFI_MEMORY_DESCRIPTOR *)tag->mb_efi_mmap, &key, &desc_size, &tag->mb_descr_vers); if (status == EFI_BUFFER_TOO_SMALL) { /* Still too small? */ map_size += EFI_PAGE_SIZE; continue; } if (EFI_ERROR(status)) { error = EINVAL; goto error; } if (keep_bs != 0) break; status = BS->ExitBootServices(IH, key); if (status == EFI_SUCCESS) { has_boot_services = false; break; } i--; } if (status != EFI_SUCCESS) { error = EINVAL; goto error; } tag->mb_type = MULTIBOOT_TAG_TYPE_EFI_MMAP; tag->mb_size = sizeof (*tag) + map_size; tag->mb_descr_size = (uint32_t)desc_size; map = (EFI_MEMORY_DESCRIPTOR *)tag->mb_efi_mmap; last_addr += map_size; last_addr = roundup2(last_addr, MULTIBOOT_TAG_ALIGN); } #endif /* EFI */ /* * MB tag list end marker. */ { multiboot_tag_t *tag = (multiboot_tag_t *) mb_malloc(sizeof (*tag)); tag->mb_type = MULTIBOOT_TAG_TYPE_END; tag->mb_size = sizeof (*tag); } mbi->mbi_total_size = last_addr - (vm_offset_t)mbi; mbi->mbi_reserved = 0; #if defined(EFI) /* * At this point we have load_addr pointing to kernel load * address, module list in MBI having physical addresses, * module list in fp having logical addresses and tmp pointing to * physical address for MBI. * Now we must move all pieces to place and start the kernel. */ head = &relocator->rel_chunk_head; STAILQ_INIT(head); i = 0; chunk = &relocator->rel_chunklist[i++]; chunk->chunk_vaddr = fp->f_addr; chunk->chunk_paddr = load_addr; chunk->chunk_size = fp->f_size; STAILQ_INSERT_TAIL(head, chunk, chunk_next); mp = module; for (mfp = fp->f_next; mfp != NULL; mfp = mfp->f_next) { chunk = &relocator->rel_chunklist[i++]; chunk->chunk_vaddr = mfp->f_addr; /* * fix the mb_mod_start and mb_mod_end. */ mp->mb_mod_start = efi_physaddr(module, tmp, map, map_size / desc_size, desc_size, mfp->f_addr, mp->mb_mod_end); if (mp->mb_mod_start == 0) panic("Could not find memory for module"); mp->mb_mod_end += mp->mb_mod_start; chunk->chunk_paddr = mp->mb_mod_start; chunk->chunk_size = mfp->f_size; STAILQ_INSERT_TAIL(head, chunk, chunk_next); mp = (multiboot_tag_module_t *) roundup2((uintptr_t)mp + mp->mb_size, MULTIBOOT_TAG_ALIGN); } chunk = &relocator->rel_chunklist[i++]; chunk->chunk_vaddr = (EFI_VIRTUAL_ADDRESS)(uintptr_t)mbi; chunk->chunk_paddr = efi_physaddr(module, tmp, map, map_size / desc_size, desc_size, (uintptr_t)mbi, mbi->mbi_total_size); chunk->chunk_size = mbi->mbi_total_size; STAILQ_INSERT_TAIL(head, chunk, chunk_next); trampoline = (void *)(uintptr_t)relocator + EFI_PAGE_SIZE; memmove(trampoline, multiboot_tramp, EFI_PAGE_SIZE); relocator->rel_copy = (uintptr_t)trampoline + EFI_PAGE_SIZE; memmove((void *)relocator->rel_copy, efi_copy_finish, EFI_PAGE_SIZE); relocator->rel_memmove = (uintptr_t)relocator->rel_copy + EFI_PAGE_SIZE; memmove((void *)relocator->rel_memmove, memmove, EFI_PAGE_SIZE); relocator->rel_stack = relocator->rel_memmove + EFI_PAGE_SIZE - 8; trampoline(MULTIBOOT2_BOOTLOADER_MAGIC, relocator, entry_addr); #else dev_cleanup(); __exec((void *)VTOP(multiboot_tramp), MULTIBOOT2_BOOTLOADER_MAGIC, (void *)entry_addr, (void *)VTOP(mbi)); #endif /* EFI */ panic("exec returned"); error: free(cmdline); #if defined(EFI) free(relocator); if (mbi != NULL) efi_free_loadaddr((vm_offset_t)mbi, EFI_SIZE_TO_PAGES(size)); #endif return (error); } #!/bin/sh - # # $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $ # # Copyright (c) 1984, 1986, 1990, 1993 # The Regents of the University of California. All rights reserved. # # 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. # 4. Neither the name of the University nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. # # @(#)newvers.sh 8.1 (Berkeley) 4/20/94 tempfile=$(mktemp tmp.XXXXXX) || exit trap "rm -f $tempfile" EXIT INT TERM LC_ALL=C; export LC_ALL r="$1" echo "char bootprog_info[] = \"illumos/${3} ${2}, Revision ${r}\\\\n\";" > $tempfile echo "unsigned bootprog_rev = ${r%%.*}${r##*.};" >> $tempfile mv $tempfile vers.c /* * Copyright 2020 Toomas Soome * * 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. * * 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. */ /* * Big Theory Statement. * * nvstore is abstraction layer to implement data read/write to different * types of non-volatile storage. * * User interfaces: * Provide mapping via environment: setenv/unsetenv/putenv. Access via * environment functions/commands is available once nvstore has * attached the backend and stored textual data is mapped to environment. * * Provide command "nvstore" to create new data instances. * * API: TBD. * nvstore_init(): attach new backend and create the environment mapping. * nvstore_fini: detach backend and unmap the related environment. * * The disk based storage, such as UFS file or ZFS bootenv label area, is * only accessible after root file system is set. Root file system change * will switch the back end storage. */ #include #include #include #include #include "stand.h" typedef struct nvstore { char *nvs_name; void *nvs_data; nvs_callbacks_t *nvs_cb; STAILQ_ENTRY(nvstore) nvs_next; } nvstore_t; typedef STAILQ_HEAD(store_list, nvstore) nvstore_list_t; nvstore_list_t stores = STAILQ_HEAD_INITIALIZER(stores); void * nvstore_get_store(const char *name) { nvstore_t *st; st = NULL; STAILQ_FOREACH(st, &stores, nvs_next) { if (strcmp(name, st->nvs_name) == 0) break; } return (st); } int nvstore_init(const char *name, nvs_callbacks_t *cb, void *data) { nvstore_t *st; st = nvstore_get_store(name); if (st != NULL) return (EEXIST); if ((st = malloc(sizeof (*st))) == NULL) return (ENOMEM); if ((st->nvs_name = strdup(name)) == NULL) { free(st); return (ENOMEM); } st->nvs_data = data; st->nvs_cb = cb; STAILQ_INSERT_TAIL(&stores, st, nvs_next); return (0); } int nvstore_fini(const char *name) { nvstore_t *st; st = nvstore_get_store(name); if (st == NULL) return (ENOENT); STAILQ_REMOVE(&stores, st, nvstore, nvs_next); free(st->nvs_name); free(st->nvs_data); free(st); return (0); } int nvstore_print(void *ptr) { nvstore_t *st = ptr; return (st->nvs_cb->nvs_iterate(st->nvs_data, st->nvs_cb->nvs_print)); } int nvstore_get_var(void *ptr, const char *name, void **data) { nvstore_t *st = ptr; return (st->nvs_cb->nvs_getter(st->nvs_data, name, data)); } int nvstore_set_var(void *ptr, int type, const char *name, void *data, size_t size) { nvstore_t *st = ptr; return (st->nvs_cb->nvs_setter(st->nvs_data, type, name, data, size)); } int nvstore_set_var_from_string(void *ptr, const char *type, const char *name, const char *data) { nvstore_t *st = ptr; return (st->nvs_cb->nvs_setter_str(st->nvs_data, type, name, data)); } int nvstore_unset_var(void *ptr, const char *name) { nvstore_t *st = ptr; return (st->nvs_cb->nvs_unset(st->nvs_data, name)); } COMMAND_SET(nvstore, "nvstore", "manage non-volatile data", command_nvstore); static void nvstore_usage(const char *me) { printf("Usage:\t%s -l\n", me); printf("\t%s store -l\n", me); printf("\t%s store [-t type] key value\n", me); printf("\t%s store -g key\n", me); printf("\t%s store -d key\n", me); } /* * Usage: nvstore -l # list stores * nvstore store -l # list data in store * nvstore store [-t type] key value * nvstore store -g key # get value * nvstore store -d key # delete key */ static int command_nvstore(int argc, char *argv[]) { int c; bool list, get, delete; nvstore_t *st; char *me, *name, *type; me = argv[0]; optind = 1; optreset = 1; list = false; while ((c = getopt(argc, argv, "l")) != -1) { switch (c) { case 'l': list = true; break; case '?': default: return (CMD_ERROR); } } argc -= optind; argv += optind; if (argc == 0) { if (list) { if (STAILQ_EMPTY(&stores)) { printf("No configured nvstores\n"); return (CMD_OK); } printf("List of configured nvstores:\n"); STAILQ_FOREACH(st, &stores, nvs_next) { printf("\t%s\n", st->nvs_name); } return (CMD_OK); } nvstore_usage(me); return (CMD_ERROR); } if (argc == 0 || (argc != 0 && list)) { nvstore_usage(me); return (CMD_ERROR); } st = nvstore_get_store(argv[0]); if (st == NULL) { nvstore_usage(me); return (CMD_ERROR); } optind = 1; optreset = 1; name = NULL; type = NULL; get = delete = false; while ((c = getopt(argc, argv, "d:g:lt:")) != -1) { switch (c) { case 'd': if (list || get) { nvstore_usage(me); return (CMD_ERROR); } name = optarg; delete = true; break; case 'g': if (delete || list) { nvstore_usage(me); return (CMD_ERROR); } name = optarg; get = true; break; case 'l': if (delete || get) { nvstore_usage(me); return (CMD_ERROR); } list = true; break; case 't': type = optarg; break; case '?': default: return (CMD_ERROR); } } argc -= optind; argv += optind; if (list) { (void) nvstore_print(st); return (CMD_OK); } if (delete && name != NULL) { (void) nvstore_unset_var(st, name); return (CMD_OK); } if (get && name != NULL) { char *ptr = NULL; if (nvstore_get_var(st, name, (void **)&ptr) == 0) printf("%s = %s\n", name, ptr); return (CMD_OK); } if (argc == 2) { c = nvstore_set_var_from_string(st, type, argv[0], argv[1]); if (c != 0) { printf("error: %s\n", strerror(c)); return (CMD_ERROR); } return (CMD_OK); } nvstore_usage(me); return (CMD_OK); } /* * Copyright (c) 2012 Andrey V. Elsukov * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PART_DEBUG #define DPRINTF(fmt, args...) printf("%s: " fmt "\n", __func__, ## args) #else #define DPRINTF(fmt, args...) ((void)0) #endif #ifdef LOADER_GPT_SUPPORT #define MAXTBLSZ 64 static const uuid_t gpt_uuid_unused = GPT_ENT_TYPE_UNUSED; static const uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA; static const uuid_t gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS; static const uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI; static const uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD; static const uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT; static const uuid_t gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP; static const uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS; static const uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM; static const uuid_t gpt_uuid_illumos_boot = GPT_ENT_TYPE_ILLUMOS_BOOT; static const uuid_t gpt_uuid_illumos_ufs = GPT_ENT_TYPE_ILLUMOS_UFS; static const uuid_t gpt_uuid_illumos_zfs = GPT_ENT_TYPE_ILLUMOS_ZFS; static const uuid_t gpt_uuid_reserved = GPT_ENT_TYPE_RESERVED; static const uuid_t gpt_uuid_apple_apfs = GPT_ENT_TYPE_APPLE_APFS; #endif struct pentry { struct ptable_entry part; uint64_t flags; union { uint8_t bsd; uint8_t mbr; uuid_t gpt; uint16_t vtoc8; uint16_t vtoc; } type; STAILQ_ENTRY(pentry) entry; }; struct ptable { enum ptable_type type; uint16_t sectorsize; uint64_t sectors; STAILQ_HEAD(, pentry) entries; }; static struct parttypes { enum partition_type type; const char *desc; } ptypes[] = { { PART_UNKNOWN, "Unknown" }, { PART_EFI, "EFI" }, { PART_FREEBSD, "FreeBSD" }, { PART_FREEBSD_BOOT, "FreeBSD boot" }, { PART_FREEBSD_UFS, "FreeBSD UFS" }, { PART_FREEBSD_ZFS, "FreeBSD ZFS" }, { PART_FREEBSD_SWAP, "FreeBSD swap" }, { PART_FREEBSD_VINUM, "FreeBSD vinum" }, { PART_LINUX, "Linux" }, { PART_LINUX_SWAP, "Linux swap" }, { PART_DOS, "DOS/Windows" }, { PART_ISO9660, "ISO9660" }, { PART_SOLARIS2, "Solaris 2" }, { PART_ILLUMOS_UFS, "illumos UFS" }, { PART_ILLUMOS_ZFS, "illumos ZFS" }, { PART_RESERVED, "Reserved" }, { PART_VTOC_BOOT, "boot" }, { PART_VTOC_ROOT, "root" }, { PART_VTOC_SWAP, "swap" }, { PART_VTOC_USR, "usr" }, { PART_VTOC_STAND, "stand" }, { PART_VTOC_VAR, "var" }, { PART_VTOC_HOME, "home" }, { PART_APFS, "APFS" } }; const char * parttype2str(enum partition_type type) { size_t i; for (i = 0; i < nitems(ptypes); i++) if (ptypes[i].type == type) return (ptypes[i].desc); return (ptypes[0].desc); } #ifdef LOADER_GPT_SUPPORT static void uuid_letoh(uuid_t *uuid) { uuid->time_low = le32toh(uuid->time_low); uuid->time_mid = le16toh(uuid->time_mid); uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version); } static enum partition_type gpt_parttype(uuid_t type) { if (uuid_equal(&type, &gpt_uuid_efi, NULL)) return (PART_EFI); else if (uuid_equal(&type, &gpt_uuid_ms_basic_data, NULL)) return (PART_DOS); else if (uuid_equal(&type, &gpt_uuid_freebsd_boot, NULL)) return (PART_FREEBSD_BOOT); else if (uuid_equal(&type, &gpt_uuid_freebsd_ufs, NULL)) return (PART_FREEBSD_UFS); else if (uuid_equal(&type, &gpt_uuid_freebsd_zfs, NULL)) return (PART_FREEBSD_ZFS); else if (uuid_equal(&type, &gpt_uuid_freebsd_swap, NULL)) return (PART_FREEBSD_SWAP); else if (uuid_equal(&type, &gpt_uuid_freebsd_vinum, NULL)) return (PART_FREEBSD_VINUM); else if (uuid_equal(&type, &gpt_uuid_freebsd, NULL)) return (PART_FREEBSD); else if (uuid_equal(&type, &gpt_uuid_illumos_boot, NULL)) return (PART_VTOC_BOOT); else if (uuid_equal(&type, &gpt_uuid_illumos_ufs, NULL)) return (PART_ILLUMOS_UFS); else if (uuid_equal(&type, &gpt_uuid_illumos_zfs, NULL)) return (PART_ILLUMOS_ZFS); else if (uuid_equal(&type, &gpt_uuid_reserved, NULL)) return (PART_RESERVED); else if (uuid_equal(&type, &gpt_uuid_apple_apfs, NULL)) return (PART_APFS); return (PART_UNKNOWN); } static struct gpt_hdr * gpt_checkhdr(struct gpt_hdr *hdr, uint64_t lba_self, uint64_t lba_last __attribute((unused)), uint16_t sectorsize) { uint32_t sz, crc; if (memcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof (hdr->hdr_sig)) != 0) { DPRINTF("no GPT signature"); return (NULL); } sz = le32toh(hdr->hdr_size); if (sz < 92 || sz > sectorsize) { DPRINTF("invalid GPT header size: %u", sz); return (NULL); } crc = le32toh(hdr->hdr_crc_self); hdr->hdr_crc_self = crc32(0, Z_NULL, 0); if (crc32(hdr->hdr_crc_self, (const Bytef *)hdr, sz) != crc) { DPRINTF("GPT header's CRC doesn't match"); return (NULL); } hdr->hdr_crc_self = crc; hdr->hdr_revision = le32toh(hdr->hdr_revision); if (hdr->hdr_revision < GPT_HDR_REVISION) { DPRINTF("unsupported GPT revision %u", hdr->hdr_revision); return (NULL); } hdr->hdr_lba_self = le64toh(hdr->hdr_lba_self); if (hdr->hdr_lba_self != lba_self) { DPRINTF("self LBA doesn't match"); return (NULL); } hdr->hdr_lba_alt = le64toh(hdr->hdr_lba_alt); if (hdr->hdr_lba_alt == hdr->hdr_lba_self) { DPRINTF("invalid alternate LBA"); return (NULL); } hdr->hdr_entries = le32toh(hdr->hdr_entries); hdr->hdr_entsz = le32toh(hdr->hdr_entsz); if (hdr->hdr_entries == 0 || hdr->hdr_entsz < sizeof (struct gpt_ent) || sectorsize % hdr->hdr_entsz != 0) { DPRINTF("invalid entry size or number of entries"); return (NULL); } hdr->hdr_lba_start = le64toh(hdr->hdr_lba_start); hdr->hdr_lba_end = le64toh(hdr->hdr_lba_end); hdr->hdr_lba_table = le64toh(hdr->hdr_lba_table); hdr->hdr_crc_table = le32toh(hdr->hdr_crc_table); uuid_letoh(&hdr->hdr_uuid); return (hdr); } static int gpt_checktbl(const struct gpt_hdr *hdr, uint8_t *tbl, size_t size, uint64_t lba_last __attribute((unused))) { struct gpt_ent *ent; uint32_t i, cnt; cnt = size / hdr->hdr_entsz; if (hdr->hdr_entries <= cnt) { cnt = hdr->hdr_entries; /* Check CRC only when buffer size is enough for table. */ if (hdr->hdr_crc_table != crc32(0, tbl, hdr->hdr_entries * hdr->hdr_entsz)) { DPRINTF("GPT table's CRC doesn't match"); return (-1); } } for (i = 0; i < cnt; i++) { ent = (struct gpt_ent *)(tbl + i * hdr->hdr_entsz); uuid_letoh(&ent->ent_type); if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) continue; ent->ent_lba_start = le64toh(ent->ent_lba_start); ent->ent_lba_end = le64toh(ent->ent_lba_end); } return (0); } static struct ptable * ptable_gptread(struct ptable *table, void *dev, diskread_t dread) { struct pentry *entry; struct gpt_hdr *phdr, hdr; struct gpt_ent *ent; uint8_t *buf, *tbl; uint64_t offset; int pri, sec; size_t size, i; buf = malloc(table->sectorsize); if (buf == NULL) return (NULL); tbl = malloc(table->sectorsize * MAXTBLSZ); if (tbl == NULL) { free(buf); return (NULL); } /* Read the primary GPT header. */ if (dread(dev, buf, 1, 1) != 0) { ptable_close(table); table = NULL; goto out; } pri = sec = 0; /* Check the primary GPT header. */ phdr = gpt_checkhdr((struct gpt_hdr *)buf, 1, table->sectors - 1, table->sectorsize); if (phdr != NULL) { /* Read the primary GPT table. */ size = MIN(MAXTBLSZ, (phdr->hdr_entries * phdr->hdr_entsz + table->sectorsize - 1) / table->sectorsize); if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 && gpt_checktbl(phdr, tbl, size * table->sectorsize, table->sectors - 1) == 0) { memcpy(&hdr, phdr, sizeof (hdr)); pri = 1; } } offset = pri ? hdr.hdr_lba_alt: table->sectors - 1; /* Read the backup GPT header. */ if (dread(dev, buf, 1, offset) != 0) phdr = NULL; else phdr = gpt_checkhdr((struct gpt_hdr *)buf, offset, table->sectors - 1, table->sectorsize); if (phdr != NULL) { /* * Compare primary and backup headers. * If they are equal, then we do not need to read backup * table. If they are different, then prefer backup header * and try to read backup table. */ if (pri == 0 || uuid_equal(&hdr.hdr_uuid, &phdr->hdr_uuid, NULL) == 0 || hdr.hdr_revision != phdr->hdr_revision || hdr.hdr_size != phdr->hdr_size || hdr.hdr_lba_start != phdr->hdr_lba_start || hdr.hdr_lba_end != phdr->hdr_lba_end || hdr.hdr_entries != phdr->hdr_entries || hdr.hdr_entsz != phdr->hdr_entsz || hdr.hdr_crc_table != phdr->hdr_crc_table) { /* Read the backup GPT table. */ size = MIN(MAXTBLSZ, (phdr->hdr_entries * phdr->hdr_entsz + table->sectorsize - 1) / table->sectorsize); if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 && gpt_checktbl(phdr, tbl, size * table->sectorsize, table->sectors - 1) == 0) { memcpy(&hdr, phdr, sizeof (hdr)); sec = 1; } } } if (pri == 0 && sec == 0) { /* Both primary and backup tables are invalid. */ table->type = PTABLE_NONE; goto out; } DPRINTF("GPT detected"); size = MIN(hdr.hdr_entries * hdr.hdr_entsz, MAXTBLSZ * table->sectorsize); /* * If the disk's sector count is smaller than the sector count recorded * in the disk's GPT table header, set the table->sectors to the value * recorded in GPT tables. This is done to work around buggy firmware * that returns truncated disk sizes. * * Note, this is still not a foolproof way to get disk's size. For * example, an image file can be truncated when copied to smaller media. */ table->sectors = hdr.hdr_lba_alt + 1; for (i = 0; i < size / hdr.hdr_entsz; i++) { ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz); if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) continue; /* Simple sanity checks. */ if (ent->ent_lba_start < hdr.hdr_lba_start || ent->ent_lba_end > hdr.hdr_lba_end || ent->ent_lba_start > ent->ent_lba_end) continue; entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = ent->ent_lba_start; entry->part.end = ent->ent_lba_end; entry->part.index = i + 1; entry->part.type = gpt_parttype(ent->ent_type); entry->flags = le64toh(ent->ent_attr); memcpy(&entry->type.gpt, &ent->ent_type, sizeof (uuid_t)); STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new GPT partition added"); } out: free(buf); free(tbl); return (table); } #endif /* LOADER_GPT_SUPPORT */ #ifdef LOADER_MBR_SUPPORT /* We do not need to support too many EBR partitions in the loader */ #define MAXEBRENTRIES 8 static enum partition_type mbr_parttype(uint8_t type) { switch (type) { case DOSPTYP_386BSD: return (PART_FREEBSD); case DOSPTYP_LINSWP: return (PART_LINUX_SWAP); case DOSPTYP_LINUX: return (PART_LINUX); case DOSPTYP_SUNIXOS2: return (PART_SOLARIS2); case 0x01: case 0x04: case 0x06: case 0x07: case 0x0b: case 0x0c: case 0x0e: return (PART_DOS); } return (PART_UNKNOWN); } static struct ptable * ptable_ebrread(struct ptable *table, void *dev, diskread_t dread) { struct dos_partition *dp; struct pentry *e1, *entry; uint32_t start, end, offset; uint8_t *buf; int i, idx; STAILQ_FOREACH(e1, &table->entries, entry) { if (e1->type.mbr == DOSPTYP_EXT || e1->type.mbr == DOSPTYP_EXTLBA) break; } if (e1 == NULL) return (table); idx = 5; offset = e1->part.start; buf = malloc(table->sectorsize); if (buf == NULL) return (table); DPRINTF("EBR detected"); for (i = 0; i < MAXEBRENTRIES; i++) { #if 0 /* Some BIOSes return an incorrect number of sectors */ if (offset >= table->sectors) break; #endif if (dread(dev, buf, 1, offset) != 0) break; dp = (struct dos_partition *)(buf + DOSPARTOFF); if (dp[0].dp_typ == 0) break; start = le32toh(dp[0].dp_start); if (dp[0].dp_typ == DOSPTYP_EXT && dp[1].dp_typ == 0) { offset = e1->part.start + start; continue; } end = le32toh(dp[0].dp_size); entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = offset + start; entry->part.end = entry->part.start + end - 1; entry->part.index = idx++; entry->part.type = mbr_parttype(dp[0].dp_typ); entry->flags = dp[0].dp_flag; entry->type.mbr = dp[0].dp_typ; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new EBR partition added"); if (dp[1].dp_typ == 0) break; offset = e1->part.start + le32toh(dp[1].dp_start); } free(buf); return (table); } #endif /* LOADER_MBR_SUPPORT */ static enum partition_type bsd_parttype(uint8_t type) { switch (type) { case FS_SWAP: return (PART_FREEBSD_SWAP); case FS_BSDFFS: return (PART_FREEBSD_UFS); case FS_VINUM: return (PART_FREEBSD_VINUM); case FS_ZFS: return (PART_FREEBSD_ZFS); } return (PART_UNKNOWN); } static struct ptable * ptable_bsdread(struct ptable *table, void *dev, diskread_t dread) { struct disklabel *dl; struct partition *part; struct pentry *entry; uint8_t *buf; uint32_t raw_offset; int i; if (table->sectorsize < sizeof (struct disklabel)) { DPRINTF("Too small sectorsize"); return (table); } buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, 1) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } dl = (struct disklabel *)buf; if (le32toh(dl->d_magic) != DISKMAGIC && le32toh(dl->d_magic2) != DISKMAGIC) goto out; if (le32toh(dl->d_secsize) != table->sectorsize) { DPRINTF("unsupported sector size"); goto out; } dl->d_npartitions = le16toh(dl->d_npartitions); if (dl->d_npartitions > 20 || dl->d_npartitions < 8) { DPRINTF("invalid number of partitions"); goto out; } DPRINTF("BSD detected"); part = &dl->d_partitions[0]; raw_offset = le32toh(part[RAW_PART].p_offset); for (i = 0; i < dl->d_npartitions; i++, part++) { if (i == RAW_PART) continue; if (part->p_size == 0) continue; entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = le32toh(part->p_offset) - raw_offset; entry->part.end = entry->part.start + le32toh(part->p_size) - 1; entry->part.type = bsd_parttype(part->p_fstype); entry->part.index = i; /* starts from zero */ entry->type.bsd = part->p_fstype; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new BSD partition added"); } table->type = PTABLE_BSD; out: free(buf); return (table); } #ifdef LOADER_VTOC8_SUPPORT static enum partition_type vtoc8_parttype(uint16_t type) { switch (type) { case VTOC_TAG_FREEBSD_SWAP: return (PART_FREEBSD_SWAP); case VTOC_TAG_FREEBSD_UFS: return (PART_FREEBSD_UFS); case VTOC_TAG_FREEBSD_VINUM: return (PART_FREEBSD_VINUM); case VTOC_TAG_FREEBSD_ZFS: return (PART_FREEBSD_ZFS); }; return (PART_UNKNOWN); } static struct ptable * ptable_vtoc8read(struct ptable *table, void *dev, diskread_t dread) { struct pentry *entry; struct vtoc8 *dl; uint8_t *buf; uint16_t sum, heads, sectors; int i; if (table->sectorsize != sizeof (struct vtoc8)) return (table); buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, 0) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } dl = (struct vtoc8 *)buf; /* Check the sum */ for (i = sum = 0; i < sizeof (struct vtoc8); i += sizeof (sum)) sum ^= be16dec(buf + i); if (sum != 0) { DPRINTF("incorrect checksum"); goto out; } if (be16toh(dl->nparts) != VTOC8_NPARTS) { DPRINTF("invalid number of entries"); goto out; } sectors = be16toh(dl->nsecs); heads = be16toh(dl->nheads); if (sectors * heads == 0) { DPRINTF("invalid geometry"); goto out; } DPRINTF("VTOC8 detected"); for (i = 0; i < VTOC8_NPARTS; i++) { dl->part[i].tag = be16toh(dl->part[i].tag); if (i == VTOC_RAW_PART || dl->part[i].tag == VTOC_TAG_UNASSIGNED) continue; entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = be32toh(dl->map[i].cyl) * heads * sectors; entry->part.end = be32toh(dl->map[i].nblks) + entry->part.start - 1; entry->part.type = vtoc8_parttype(dl->part[i].tag); entry->part.index = i; /* starts from zero */ entry->type.vtoc8 = dl->part[i].tag; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new VTOC8 partition added"); } table->type = PTABLE_VTOC8; out: free(buf); return (table); } #endif /* LOADER_VTOC8_SUPPORT */ static enum partition_type vtoc_parttype(uint16_t type) { switch (type) { case VTOC_TAG_BOOT: return (PART_VTOC_BOOT); case VTOC_TAG_ROOT: return (PART_VTOC_ROOT); case VTOC_TAG_SWAP: return (PART_VTOC_SWAP); case VTOC_TAG_USR: return (PART_VTOC_USR); case VTOC_TAG_BACKUP: return (PART_VTOC_BACKUP); case VTOC_TAG_STAND: return (PART_VTOC_STAND); case VTOC_TAG_VAR: return (PART_VTOC_VAR); case VTOC_TAG_HOME: return (PART_VTOC_HOME); }; return (PART_UNKNOWN); } static struct ptable * ptable_dklabelread(struct ptable *table, void *dev, diskread_t dread) { struct pentry *entry; struct dk_label *dl; struct dk_vtoc *dv; uint8_t *buf; int i; if (table->sectorsize < sizeof (struct dk_label)) { DPRINTF("Too small sectorsize"); return (table); } buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, DK_LABEL_LOC) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } dl = (struct dk_label *)buf; dv = (struct dk_vtoc *)&dl->dkl_vtoc; if (dl->dkl_magic != VTOC_MAGIC) { DPRINTF("dk_label magic error"); goto out; } if (dv->v_sanity != VTOC_SANITY) { DPRINTF("this vtoc is not sane"); goto out; } if (dv->v_nparts != NDKMAP) { DPRINTF("invalid number of entries"); goto out; } DPRINTF("VTOC detected"); for (i = 0; i < NDKMAP; i++) { if (i == VTOC_RAW_PART || /* skip slice 2 and empty */ dv->v_part[i].p_size == 0) continue; entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = dv->v_part[i].p_start; entry->part.end = dv->v_part[i].p_size + entry->part.start - 1; entry->part.type = vtoc_parttype(dv->v_part[i].p_tag); entry->part.index = i; /* starts from zero */ entry->type.vtoc = dv->v_part[i].p_tag; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new VTOC partition added"); } table->type = PTABLE_VTOC; out: free(buf); return (table); } #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize) static struct ptable * ptable_iso9660read(struct ptable *table, void *dev, diskread_t dread) { uint8_t *buf; struct iso_primary_descriptor *vd; struct pentry *entry; buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, cdb2devb(16)) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } vd = (struct iso_primary_descriptor *)buf; if (bcmp(vd->id, ISO_STANDARD_ID, sizeof (vd->id)) != 0) goto out; entry = malloc(sizeof (*entry)); if (entry == NULL) goto out; entry->part.start = 0; entry->part.end = table->sectors; entry->part.type = PART_ISO9660; entry->part.index = 0; STAILQ_INSERT_TAIL(&table->entries, entry, entry); table->type = PTABLE_ISO9660; out: free(buf); return (table); } struct ptable * ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread) { struct dos_partition *dp; struct ptable *table; uint8_t *buf; int i; #ifdef LOADER_MBR_SUPPORT struct pentry *entry; uint32_t start, end; int has_ext; #endif table = NULL; dp = NULL; buf = malloc(sectorsize); if (buf == NULL) return (NULL); /* First, read the MBR. */ if (dread(dev, buf, 1, DOSBBSECTOR) != 0) { DPRINTF("read failed"); goto out; } table = malloc(sizeof (*table)); if (table == NULL) goto out; table->sectors = sectors; table->sectorsize = sectorsize; table->type = PTABLE_NONE; STAILQ_INIT(&table->entries); if (ptable_iso9660read(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_ISO9660) goto out; if (ptable_dklabelread(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_VTOC) goto out; #ifdef LOADER_VTOC8_SUPPORT if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) { if (ptable_vtoc8read(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_VTOC8) goto out; } #endif /* Check the BSD label. */ if (ptable_bsdread(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_BSD) goto out; #if defined(LOADER_GPT_SUPPORT) || defined(LOADER_MBR_SUPPORT) /* Check the MBR magic. */ if (buf[DOSMAGICOFFSET] != 0x55 || buf[DOSMAGICOFFSET + 1] != 0xaa) { DPRINTF("magic sequence not found"); #if defined(LOADER_GPT_SUPPORT) /* There is no PMBR, check that we have backup GPT */ table->type = PTABLE_GPT; table = ptable_gptread(table, dev, dread); #endif goto out; } /* Check that we have PMBR. Also do some validation. */ dp = malloc(NDOSPART * sizeof (struct dos_partition)); if (dp == NULL) goto out; bcopy(buf + DOSPARTOFF, dp, NDOSPART * sizeof (struct dos_partition)); /* * macOS can create PMBR partition in a hybrid MBR; that is, an MBR * partition which has a DOSTYP_PMBR entry defined to start at sector 1. * After the DOSTYP_PMBR, there may be other paritions. A UEFI * compliant PMBR has no other partitions. */ for (i = 0; i < NDOSPART; i++) { if (dp[i].dp_flag != 0 && dp[i].dp_flag != 0x80) { DPRINTF("invalid partition flag %x", dp[i].dp_flag); goto out; } #ifdef LOADER_GPT_SUPPORT if (dp[i].dp_typ == DOSPTYP_PMBR && dp[i].dp_start == 1) { table->type = PTABLE_GPT; DPRINTF("PMBR detected"); } #endif } #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) { table = ptable_gptread(table, dev, dread); goto out; } #endif #ifdef LOADER_MBR_SUPPORT /* Read MBR. */ DPRINTF("MBR detected"); table->type = PTABLE_MBR; for (i = has_ext = 0; i < NDOSPART; i++) { if (dp[i].dp_typ == 0) continue; start = le32dec(&(dp[i].dp_start)); end = le32dec(&(dp[i].dp_size)); if (start == 0 || end == 0) continue; #if 0 /* Some BIOSes return an incorrect number of sectors */ if (start + end - 1 >= sectors) continue; /* XXX: ignore */ #endif if (dp[i].dp_typ == DOSPTYP_EXT || dp[i].dp_typ == DOSPTYP_EXTLBA) has_ext = 1; entry = malloc(sizeof (*entry)); if (entry == NULL) break; entry->part.start = start; entry->part.end = start + end - 1; entry->part.index = i + 1; entry->part.type = mbr_parttype(dp[i].dp_typ); entry->flags = dp[i].dp_flag; entry->type.mbr = dp[i].dp_typ; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new MBR partition added"); } if (has_ext) { table = ptable_ebrread(table, dev, dread); /* FALLTHROUGH */ } #endif /* LOADER_MBR_SUPPORT */ #endif /* LOADER_MBR_SUPPORT || LOADER_GPT_SUPPORT */ out: free(dp); free(buf); return (table); } void ptable_close(struct ptable *table) { struct pentry *entry; if (table == NULL) return; while (!STAILQ_EMPTY(&table->entries)) { entry = STAILQ_FIRST(&table->entries); STAILQ_REMOVE_HEAD(&table->entries, entry); free(entry); } free(table); } enum ptable_type ptable_gettype(const struct ptable *table) { return (table->type); } int ptable_getsize(const struct ptable *table, uint64_t *sizep) { uint64_t tmp = table->sectors * table->sectorsize; if (tmp < table->sectors) return (EOVERFLOW); if (sizep != NULL) *sizep = tmp; return (0); } int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int idx) { struct pentry *entry; if (part == NULL || table == NULL) return (EINVAL); STAILQ_FOREACH(entry, &table->entries, entry) { if (entry->part.index != idx) continue; memcpy(part, &entry->part, sizeof (*part)); return (0); } return (ENOENT); } /* * Search for a slice with the following preferences: * * 1: Active illumos slice * 2: Non-active illumos slice * 3: Active Linux slice * 4: non-active Linux slice * 5: Active FAT/FAT32 slice * 6: non-active FAT/FAT32 slice */ #define PREF_RAWDISK 0 #define PREF_ILLUMOS_ACT 1 #define PREF_ILLUMOS 2 #define PREF_LINUX_ACT 3 #define PREF_LINUX 4 #define PREF_DOS_ACT 5 #define PREF_DOS 6 #define PREF_NONE 7 int ptable_getbestpart(const struct ptable *table, struct ptable_entry *part) { struct pentry *entry, *best; int pref, preflevel; if (part == NULL || table == NULL) return (EINVAL); best = NULL; preflevel = pref = PREF_NONE; STAILQ_FOREACH(entry, &table->entries, entry) { #ifdef LOADER_MBR_SUPPORT if (table->type == PTABLE_MBR) { switch (entry->type.mbr) { case DOSPTYP_SUNIXOS2: pref = entry->flags & 0x80 ? PREF_ILLUMOS_ACT: PREF_ILLUMOS; break; case DOSPTYP_LINUX: pref = entry->flags & 0x80 ? PREF_LINUX_ACT: PREF_LINUX; break; case 0x01: /* DOS/Windows */ case 0x04: case 0x06: case 0x0c: case 0x0e: case DOSPTYP_FAT32: pref = entry->flags & 0x80 ? PREF_DOS_ACT: PREF_DOS; break; default: pref = PREF_NONE; } } #endif /* LOADER_MBR_SUPPORT */ #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) { if (entry->part.type == PART_DOS) pref = PREF_DOS; else if (entry->part.type == PART_ILLUMOS_ZFS) pref = PREF_ILLUMOS; else pref = PREF_NONE; } #endif /* LOADER_GPT_SUPPORT */ if (pref < preflevel) { preflevel = pref; best = entry; } } if (best != NULL) { memcpy(part, &best->part, sizeof (*part)); return (0); } return (ENOENT); } /* * iterate will stop if iterator will return non 0. */ int ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter) { struct pentry *entry; char name[32]; int ret = 0; name[0] = '\0'; STAILQ_FOREACH(entry, &table->entries, entry) { #ifdef LOADER_MBR_SUPPORT if (table->type == PTABLE_MBR) sprintf(name, "s%d", entry->part.index); else #endif #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) sprintf(name, "p%d", entry->part.index); else #endif #ifdef LOADER_VTOC8_SUPPORT if (table->type == PTABLE_VTOC8) sprintf(name, "%c", (uint8_t)'a' + entry->part.index); else #endif if (table->type == PTABLE_VTOC) sprintf(name, "%c", (uint8_t)'a' + entry->part.index); else if (table->type == PTABLE_BSD) sprintf(name, "%c", (uint8_t)'a' + entry->part.index); ret = iter(arg, name, &entry->part); if (ret != 0) return (ret); } return (ret); } /* * Copyright (c) 2012 Andrey V. Elsukov * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 _PART_H_ #define _PART_H_ struct ptable; enum ptable_type { PTABLE_NONE, PTABLE_BSD, PTABLE_MBR, PTABLE_GPT, PTABLE_VTOC8, PTABLE_VTOC, PTABLE_ISO9660 }; enum partition_type { PART_UNKNOWN, PART_EFI, PART_FREEBSD, PART_FREEBSD_BOOT, PART_FREEBSD_UFS, PART_FREEBSD_ZFS, PART_FREEBSD_SWAP, PART_FREEBSD_VINUM, PART_LINUX, PART_LINUX_SWAP, PART_DOS, PART_ISO9660, PART_SOLARIS2, PART_ILLUMOS_UFS, PART_ILLUMOS_ZFS, PART_RESERVED, PART_VTOC_BOOT, PART_VTOC_ROOT, PART_VTOC_SWAP, PART_VTOC_USR, PART_VTOC_BACKUP, PART_VTOC_STAND, PART_VTOC_VAR, PART_VTOC_HOME, PART_APFS }; struct ptable_entry { uint64_t start; uint64_t end; int index; enum partition_type type; }; /* The offset and size are in sectors */ typedef int (diskread_t)(void *arg, void *buf, size_t blocks, uint64_t offset); typedef int (ptable_iterate_t)(void *arg, const char *partname, const struct ptable_entry *part); struct ptable *ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread); void ptable_close(struct ptable *table); enum ptable_type ptable_gettype(const struct ptable *table); int ptable_getsize(const struct ptable *table, uint64_t *sizep); int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index); int ptable_getbestpart(const struct ptable *table, struct ptable_entry *part); int ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter); const char *parttype2str(enum partition_type type); #endif /* !_PART_H_ */ /* * Copyright (c) 2016 M. Warner Losh * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 _PATHS_H_ #define _PATHS_H_ #define PATH_DOTCONFIG "/boot.config" #define PATH_CONFIG "/boot/config" #define PATH_LOADER "/boot/loader" #define PATH_LOADER_EFI "/boot/" LOADER_EFI #define PATH_KERNEL "/boot/kernel/kernel" #endif /* _PATHS_H_ */ /* * mjs copyright * */ #include /* * "Plug and Play" functionality. * * We use the PnP enumerators to obtain identifiers for installed hardware, * and the contents of a database to determine modules to be loaded to support * such hardware. */ #include #include #include #include "ficl.h" static struct pnpinfo_stql pnp_devices; static int pnp_devices_initted = 0; static void pnp_discard(void); /* * Perform complete enumeration sweep */ COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan); static int pnp_scan(int argc, char *argv[]) { struct pnpinfo *pi; int hdlr; int verbose; int ch; if (pnp_devices_initted == 0) { STAILQ_INIT(&pnp_devices); pnp_devices_initted = 1; } verbose = 0; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "v")) != -1) { switch(ch) { case 'v': verbose = 1; break; case '?': default: /* getopt has already reported an error */ return(CMD_OK); } } /* forget anything we think we knew */ pnp_discard(); /* iterate over all of the handlers */ for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) { if (verbose) printf("Probing %s...\n", pnphandlers[hdlr]->pp_name); pnphandlers[hdlr]->pp_enumerate(); } if (verbose) { pager_open(); pager_output("PNP scan summary:\n"); STAILQ_FOREACH(pi, &pnp_devices, pi_link) { pager_output(STAILQ_FIRST(&pi->pi_ident)->id_ident); /* first ident should be canonical */ if (pi->pi_desc != NULL) { pager_output(" : "); pager_output(pi->pi_desc); } pager_output("\n"); } pager_close(); } return(CMD_OK); } /* * Throw away anything we think we know about PnP devices. */ static void pnp_discard(void) { struct pnpinfo *pi; while (STAILQ_FIRST(&pnp_devices) != NULL) { pi = STAILQ_FIRST(&pnp_devices); STAILQ_REMOVE_HEAD(&pnp_devices, pi_link); pnp_freeinfo(pi); } } /* * Add a unique identifier to (pi) */ void pnp_addident(struct pnpinfo *pi, char *ident) { struct pnpident *id; STAILQ_FOREACH(id, &pi->pi_ident, id_link) if (!strcmp(id->id_ident, ident)) return; /* already have this one */ id = malloc(sizeof(struct pnpident)); id->id_ident = strdup(ident); STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link); } /* * Allocate a new pnpinfo struct */ struct pnpinfo * pnp_allocinfo(void) { struct pnpinfo *pi; pi = malloc(sizeof(struct pnpinfo)); bzero(pi, sizeof(struct pnpinfo)); STAILQ_INIT(&pi->pi_ident); return(pi); } /* * Release storage held by a pnpinfo struct */ void pnp_freeinfo(struct pnpinfo *pi) { struct pnpident *id; while (!STAILQ_EMPTY(&pi->pi_ident)) { id = STAILQ_FIRST(&pi->pi_ident); STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link); free(id->id_ident); free(id); } if (pi->pi_desc) free(pi->pi_desc); if (pi->pi_module) free(pi->pi_module); if (pi->pi_argv) free(pi->pi_argv); free(pi); } /* * Add a new pnpinfo struct to the list. */ void pnp_addinfo(struct pnpinfo *pi) { STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link); } /* * Format an EISA id as a string in standard ISA PnP format, AAAIIRR * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID. */ char * pnp_eisaformat(u_int8_t *data) { static char idbuf[8]; const char hextoascii[] = "0123456789abcdef"; idbuf[0] = '@' + ((data[0] & 0x7c) >> 2); idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5)); idbuf[2] = '@' + (data[1] & 0x1f); idbuf[3] = hextoascii[(data[2] >> 4)]; idbuf[4] = hextoascii[(data[2] & 0xf)]; idbuf[5] = hextoascii[(data[3] >> 4)]; idbuf[6] = hextoascii[(data[3] & 0xf)]; idbuf[7] = 0; return(idbuf); } void ficlPnpdevices(ficlVm *pVM) { static int pnp_devices_initted = 0; FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1); if (!pnp_devices_initted) { STAILQ_INIT(&pnp_devices); pnp_devices_initted = 1; } ficlStackPushPointer(ficlVmGetDataStack(pVM), &pnp_devices); } void ficlPnphandlers(ficlVm *pVM) { FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1); ficlStackPushPointer(ficlVmGetDataStack(pVM), pnphandlers); } /* * Glue function to add the appropriate forth words to access pnp BIOS * functionality. */ static void ficlCompilePnp(ficlSystem *pSys) { ficlDictionary *dp = ficlSystemGetDictionary(pSys); FICL_SYSTEM_ASSERT(pSys, dp); ficlDictionarySetPrimitive(dp, "pnpdevices", ficlPnpdevices, FICL_WORD_DEFAULT); ficlDictionarySetPrimitive(dp, "pnphandlers", ficlPnphandlers, FICL_WORD_DEFAULT); } FICL_COMPILE_SET(ficlCompilePnp); /* * Copyright (c) 1998 Robert Nordier * All rights reserved. * * Redistribution and use in source and binary forms are freely * permitted provided that the above copyright notice and this * paragraph and the following disclaimer are duplicated in all * such forms. * * This software is provided "AS IS" and without any express or * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. */ #ifndef _RBX_H_ #define _RBX_H_ #define RBX_ASKNAME 0x0 /* -a */ #define RBX_SINGLE 0x1 /* -s */ /* 0x2 is reserved for log2(RB_NOSYNC). */ /* 0x3 is reserved for log2(RB_HALT). */ /* 0x4 is reserved for log2(RB_INITNAME). */ #define RBX_DFLTROOT 0x5 /* -r */ #define RBX_KDB 0x6 /* -d */ /* 0x7 is reserved for log2(RB_RDONLY). */ /* 0x8 is reserved for log2(RB_DUMP). */ /* 0x9 is reserved for log2(RB_MINIROOT). */ #define RBX_CONFIG 0xa /* -c */ #define RBX_VERBOSE 0xb /* -v */ #define RBX_SERIAL 0xc /* -h */ #define RBX_CDROM 0xd /* -C */ /* 0xe is reserved for log2(RB_POWEROFF). */ #define RBX_GDB 0xf /* -g */ #define RBX_MUTE 0x10 /* -m */ /* 0x11 is reserved for log2(RB_SELFTEST). */ /* 0x12 is reserved for boot programs. */ #define RBX_TEXT_MODE 0x13 /* -t */ #define RBX_PAUSE 0x14 /* -p */ #define RBX_QUIET 0x15 /* -q */ #define RBX_NOINTR 0x1c /* -n */ /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */ #define RBX_DUAL 0x1d /* -D */ /* 0x1f is reserved for log2(RB_BOOTINFO). */ /* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D, -t */ #define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \ OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \ OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \ OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \ OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \ OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL) | \ OPT_SET(RBX_TEXT_MODE)) #define OPT_SET(opt) (1 << (opt)) #define OPT_CHECK(opt) ((opts) & OPT_SET(opt)) extern uint32_t opts; #endif /* !_RBX_H_ */ /*- * Copyright (c) 2003 Jake Burkholder. * Copyright 1996-1998 John D. Polstra. * Copyright (c) 1998 Michael Smith * Copyright (c) 1998 Peter Wemm * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #define FREEBSD_ELF #include #include "bootstrap.h" #define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) /* * Apply a single intra-module relocation to the data. `relbase' is the * target relocation base for the section (i.e. it corresponds to where * r_offset == 0). `dataaddr' is the relocated address corresponding to * the start of the data, and `len' is the number of bytes. */ int __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, int reltype, Elf_Addr relbase, Elf_Addr dataaddr, void *data, size_t len) { #ifdef __sparc__ Elf_Size w; const Elf_Rela *a; switch (reltype) { case ELF_RELOC_RELA: a = reldata; if (relbase + a->r_offset >= dataaddr && relbase + a->r_offset < dataaddr + len) { switch (ELF_R_TYPE(a->r_info)) { case R_SPARC_RELATIVE: w = relbase + a->r_addend; bcopy(&w, (u_char *)data + (relbase + a->r_offset - dataaddr), sizeof(w)); break; default: printf("\nunhandled relocation type %u\n", (u_int)ELF_R_TYPE(a->r_info)); return (EFTYPE); } } break; } return (0); #elif (defined(__i386__) || defined(__amd64__)) && __ELF_WORD_SIZE == 64 Elf64_Addr *where, val; Elf_Addr addend, addr; Elf_Size rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; switch (reltype) { case ELF_RELOC_REL: rel = (const Elf_Rel *)reldata; where = (Elf_Addr *)((char *)data + relbase + rel->r_offset - dataaddr); addend = 0; rtype = ELF_R_TYPE(rel->r_info); symidx = ELF_R_SYM(rel->r_info); addend = 0; break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)reldata; where = (Elf_Addr *)((char *)data + relbase + rela->r_offset - dataaddr); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); symidx = ELF_R_SYM(rela->r_info); break; default: return (EINVAL); } if ((char *)where < (char *)data || (char *)where >= (char *)data + len) return (0); if (reltype == ELF_RELOC_REL) addend = *where; /* XXX, definitions not available on i386. */ #define R_X86_64_64 1 #define R_X86_64_RELATIVE 8 switch (rtype) { case R_X86_64_64: /* S + A */ addr = symaddr(ef, symidx); if (addr == 0) return (ESRCH); val = addr + addend; *where = val; break; case R_X86_64_RELATIVE: addr = (Elf_Addr)addend + relbase; val = addr; *where = val; break; default: printf("\nunhandled relocation type %u\n", (u_int)rtype); return (EFTYPE); } return (0); #elif defined(__i386__) && __ELF_WORD_SIZE == 32 Elf_Addr addend, addr, *where, val; Elf_Size rtype, symidx; const Elf_Rel *rel; const Elf_Rela *rela; switch (reltype) { case ELF_RELOC_REL: rel = (const Elf_Rel *)reldata; where = (Elf_Addr *)((char *)data + relbase + rel->r_offset - dataaddr); addend = 0; rtype = ELF_R_TYPE(rel->r_info); symidx = ELF_R_SYM(rel->r_info); addend = 0; break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)reldata; where = (Elf_Addr *)((char *)data + relbase + rela->r_offset - dataaddr); addend = rela->r_addend; rtype = ELF_R_TYPE(rela->r_info); symidx = ELF_R_SYM(rela->r_info); break; default: return (EINVAL); } if ((char *)where < (char *)data || (char *)where >= (char *)data + len) return (0); if (reltype == ELF_RELOC_REL) addend = *where; /* XXX, definitions not available on amd64. */ #define R_386_32 1 /* Add symbol value. */ #define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ #define R_386_RELATIVE 8 /* Add load address of shared object. */ switch (rtype) { case R_386_RELATIVE: addr = addend + relbase; *where = addr; break; case R_386_32: /* S + A */ addr = symaddr(ef, symidx); if (addr == 0) return (ESRCH); val = addr + addend; *where = val; break; default: printf("\nunhandled relocation type %u\n", (u_int)rtype); return (EFTYPE); } return (0); #elif defined(__powerpc__) Elf_Size w; const Elf_Rela *rela; switch (reltype) { case ELF_RELOC_RELA: rela = reldata; if (relbase + rela->r_offset >= dataaddr && relbase + rela->r_offset < dataaddr + len) { switch (ELF_R_TYPE(rela->r_info)) { case R_PPC_RELATIVE: w = relbase + rela->r_addend; bcopy(&w, (u_char *)data + (relbase + rela->r_offset - dataaddr), sizeof(w)); break; default: printf("\nunhandled relocation type %u\n", (u_int)ELF_R_TYPE(rela->r_info)); return (EFTYPE); } } break; } return (0); #else (void)ef; (void)symaddr; (void)reldata; (void)reltype; (void)relbase; (void)dataaddr; (void)data; (void)len; return (EOPNOTSUPP); #endif } #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 32 #include "reloc_elf.c" #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include "reloc_elf.c" /*- * Copyright (c) 2008-2010 Rui Paulo * All rights reserved. * * 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. * * 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. */ #include #include #include #include #if defined(__aarch64__) || defined(__amd64__) #define ElfW_Rel Elf64_Rela #define ElfW_Dyn Elf64_Dyn #define ELFW_R_TYPE ELF64_R_TYPE #define ELF_RELA #elif defined(__arm__) || defined(__i386__) #define ElfW_Rel Elf32_Rel #define ElfW_Dyn Elf32_Dyn #define ELFW_R_TYPE ELF32_R_TYPE #else #error architecture not supported #endif #if defined(__aarch64__) #define RELOC_TYPE_NONE R_AARCH64_NONE #define RELOC_TYPE_RELATIVE R_AARCH64_RELATIVE #elif defined(__amd64__) #define RELOC_TYPE_NONE R_X86_64_NONE #define RELOC_TYPE_RELATIVE R_X86_64_RELATIVE #elif defined(__arm__) #define RELOC_TYPE_NONE R_ARM_NONE #define RELOC_TYPE_RELATIVE R_ARM_RELATIVE #elif defined(__i386__) #define RELOC_TYPE_NONE R_386_NONE #define RELOC_TYPE_RELATIVE R_386_RELATIVE #endif void self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic); /* * A simple elf relocator. */ void self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic) { Elf_Word relsz, relent; Elf_Addr *newaddr; ElfW_Rel *rel = 0; ElfW_Dyn *dynp; /* * Find the relocation address, its size and the relocation entry. */ relsz = 0; relent = 0; for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) { switch (dynp->d_tag) { case DT_REL: case DT_RELA: rel = (ElfW_Rel *)(dynp->d_un.d_ptr + baseaddr); break; case DT_RELSZ: case DT_RELASZ: relsz = dynp->d_un.d_val; break; case DT_RELENT: case DT_RELAENT: relent = dynp->d_un.d_val; break; default: break; } } /* * Perform the actual relocation. We rely on the object having been * linked at 0, so that the difference between the load and link * address is the same as the load address. */ for (; relsz > 0; relsz -= relent) { switch (ELFW_R_TYPE(rel->r_info)) { case RELOC_TYPE_NONE: /* No relocation needs be performed. */ break; case RELOC_TYPE_RELATIVE: newaddr = (Elf_Addr *)(rel->r_offset + baseaddr); #ifdef ELF_RELA /* Addend relative to the base address. */ *newaddr = baseaddr + rel->r_addend; #else /* Address relative to the base address. */ *newaddr += baseaddr; #endif break; default: /* XXX: do we need other relocations ? */ break; } rel = (ElfW_Rel *)(void *)((caddr_t) rel + relent); } } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2016 Joyent, Inc. * Copyright 2021 Toomas Soome * Copyright 2021 RackTop Systems, Inc. */ /* * ANSI terminal emulator module; parse ANSI X3.64 escape sequences and * the like. * * How Virtual Terminal Emulator Works: * * Every virtual terminal is associated with a tem_vt_state structure * and maintains a virtual screen buffer in tvs_screen_buf, which contains * all the characters which should be shown on the physical screen when * the terminal is activated. * * Data written to a virtual terminal is composed of characters which * should be displayed on the screen when this virtual terminal is * activated, fg/bg colors of these characters, and other control * information (escape sequence, etc). * * When data is passed to a virtual terminal it first is parsed for * control information by tem_parse(). Subsequently the character * and color data are written to tvs_screen_buf. * They are saved in buffer in order to refresh the screen when this * terminal is activated. If the terminal is currently active, the data * (characters and colors) are also written to the physical screen by * invoking a callback function, tem_text_callbacks() or tem_pix_callbacks(). * * When rendering data to the framebuffer, if the framebuffer is in * VIS_PIXEL mode, the character data will first be converted to pixel * data using tem_pix_bit2pix(), and then the pixels get displayed * on the physical screen. We only store the character and color data in * tem_vt_state since the bit2pix conversion only happens when actually * rendering to the physical framebuffer. * * Color support: * Text mode can only support standard system colors, 4-bit [0-15] indexed. * On framebuffer devices, we can aditionally use [16-255] or truecolor. * Additional colors can be used via CSI 38 and CSI 48 sequences. * CSI 38/48;5 is using indexed colors [0-255], CSI 38/48;2 does * specify color by RGB triple. * * While sending glyphs to display, we need to process glyph attributes: * TEM_ATTR_BOLD will cause BOLD font to be used (or BRIGHT color if we * we use indexed color [0-7]). * We ignore TEM_ATTR_BRIGHT_FG/TEM_ATTR_BRIGHT_BG with RGB colors. * TEM_ATTR_REVERSE and TEM_ATTR_SCREEN_REVERSE will cause fg and bg to be * swapped. */ #include #include #include #include #ifdef _HAVE_TEM_FIRMWARE #include #endif /* _HAVE_TEM_FIRMWARE */ #include #include #include /* Terminal emulator internal helper functions */ static void tems_setup_terminal(struct vis_devinit *, size_t, size_t); static void tems_modechange_callback(struct vis_modechg_arg *, struct vis_devinit *); static void tems_reset_colormap(void); static void tem_free_buf(struct tem_vt_state *); static void tem_internal_init(struct tem_vt_state *, bool, bool); static void tems_get_initial_color(tem_color_t *pcolor); static void tem_control(struct tem_vt_state *, uint8_t); static void tem_setparam(struct tem_vt_state *, int, int); static void tem_selgraph(struct tem_vt_state *); static void tem_chkparam(struct tem_vt_state *, uint8_t); static void tem_getparams(struct tem_vt_state *, uint8_t); static void tem_outch(struct tem_vt_state *, tem_char_t); static void tem_parse(struct tem_vt_state *, tem_char_t); static void tem_new_line(struct tem_vt_state *); static void tem_cr(struct tem_vt_state *); static void tem_lf(struct tem_vt_state *); static void tem_send_data(struct tem_vt_state *); static void tem_cls(struct tem_vt_state *); static void tem_tab(struct tem_vt_state *); static void tem_back_tab(struct tem_vt_state *); static void tem_clear_tabs(struct tem_vt_state *, int); static void tem_set_tab(struct tem_vt_state *); static void tem_mv_cursor(struct tem_vt_state *, int, int); static void tem_shift(struct tem_vt_state *, int, int); static void tem_scroll(struct tem_vt_state *, int, int, int, int); static void tem_clear_chars(struct tem_vt_state *tem, int count, screen_pos_t row, screen_pos_t col); static void tem_copy_area(struct tem_vt_state *tem, screen_pos_t s_col, screen_pos_t s_row, screen_pos_t e_col, screen_pos_t e_row, screen_pos_t t_col, screen_pos_t t_row); static void tem_bell(struct tem_vt_state *tem); static void tem_pix_clear_prom_output(struct tem_vt_state *tem); static void tem_virtual_cls(struct tem_vt_state *, size_t, screen_pos_t, screen_pos_t); static void tem_virtual_display(struct tem_vt_state *, term_char_t *, size_t, screen_pos_t, screen_pos_t); static void tem_align_cursor(struct tem_vt_state *tem); static void tem_check_first_time(struct tem_vt_state *tem); static void tem_reset_display(struct tem_vt_state *, bool, bool); static void tem_terminal_emulate(struct tem_vt_state *, uint8_t *, int); static void tem_text_cursor(struct tem_vt_state *, short); static void tem_text_cls(struct tem_vt_state *, int count, screen_pos_t row, screen_pos_t col); static void tem_pix_display(struct tem_vt_state *, term_char_t *, int, screen_pos_t, screen_pos_t); static void tem_pix_copy(struct tem_vt_state *, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t); static void tem_pix_cursor(struct tem_vt_state *, short); static void tem_get_attr(struct tem_vt_state *, text_color_t *, text_color_t *, text_attr_t *, uint8_t); static void tem_get_color(struct tem_vt_state *, text_color_t *, text_color_t *, term_char_t *); static void tem_set_color(text_color_t *, color_t *); static void tem_pix_align(struct tem_vt_state *); static void tem_text_display(struct tem_vt_state *, term_char_t *, int, screen_pos_t, screen_pos_t); static void tem_text_copy(struct tem_vt_state *, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t); static void tem_pix_bit2pix(struct tem_vt_state *, term_char_t *); static void tem_pix_cls_range(struct tem_vt_state *, screen_pos_t, int, int, screen_pos_t, int, int, bool); static void tem_pix_cls(struct tem_vt_state *, int, screen_pos_t, screen_pos_t); static void bit_to_pix32(struct tem_vt_state *tem, tem_char_t c, text_color_t fg_color, text_color_t bg_color); /* * Globals */ tem_state_t tems; /* common term info */ tem_callbacks_t tem_text_callbacks = { .tsc_display = &tem_text_display, .tsc_copy = &tem_text_copy, .tsc_cursor = &tem_text_cursor, .tsc_bit2pix = NULL, .tsc_cls = &tem_text_cls }; tem_callbacks_t tem_pix_callbacks = { .tsc_display = &tem_pix_display, .tsc_copy = &tem_pix_copy, .tsc_cursor = &tem_pix_cursor, .tsc_bit2pix = &tem_pix_bit2pix, .tsc_cls = &tem_pix_cls }; #define tem_callback_display (*tems.ts_callbacks->tsc_display) #define tem_callback_copy (*tems.ts_callbacks->tsc_copy) #define tem_callback_cursor (*tems.ts_callbacks->tsc_cursor) #define tem_callback_cls (*tems.ts_callbacks->tsc_cls) #define tem_callback_bit2pix (*tems.ts_callbacks->tsc_bit2pix) static void tem_add(struct tem_vt_state *tem) { list_insert_head(&tems.ts_list, tem); } /* * This is the main entry point to the module. It handles output requests * during normal system operation, when (e.g.) mutexes are available. */ void tem_write(tem_vt_state_t tem_arg, uint8_t *buf, ssize_t len) { struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg; if (tems.ts_initialized == 0 || tem->tvs_initialized == 0) { return; } tem_check_first_time(tem); tem_terminal_emulate(tem, buf, len); } static void tem_internal_init(struct tem_vt_state *ptem, bool init_color, bool clear_screen) { size_t size, width, height; if (tems.ts_display_mode == VIS_PIXEL) { ptem->tvs_pix_data_size = tems.ts_pix_data_size; ptem->tvs_pix_data = malloc(ptem->tvs_pix_data_size); } ptem->tvs_stateflags = TVS_AUTOWRAP; width = tems.ts_c_dimension.width; height = tems.ts_c_dimension.height; size = width * sizeof (tem_char_t); ptem->tvs_outbuf = malloc(size); if (ptem->tvs_outbuf == NULL) panic("out of memory in tem_internal_init()\n"); ptem->tvs_maxtab = width / 8; ptem->tvs_tabs = calloc(ptem->tvs_maxtab, sizeof (*ptem->tvs_tabs)); if (ptem->tvs_tabs == NULL) panic("out of memory in tem_internal_init()\n"); tem_reset_display(ptem, clear_screen, init_color); ptem->tvs_utf8_left = 0; ptem->tvs_utf8_partial = 0; ptem->tvs_initialized = true; /* * Out of memory is not fatal there, without the screen history, * we can not optimize the screen copy. */ size = width * height * sizeof (term_char_t); ptem->tvs_screen_buf = malloc(size); tem_virtual_cls(ptem, width * height, 0, 0); } int tem_initialized(tem_vt_state_t tem_arg) { struct tem_vt_state *ptem = (struct tem_vt_state *)tem_arg; return (ptem->tvs_initialized); } tem_vt_state_t tem_init(void) { struct tem_vt_state *ptem; ptem = calloc(1, sizeof (struct tem_vt_state)); if (ptem == NULL) return ((tem_vt_state_t)ptem); ptem->tvs_isactive = false; ptem->tvs_fbmode = KD_TEXT; /* * A tem is regarded as initialized only after tem_internal_init(), * will be set at the end of tem_internal_init(). */ ptem->tvs_initialized = 0; if (!tems.ts_initialized) { /* * Only happens during early console configuration. */ tem_add(ptem); return ((tem_vt_state_t)ptem); } tem_internal_init(ptem, true, false); tem_add(ptem); return ((tem_vt_state_t)ptem); } /* * re-init the tem after video mode has changed and tems_info has * been re-inited. */ static void tem_reinit(struct tem_vt_state *tem, bool reset_display) { tem_free_buf(tem); /* only free virtual buffers */ /* reserve color */ tem_internal_init(tem, false, reset_display); } static void tem_free_buf(struct tem_vt_state *tem) { free(tem->tvs_outbuf); tem->tvs_outbuf = NULL; free(tem->tvs_pix_data); tem->tvs_pix_data = NULL; free(tem->tvs_screen_buf); tem->tvs_screen_buf = NULL; free(tem->tvs_tabs); tem->tvs_tabs = NULL; } static int tems_failed(bool finish_ioctl) { if (finish_ioctl && tems.ts_hdl != NULL) (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_DEVFINI, NULL); tems.ts_hdl = NULL; return (ENXIO); } /* * Only called once during boot */ int tem_info_init(struct console *cp) { int ret; struct vis_devinit temargs; size_t height = 0; size_t width = 0; struct tem_vt_state *p; if (tems.ts_initialized) { return (0); } list_create(&tems.ts_list, sizeof (struct tem_vt_state), __offsetof(struct tem_vt_state, tvs_list_node)); tems.ts_active = NULL; tems.ts_hdl = cp; bzero(&temargs, sizeof (temargs)); temargs.modechg_cb = (vis_modechg_cb_t)tems_modechange_callback; temargs.modechg_arg = NULL; /* * Initialize the console and get the device parameters */ if (cp->c_ioctl(cp, VIS_DEVINIT, &temargs) != 0) { printf("terminal emulator: Compatible fb not found\n"); ret = tems_failed(false); return (ret); } /* Make sure the fb driver and terminal emulator versions match */ if (temargs.version != VIS_CONS_REV) { printf( "terminal emulator: VIS_CONS_REV %d (see sys/visual_io.h) " "of console fb driver not supported\n", temargs.version); ret = tems_failed(true); return (ret); } /* other sanity checks */ if (!((temargs.depth == 4) || (temargs.depth == 8) || (temargs.depth == 15) || (temargs.depth == 16) || (temargs.depth == 24) || (temargs.depth == 32))) { printf("terminal emulator: unsupported depth\n"); ret = tems_failed(true); return (ret); } if ((temargs.mode != VIS_TEXT) && (temargs.mode != VIS_PIXEL)) { printf("terminal emulator: unsupported mode\n"); ret = tems_failed(true); return (ret); } plat_tem_get_prom_size(&height, &width); /* * Initialize the common terminal emulator info */ tems_setup_terminal(&temargs, height, width); tems_reset_colormap(); tems_get_initial_color(&tems.ts_init_color); tems.ts_initialized = 1; /* initialization flag */ for (p = list_head(&tems.ts_list); p != NULL; p = list_next(&tems.ts_list, p)) { tem_internal_init(p, true, false); if (temargs.mode == VIS_PIXEL) tem_pix_align(p); } return (0); } #define TEMS_DEPTH_DIFF 0x01 #define TEMS_DIMENSION_DIFF 0x02 static uint8_t tems_check_videomode(struct vis_devinit *tp) { uint8_t result = 0; if (tems.ts_pdepth != tp->depth) result |= TEMS_DEPTH_DIFF; if (tp->mode == VIS_TEXT) { if (tems.ts_c_dimension.width != tp->width || tems.ts_c_dimension.height != tp->height) result |= TEMS_DIMENSION_DIFF; } else { if (tems.ts_p_dimension.width != tp->width || tems.ts_p_dimension.height != tp->height) result |= TEMS_DIMENSION_DIFF; } if (tems.update_font == true) result |= TEMS_DIMENSION_DIFF; return (result); } static int env_screen_nounset(struct env_var *ev __unused) { if (tems.ts_p_dimension.width == 0 && tems.ts_p_dimension.height == 0) return (0); return (EPERM); } static void tems_setup_font(screen_size_t height, screen_size_t width) { bitmap_data_t *font_data; /* * set_font() will select an appropriate sized font for * the number of rows and columns selected. If we don't * have a font that will fit, then it will use the * default builtin font and adjust the rows and columns * to fit on the screen. */ font_data = set_font(&tems.ts_c_dimension.height, &tems.ts_c_dimension.width, height, width); if (font_data == NULL) panic("out of memory"); /* * To use loaded font, we assign the loaded font data to tems.ts_font. * In case of next load, the previously loaded data is freed * when loading the new font. */ for (int i = 0; i < VFNT_MAPS; i++) { tems.ts_font.vf_map[i] = font_data->font->vf_map[i]; tems.ts_font.vf_map_count[i] = font_data->font->vf_map_count[i]; } tems.ts_font.vf_bytes = font_data->font->vf_bytes; tems.ts_font.vf_width = font_data->font->vf_width; tems.ts_font.vf_height = font_data->font->vf_height; } static void tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) { char env[8]; tems.ts_pdepth = tp->depth; tems.ts_linebytes = tp->linebytes; tems.ts_display_mode = tp->mode; tems.ts_color_map = tp->color_map; switch (tp->mode) { case VIS_TEXT: /* Set fake pixel dimensions to assist set_font() */ tems.ts_p_dimension.width = 0; tems.ts_p_dimension.height = 0; tems.ts_c_dimension.width = tp->width; tems.ts_c_dimension.height = tp->height; tems.ts_callbacks = &tem_text_callbacks; tems_setup_font(16 * tp->height + BORDER_PIXELS, 8 * tp->width + BORDER_PIXELS); /* ensure the following are not set for text mode */ unsetenv("screen-height"); unsetenv("screen-width"); break; case VIS_PIXEL: /* * First check to see if the user has specified a screen size. * If so, use those values. Else use 34x80 as the default. */ if (width == 0) { width = TEM_DEFAULT_COLS; height = TEM_DEFAULT_ROWS; } tems.ts_c_dimension.height = (screen_size_t)height; tems.ts_c_dimension.width = (screen_size_t)width; tems.ts_p_dimension.height = tp->height; tems.ts_p_dimension.width = tp->width; tems.ts_callbacks = &tem_pix_callbacks; tems_setup_font(tp->height, tp->width); snprintf(env, sizeof (env), "%d", tems.ts_p_dimension.height); env_setenv("screen-height", EV_VOLATILE | EV_NOHOOK, env, env_noset, env_screen_nounset); snprintf(env, sizeof (env), "%d", tems.ts_p_dimension.width); env_setenv("screen-width", EV_VOLATILE | EV_NOHOOK, env, env_noset, env_screen_nounset); tems.ts_p_offset.y = (tems.ts_p_dimension.height - (tems.ts_c_dimension.height * tems.ts_font.vf_height)) / 2; tems.ts_p_offset.x = (tems.ts_p_dimension.width - (tems.ts_c_dimension.width * tems.ts_font.vf_width)) / 2; tems.ts_pix_data_size = tems.ts_font.vf_width * tems.ts_font.vf_height; tems.ts_pix_data_size *= 4; tems.ts_pdepth = tp->depth; break; } tems.update_font = false; snprintf(env, sizeof (env), "%d", tems.ts_c_dimension.height); env_setenv("screen-#rows", EV_VOLATILE | EV_NOHOOK, env, env_noset, env_nounset); snprintf(env, sizeof (env), "%d", tems.ts_c_dimension.width); env_setenv("screen-#cols", EV_VOLATILE | EV_NOHOOK, env, env_noset, env_nounset); snprintf(env, sizeof (env), "%dx%d", tems.ts_font.vf_width, tems.ts_font.vf_height); env_setenv("screen-font", EV_VOLATILE | EV_NOHOOK, env, NULL, NULL); } /* * This is a callback function that we register with the frame * buffer driver layered underneath. It gets invoked from * the underlying frame buffer driver to reconfigure the terminal * emulator to a new screen size and depth in conjunction with * framebuffer videomode changes. * Here we keep the foreground/background color and attributes, * which may be different with the initial settings, so that * the color won't change while the framebuffer videomode changes. * And we also reset the kernel terminal emulator and clear the * whole screen. */ /* ARGSUSED */ void tems_modechange_callback(struct vis_modechg_arg *arg __unused, struct vis_devinit *devinit) { uint8_t diff; struct tem_vt_state *p; tem_modechg_cb_t cb; tem_modechg_cb_arg_t cb_arg; size_t height = 0; size_t width = 0; int state; diff = tems_check_videomode(devinit); if (diff == 0) { /* * This is color related change, reset color and redraw the * screen. Only need to reinit the active tem. */ struct tem_vt_state *active = tems.ts_active; tems_get_initial_color(&tems.ts_init_color); active->tvs_fg_color = tems.ts_init_color.fg_color; active->tvs_bg_color = tems.ts_init_color.bg_color; active->tvs_flags = tems.ts_init_color.a_flags; tem_reinit(active, true); return; } diff = diff & TEMS_DIMENSION_DIFF; if (diff == 0) { /* * Only need to reinit the active tem. */ struct tem_vt_state *active = tems.ts_active; tems.ts_pdepth = devinit->depth; /* color depth did change, reset colors */ tems_reset_colormap(); tems_get_initial_color(&tems.ts_init_color); tem_reinit(active, true); return; } plat_tem_get_prom_size(&height, &width); state = tems.ts_initialized; tems.ts_initialized = 0; /* stop all output */ tems_setup_terminal(devinit, height, width); tems_reset_colormap(); tems_get_initial_color(&tems.ts_init_color); tems.ts_initialized = state; /* restore state */ for (p = list_head(&tems.ts_list); p != NULL; p = list_next(&tems.ts_list, p)) { tem_reinit(p, p->tvs_isactive); } if (tems.ts_modechg_cb == NULL) { return; } cb = tems.ts_modechg_cb; cb_arg = tems.ts_modechg_arg; cb(cb_arg); } /* * This function is used to clear entire screen via the underlying framebuffer * driver. */ int tems_cls(struct vis_consclear *pda) { if (tems.ts_hdl == NULL) return (1); return (tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_CONSCLEAR, pda)); } /* * This function is used to display a rectangular blit of data * of a given size and location via the underlying framebuffer driver. * The blit can be as small as a pixel or as large as the screen. */ void tems_display(struct vis_consdisplay *pda) { if (tems.ts_hdl != NULL) (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_CONSDISPLAY, pda); } /* * This function is used to invoke a block copy operation in the * underlying framebuffer driver. Rectangle copies are how scrolling * is implemented, as well as horizontal text shifting escape seqs. * such as from vi when deleting characters and words. */ void tems_copy(struct vis_conscopy *pma) { if (tems.ts_hdl != NULL) (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_CONSCOPY, pma); } /* * This function is used to show or hide a rectangluar monochrom * pixel inverting, text block cursor via the underlying framebuffer. */ void tems_cursor(struct vis_conscursor *pca) { if (tems.ts_hdl != NULL) (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_CONSCURSOR, pca); } static void tem_kdsetmode(int mode) { if (tems.ts_hdl != NULL) { (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, KDSETMODE, (void *)(intptr_t)mode); } } static void tems_reset_colormap(void) { struct vis_cmap cm; switch (tems.ts_pdepth) { case 8: cm.index = 0; cm.count = 16; /* 8-bits (1/3 of TrueColor 24) */ cm.red = (uint8_t *)cmap4_to_24.red; /* 8-bits (1/3 of TrueColor 24) */ cm.blue = (uint8_t *)cmap4_to_24.blue; /* 8-bits (1/3 of TrueColor 24) */ cm.green = (uint8_t *)cmap4_to_24.green; if (tems.ts_hdl != NULL) (void) tems.ts_hdl->c_ioctl(tems.ts_hdl, VIS_PUTCMAP, &cm); break; } } void tem_get_size(uint16_t *r, uint16_t *c, uint16_t *x, uint16_t *y) { *r = (uint16_t)tems.ts_c_dimension.height; *c = (uint16_t)tems.ts_c_dimension.width; *x = (uint16_t)tems.ts_p_dimension.width; *y = (uint16_t)tems.ts_p_dimension.height; } /* * Loader extension. Store important data in environment. Intended to be used * just before booting the OS to make the data available in kernel * environment module. */ void tem_save_state(void) { struct tem_vt_state *active = tems.ts_active; char buf[80]; /* * We already have in environment: * tem.inverse, tem.inverse_screen * tem.fg_color, tem.bg_color. * So we only need to add the position of the cursor. */ if (active != NULL) { snprintf(buf, sizeof (buf), "%d", active->tvs_c_cursor.col); setenv("tem.cursor.col", buf, 1); snprintf(buf, sizeof (buf), "%d", active->tvs_c_cursor.row); setenv("tem.cursor.row", buf, 1); } } void tem_register_modechg_cb(tem_modechg_cb_t func, tem_modechg_cb_arg_t arg) { tems.ts_modechg_cb = func; tems.ts_modechg_arg = arg; } /* * This function is to scroll up the OBP output, which has * different screen height and width with our kernel console. */ static void tem_prom_scroll_up(struct tem_vt_state *tem, int nrows) { struct vis_conscopy ma; int ncols, width; /* copy */ ma.s_row = nrows * tems.ts_font.vf_height; ma.e_row = tems.ts_p_dimension.height - 1; ma.t_row = 0; ma.s_col = 0; ma.e_col = tems.ts_p_dimension.width - 1; ma.t_col = 0; tems_copy(&ma); /* clear */ width = tems.ts_font.vf_width; ncols = (tems.ts_p_dimension.width + (width - 1)) / width; tem_pix_cls_range(tem, 0, nrows, tems.ts_p_offset.y, 0, ncols, 0, true); } /* * This function is to compute the starting row of the console, according to * PROM cursor's position. Here we have to take different fonts into account. */ static int tem_adjust_row(struct tem_vt_state *tem, int prom_row) { int tem_row; int tem_y; int prom_charheight = 0; int prom_window_top = 0; int scroll_up_lines; plat_tem_get_prom_font_size(&prom_charheight, &prom_window_top); if (prom_charheight == 0) prom_charheight = tems.ts_font.vf_height; tem_y = (prom_row + 1) * prom_charheight + prom_window_top - tems.ts_p_offset.y; tem_row = (tem_y + tems.ts_font.vf_height - 1) / tems.ts_font.vf_height - 1; if (tem_row < 0) { tem_row = 0; } else if (tem_row >= (tems.ts_c_dimension.height - 1)) { /* * Scroll up the prom outputs if the PROM cursor's position is * below our tem's lower boundary. */ scroll_up_lines = tem_row - (tems.ts_c_dimension.height - 1); tem_prom_scroll_up(tem, scroll_up_lines); tem_row = tems.ts_c_dimension.height - 1; } return (tem_row); } static void tem_pix_align(struct tem_vt_state *tem) { uint32_t row = 0; uint32_t col = 0; if (plat_stdout_is_framebuffer()) { plat_tem_hide_prom_cursor(); /* * We are getting the current cursor position in pixel * mode so that we don't over-write the console output * during boot. */ plat_tem_get_prom_pos(&row, &col); /* * Adjust the row if necessary when the font of our * kernel console tem is different with that of prom * tem. */ row = tem_adjust_row(tem, row); /* first line of our kernel console output */ tem->tvs_first_line = row + 1; /* re-set and align cursor position */ tem->tvs_s_cursor.row = tem->tvs_c_cursor.row = (screen_pos_t)row; tem->tvs_s_cursor.col = tem->tvs_c_cursor.col = 0; } else { tem_reset_display(tem, true, true); } } static void tems_get_inverses(bool *p_inverse, bool *p_inverse_screen) { int i_inverse = 0; int i_inverse_screen = 0; plat_tem_get_inverses(&i_inverse, &i_inverse_screen); *p_inverse = i_inverse != 0; *p_inverse_screen = i_inverse_screen != 0; } /* * Get the foreground/background color and attributes from environment. */ static void tems_get_initial_color(tem_color_t *pcolor) { bool inverse, inverse_screen; unsigned short flags = 0; uint8_t fg, bg; fg = DEFAULT_ANSI_FOREGROUND; bg = DEFAULT_ANSI_BACKGROUND; plat_tem_get_colors(&fg, &bg); pcolor->fg_color.n = fg; pcolor->bg_color.n = bg; tems_get_inverses(&inverse, &inverse_screen); if (inverse) flags |= TEM_ATTR_REVERSE; if (inverse_screen) flags |= TEM_ATTR_SCREEN_REVERSE; if (flags != 0) { /* * The reverse attribute is set. * In case of black on white we want bright white for BG. */ if (pcolor->fg_color.n == ANSI_COLOR_WHITE) flags |= TEM_ATTR_BRIGHT_BG; /* * For white on black, unset the bright attribute we * had set to have bright white background. */ if (pcolor->fg_color.n == ANSI_COLOR_BLACK) flags &= ~TEM_ATTR_BRIGHT_BG; } else { /* * In case of black on white we want bright white for BG. */ if (pcolor->bg_color.n == ANSI_COLOR_WHITE) flags |= TEM_ATTR_BRIGHT_BG; } pcolor->a_flags = flags; } void tem_activate(tem_vt_state_t tem_arg, bool unblank) { struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg; tems.ts_active = tem; tem->tvs_isactive = true; tem_kdsetmode(tem->tvs_fbmode); if (unblank) tem_cls(tem); } static void tem_check_first_time(struct tem_vt_state *tem) { static int first_time = 1; /* * Realign the console cursor. We did this in tem_init(). * However, drivers in the console stream may emit additional * messages before we are ready. This causes text overwrite * on the screen. This is a workaround. */ if (!first_time) return; first_time = 0; if (tems.ts_display_mode == VIS_TEXT) tem_text_cursor(tem, VIS_GET_CURSOR); else tem_pix_cursor(tem, VIS_GET_CURSOR); tem_align_cursor(tem); } /* Process partial UTF-8 sequence. */ static void tem_input_partial(struct tem_vt_state *tem) { unsigned i; tem_char_t c; if (tem->tvs_utf8_left == 0) return; for (i = 0; i < sizeof (tem->tvs_utf8_partial); i++) { c = (tem->tvs_utf8_partial >> (24 - (i << 3))) & 0xff; if (c != 0) { tem_parse(tem, c); } } tem->tvs_utf8_left = 0; tem->tvs_utf8_partial = 0; } /* * Handle UTF-8 sequences. */ static void tem_input_byte(struct tem_vt_state *tem, uint8_t c) { /* * Check for UTF-8 code points. In case of error fall back to * 8-bit code. As we only have 8859-1 fonts for console, this will set * the limits on what chars we actually can display, therefore we * have to return to this code once we have solved the font issue. */ if ((c & 0x80) == 0x00) { /* One-byte sequence. */ tem_input_partial(tem); tem_parse(tem, c); return; } if ((c & 0xe0) == 0xc0) { /* Two-byte sequence. */ tem_input_partial(tem); tem->tvs_utf8_left = 1; tem->tvs_utf8_partial = c; return; } if ((c & 0xf0) == 0xe0) { /* Three-byte sequence. */ tem_input_partial(tem); tem->tvs_utf8_left = 2; tem->tvs_utf8_partial = c; return; } if ((c & 0xf8) == 0xf0) { /* Four-byte sequence. */ tem_input_partial(tem); tem->tvs_utf8_left = 3; tem->tvs_utf8_partial = c; return; } if ((c & 0xc0) == 0x80) { /* Invalid state? */ if (tem->tvs_utf8_left == 0) { tem_parse(tem, c); return; } tem->tvs_utf8_left--; tem->tvs_utf8_partial = (tem->tvs_utf8_partial << 8) | c; if (tem->tvs_utf8_left == 0) { tem_char_t v, u; uint8_t b; /* * Transform the sequence of 2 to 4 bytes to * unicode number. */ v = 0; u = tem->tvs_utf8_partial; b = (u >> 24) & 0xff; if (b != 0) { /* Four-byte sequence */ v = b & 0x07; b = (u >> 16) & 0xff; v = (v << 6) | (b & 0x3f); b = (u >> 8) & 0xff; v = (v << 6) | (b & 0x3f); b = u & 0xff; v = (v << 6) | (b & 0x3f); } else if ((b = (u >> 16) & 0xff) != 0) { v = b & 0x0f; /* Three-byte sequence */ b = (u >> 8) & 0xff; v = (v << 6) | (b & 0x3f); b = u & 0xff; v = (v << 6) | (b & 0x3f); } else if ((b = (u >> 8) & 0xff) != 0) { v = b & 0x1f; /* Two-byte sequence */ b = u & 0xff; v = (v << 6) | (b & 0x3f); } tem_parse(tem, v); tem->tvs_utf8_partial = 0; } return; } /* Anything left is illegal in UTF-8 sequence. */ tem_input_partial(tem); tem_parse(tem, c); } /* * This is the main entry point into the terminal emulator. * * For each data message coming downstream, ANSI assumes that it is composed * of ASCII characters, which are treated as a byte-stream input to the * parsing state machine. All data is parsed immediately -- there is * no enqueing. */ static void tem_terminal_emulate(struct tem_vt_state *tem, uint8_t *buf, int len) { if (tem->tvs_isactive && !tem->tvs_cursor_hidden) tem_callback_cursor(tem, VIS_HIDE_CURSOR); for (; len > 0; len--, buf++) tem_input_byte(tem, *buf); /* * Send the data we just got to the framebuffer. */ tem_send_data(tem); if (tem->tvs_isactive && !tem->tvs_cursor_hidden) tem_callback_cursor(tem, VIS_DISPLAY_CURSOR); } /* * send the appropriate control message or set state based on the * value of the control character ch */ static void tem_control(struct tem_vt_state *tem, uint8_t ch) { tem->tvs_state = A_STATE_START; switch (ch) { case A_BEL: tem_bell(tem); break; case A_BS: tem_mv_cursor(tem, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col - 1); break; case A_HT: tem_tab(tem); break; case A_NL: /* * tem_send_data(tem, credp, called_from); * tem_new_line(tem, credp, called_from); * break; */ case A_VT: tem_send_data(tem); tem_lf(tem); break; case A_FF: tem_send_data(tem); tem_cls(tem); break; case A_CR: tem_send_data(tem); tem_cr(tem); break; case A_ESC: tem->tvs_state = A_STATE_ESC; break; case A_CSI: tem->tvs_curparam = 0; tem->tvs_paramval = 0; tem->tvs_gotparam = false; /* clear the parameters */ for (int i = 0; i < TEM_MAXPARAMS; i++) tem->tvs_params[i] = -1; tem->tvs_state = A_STATE_CSI; break; case A_GS: tem_back_tab(tem); break; default: break; } } /* * if parameters [0..count - 1] are not set, set them to the value * of newparam. */ static void tem_setparam(struct tem_vt_state *tem, int count, int newparam) { int i; for (i = 0; i < count; i++) { if (tem->tvs_params[i] == -1) tem->tvs_params[i] = newparam; } } /* * For colors 0-15 the tem is using color code translation * from sun colors to vga (dim_xlate and brt_xlate tables, see tem_get_color). * Colors 16-255 are used without translation. */ static void tem_select_color(struct tem_vt_state *tem, int color, bool fg) { if (color < 0 || color > 255) return; /* VGA text mode only does support 16 colors. */ if (tems.ts_display_mode == VIS_TEXT && color > 15) return; /* Switch to use indexed colors. */ if (fg == true) { tem->tvs_flags &= ~TEM_ATTR_RGB_FG; tem->tvs_fg_color.n = color; } else { tem->tvs_flags &= ~TEM_ATTR_RGB_BG; tem->tvs_bg_color.n = color; } /* * For colors 0-7, make sure the BRIGHT attribute is not set. */ if (color < 8) { if (fg == true) tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG; else tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG; return; } /* * For colors 8-15, we use color codes 0-7 and set BRIGHT attribute. */ if (color < 16) { if (fg == true) { tem->tvs_fg_color.n -= 8; tem->tvs_flags |= TEM_ATTR_BRIGHT_FG; } else { tem->tvs_bg_color.n -= 8; tem->tvs_flags |= TEM_ATTR_BRIGHT_BG; } } } /* * select graphics mode based on the param vals stored in a_params */ static void tem_selgraph(struct tem_vt_state *tem) { int curparam; int count = 0; int param; int r, g, b; tem->tvs_state = A_STATE_START; curparam = tem->tvs_curparam; do { param = tem->tvs_params[count]; switch (param) { case -1: case 0: /* reset to initial normal settings */ tem->tvs_fg_color = tems.ts_init_color.fg_color; tem->tvs_bg_color = tems.ts_init_color.bg_color; tem->tvs_flags = tems.ts_init_color.a_flags; break; case 1: /* Bold Intense */ tem->tvs_flags |= TEM_ATTR_BOLD; break; case 2: /* Faint Intense */ tem->tvs_flags &= ~TEM_ATTR_BOLD; break; case 4: /* Underline */ tem->tvs_flags |= TEM_ATTR_UNDERLINE; break; case 5: /* Blink */ tem->tvs_flags |= TEM_ATTR_BLINK; break; case 7: /* Reverse video */ if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) { tem->tvs_flags &= ~TEM_ATTR_REVERSE; } else { tem->tvs_flags |= TEM_ATTR_REVERSE; } break; case 22: /* Remove Bold */ tem->tvs_flags &= ~TEM_ATTR_BOLD; break; case 24: /* Remove Underline */ tem->tvs_flags &= ~TEM_ATTR_UNDERLINE; break; case 25: /* Remove Blink */ tem->tvs_flags &= ~TEM_ATTR_BLINK; break; case 27: /* Remove Reverse */ if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) { tem->tvs_flags |= TEM_ATTR_REVERSE; } else { tem->tvs_flags &= ~TEM_ATTR_REVERSE; } break; case 30: /* black (grey) foreground */ case 31: /* red (light red) foreground */ case 32: /* green (light green) foreground */ case 33: /* brown (yellow) foreground */ case 34: /* blue (light blue) foreground */ case 35: /* magenta (light magenta) foreground */ case 36: /* cyan (light cyan) foreground */ case 37: /* white (bright white) foreground */ tem->tvs_fg_color.n = param - 30; tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG; tem->tvs_flags &= ~TEM_ATTR_RGB_FG; break; case 38: /* * We should have 3 parameters for 256 colors and * 5 parameters for 24-bit colors. */ if (curparam < 3) { curparam = 0; break; } /* * 256 and truecolor needs depth > 8, but * we still need to process the sequence. */ count++; curparam--; param = tem->tvs_params[count]; switch (param) { case 2: /* RGB colors */ if (curparam < 4) { curparam = 0; break; } r = tem->tvs_params[++count]; g = tem->tvs_params[++count]; b = tem->tvs_params[++count]; curparam -= 3; if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) break; if (tems.ts_display_mode == VIS_PIXEL && tems.ts_pdepth > 8) { tem->tvs_flags |= TEM_ATTR_RGB_FG; tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG; tem->tvs_fg_color.rgb.a = tem->tvs_alpha; tem->tvs_fg_color.rgb.r = r; tem->tvs_fg_color.rgb.g = g; tem->tvs_fg_color.rgb.b = b; } break; case 5: /* 256 colors */ count++; curparam--; tem_select_color(tem, tem->tvs_params[count], true); break; default: curparam = 0; break; } break; case 39: /* * Reset the foreground colour and brightness. */ tem->tvs_fg_color = tems.ts_init_color.fg_color; tem->tvs_flags &= ~TEM_ATTR_RGB_FG; if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_FG) tem->tvs_flags |= TEM_ATTR_BRIGHT_FG; else tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG; break; case 40: /* black (grey) background */ case 41: /* red (light red) background */ case 42: /* green (light green) background */ case 43: /* brown (yellow) background */ case 44: /* blue (light blue) background */ case 45: /* magenta (light magenta) background */ case 46: /* cyan (light cyan) background */ case 47: /* white (bright white) background */ tem->tvs_bg_color.n = param - 40; tem->tvs_flags &= ~TEM_ATTR_RGB_BG; tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG; break; case 48: /* * We should have 3 parameters for 256 colors and * 5 parameters for 24-bit colors. */ /* We should have at least 3 parameters */ if (curparam < 3) { curparam = 0; break; } /* * 256 and truecolor needs depth > 8, but * we still need to process the sequence. */ count++; curparam--; param = tem->tvs_params[count]; switch (param) { case 2: /* RGB colors */ if (curparam < 4) { curparam = 0; break; } r = tem->tvs_params[++count]; g = tem->tvs_params[++count]; b = tem->tvs_params[++count]; curparam -= 3; if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) break; if (tems.ts_display_mode == VIS_PIXEL && tems.ts_pdepth > 8) { tem->tvs_flags |= TEM_ATTR_RGB_BG; tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG; tem->tvs_bg_color.rgb.a = tem->tvs_alpha; tem->tvs_bg_color.rgb.r = r; tem->tvs_bg_color.rgb.g = g; tem->tvs_bg_color.rgb.b = b; } break; case 5: /* 256 colors */ count++; curparam--; tem_select_color(tem, tem->tvs_params[count], false); break; default: curparam = 0; break; } break; case 49: /* * Reset the background colour and brightness. */ tem->tvs_bg_color = tems.ts_init_color.bg_color; tem->tvs_flags &= ~TEM_ATTR_RGB_BG; if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_BG) tem->tvs_flags |= TEM_ATTR_BRIGHT_BG; else tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG; break; case 90: /* black (grey) foreground */ case 91: /* red (light red) foreground */ case 92: /* green (light green) foreground */ case 93: /* brown (yellow) foreground */ case 94: /* blue (light blue) foreground */ case 95: /* magenta (light magenta) foreground */ case 96: /* cyan (light cyan) foreground */ case 97: /* white (bright white) foreground */ tem->tvs_fg_color.n = param - 90; tem->tvs_flags |= TEM_ATTR_BRIGHT_FG; tem->tvs_flags &= ~TEM_ATTR_RGB_FG; break; case 100: /* black (grey) background */ case 101: /* red (light red) background */ case 102: /* green (light green) background */ case 103: /* brown (yellow) background */ case 104: /* blue (light blue) background */ case 105: /* magenta (light magenta) background */ case 106: /* cyan (light cyan) background */ case 107: /* white (bright white) background */ tem->tvs_bg_color.n = param - 100; tem->tvs_flags |= TEM_ATTR_BRIGHT_BG; tem->tvs_flags &= ~TEM_ATTR_RGB_BG; break; default: break; } count++; curparam--; } while (curparam > 0); } /* * perform the appropriate action for the escape sequence * * General rule: This code does not validate the arguments passed. * It assumes that the next lower level will do so. */ static void tem_chkparam(struct tem_vt_state *tem, uint8_t ch) { int i; int row; int col; row = tem->tvs_c_cursor.row; col = tem->tvs_c_cursor.col; switch (ch) { case 'm': /* select terminal graphics mode */ tem_send_data(tem); tem_selgraph(tem); break; case '@': /* insert char */ tem_setparam(tem, 1, 1); tem_shift(tem, tem->tvs_params[0], TEM_SHIFT_RIGHT); break; case 'A': /* cursor up */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row - tem->tvs_params[0], col); break; case 'd': /* VPA - vertical position absolute */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, tem->tvs_params[0] - 1, col); break; case 'e': /* VPR - vertical position relative */ case 'B': /* cursor down */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row + tem->tvs_params[0], col); break; case 'a': /* HPR - horizontal position relative */ case 'C': /* cursor right */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row, col + tem->tvs_params[0]); break; case '`': /* HPA - horizontal position absolute */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row, tem->tvs_params[0] - 1); break; case 'D': /* cursor left */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row, col - tem->tvs_params[0]); break; case 'E': /* CNL cursor next line */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row + tem->tvs_params[0], 0); break; case 'F': /* CPL cursor previous line */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row - tem->tvs_params[0], 0); break; case 'G': /* cursor horizontal position */ tem_setparam(tem, 1, 1); tem_mv_cursor(tem, row, tem->tvs_params[0] - 1); break; case 'g': /* clear tabs */ tem_setparam(tem, 1, 0); tem_clear_tabs(tem, tem->tvs_params[0]); break; case 'f': /* HVP Horizontal and Vertical Position */ case 'H': /* CUP position cursor */ tem_setparam(tem, 2, 1); tem_mv_cursor(tem, tem->tvs_params[0] - 1, tem->tvs_params[1] - 1); break; case 'I': /* CHT - Cursor Horizontal Tab */ /* Not implemented */ break; case 'J': /* ED - Erase in Display */ tem_send_data(tem); tem_setparam(tem, 1, 0); switch (tem->tvs_params[0]) { case 0: /* erase cursor to end of screen */ /* FIRST erase cursor to end of line */ tem_clear_chars(tem, tems.ts_c_dimension.width - tem->tvs_c_cursor.col, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col); /* THEN erase lines below the cursor */ for (row = tem->tvs_c_cursor.row + 1; row < tems.ts_c_dimension.height; row++) { tem_clear_chars(tem, tems.ts_c_dimension.width, row, 0); } break; case 1: /* erase beginning of screen to cursor */ /* FIRST erase lines above the cursor */ for (row = 0; row < tem->tvs_c_cursor.row; row++) { tem_clear_chars(tem, tems.ts_c_dimension.width, row, 0); } /* THEN erase beginning of line to cursor */ tem_clear_chars(tem, tem->tvs_c_cursor.col + 1, tem->tvs_c_cursor.row, 0); break; case 2: /* erase whole screen */ for (row = 0; row < tems.ts_c_dimension.height; row++) { tem_clear_chars(tem, tems.ts_c_dimension.width, row, 0); } break; } break; case 'K': /* EL - Erase in Line */ tem_send_data(tem); tem_setparam(tem, 1, 0); switch (tem->tvs_params[0]) { case 0: /* erase cursor to end of line */ tem_clear_chars(tem, (tems.ts_c_dimension.width - tem->tvs_c_cursor.col), tem->tvs_c_cursor.row, tem->tvs_c_cursor.col); break; case 1: /* erase beginning of line to cursor */ tem_clear_chars(tem, tem->tvs_c_cursor.col + 1, tem->tvs_c_cursor.row, 0); break; case 2: /* erase whole line */ tem_clear_chars(tem, tems.ts_c_dimension.width, tem->tvs_c_cursor.row, 0); break; } break; case 'L': /* insert line */ tem_send_data(tem); tem_setparam(tem, 1, 1); tem_scroll(tem, tem->tvs_c_cursor.row, tems.ts_c_dimension.height - 1, tem->tvs_params[0], TEM_SCROLL_DOWN); break; case 'M': /* delete line */ tem_send_data(tem); tem_setparam(tem, 1, 1); tem_scroll(tem, tem->tvs_c_cursor.row, tems.ts_c_dimension.height - 1, tem->tvs_params[0], TEM_SCROLL_UP); break; case 'P': /* DCH - delete char */ tem_setparam(tem, 1, 1); tem_shift(tem, tem->tvs_params[0], TEM_SHIFT_LEFT); break; case 'S': /* scroll up */ tem_send_data(tem); tem_setparam(tem, 1, 1); tem_scroll(tem, 0, tems.ts_c_dimension.height - 1, tem->tvs_params[0], TEM_SCROLL_UP); break; case 'T': /* scroll down */ tem_send_data(tem); tem_setparam(tem, 1, 1); tem_scroll(tem, 0, tems.ts_c_dimension.height - 1, tem->tvs_params[0], TEM_SCROLL_DOWN); break; case 'X': /* erase char */ tem_setparam(tem, 1, 1); tem_clear_chars(tem, tem->tvs_params[0], tem->tvs_c_cursor.row, tem->tvs_c_cursor.col); break; case 'Z': /* cursor backward tabulation */ tem_setparam(tem, 1, 1); /* * Rule exception - We do sanity checking here. * * Restrict the count to a sane value to keep from * looping for a long time. There can't be more than one * tab stop per column, so use that as a limit. */ if (tem->tvs_params[0] > tems.ts_c_dimension.width) tem->tvs_params[0] = tems.ts_c_dimension.width; for (i = 0; i < tem->tvs_params[0]; i++) tem_back_tab(tem); break; } tem->tvs_state = A_STATE_START; } static void tem_chkparam_qmark(struct tem_vt_state *tem, tem_char_t ch) { switch (ch) { case 'h': /* DEC private mode set */ tem_setparam(tem, 1, 1); switch (tem->tvs_params[0]) { case 7: /* Autowrap mode. */ tem->tvs_stateflags |= TVS_AUTOWRAP; break; case 25: /* show cursor */ /* * Note that cursor is not displayed either way * at this entry point. Clearing the flag ensures * that on exit from tem_safe_terminal_emulate * we will display the cursor. */ tem_send_data(tem); tem->tvs_cursor_hidden = false; break; } break; case 'l': /* DEC private mode reset */ tem_setparam(tem, 1, 1); switch (tem->tvs_params[0]) { case 7: /* Autowrap mode. */ tem->tvs_stateflags &= ~TVS_AUTOWRAP; break; case 25: /* hide cursor */ /* * Note that the cursor is not displayed already. * This is true regardless of the flag state. * Setting this flag ensures we won't display it * on exit from tem_safe_terminal_emulate. */ tem_send_data(tem); tem->tvs_cursor_hidden = true; break; } break; } tem->tvs_state = A_STATE_START; } /* * Gather the parameters of an ANSI escape sequence */ static void tem_getparams(struct tem_vt_state *tem, uint8_t ch) { if (isdigit(ch)) { tem->tvs_paramval = ((tem->tvs_paramval * 10) + (ch - '0')); tem->tvs_gotparam = true; /* Remember got parameter */ return; /* Return immediately */ } else if (tem->tvs_state == A_STATE_CSI_EQUAL) { tem->tvs_state = A_STATE_START; } else if (tem->tvs_state == A_STATE_CSI_QMARK) { if (tem->tvs_curparam < TEM_MAXPARAMS) { if (tem->tvs_gotparam) { /* get the parameter value */ tem->tvs_params[tem->tvs_curparam] = tem->tvs_paramval; } tem->tvs_curparam++; } if (ch == ';') { /* Restart parameter search */ tem->tvs_gotparam = false; tem->tvs_paramval = 0; /* No parameter value yet */ } else { /* Handle escape sequence */ tem_chkparam_qmark(tem, ch); } } else { if (tem->tvs_curparam < TEM_MAXPARAMS) { if (tem->tvs_gotparam) { /* get the parameter value */ tem->tvs_params[tem->tvs_curparam] = tem->tvs_paramval; } tem->tvs_curparam++; } if (ch == ';') { /* Restart parameter search */ tem->tvs_gotparam = false; tem->tvs_paramval = 0; /* No parameter value yet */ } else { /* Handle escape sequence */ tem_chkparam(tem, ch); } } } /* * Add character to internal buffer. * When its full, send it to the next layer. */ static void tem_outch(struct tem_vt_state *tem, tem_char_t ch) { text_color_t fg; text_color_t bg; text_attr_t attr; /* We have autowrap enabled and we did wrap - get cursor to new line */ if ((tem->tvs_stateflags & (TVS_AUTOWRAP | TVS_WRAPPED)) == (TVS_AUTOWRAP | TVS_WRAPPED)) { tem_new_line(tem); } /* buffer up the character until later */ tem_get_attr(tem, &fg, &bg, &attr, TEM_ATTR_REVERSE); tem->tvs_outbuf[tem->tvs_outindex].tc_char = ch | TEM_ATTR(attr); tem->tvs_outbuf[tem->tvs_outindex].tc_fg_color = fg; tem->tvs_outbuf[tem->tvs_outindex].tc_bg_color = bg; tem->tvs_outindex++; tem->tvs_c_cursor.col++; if (tem->tvs_c_cursor.col >= tems.ts_c_dimension.width) { tem->tvs_stateflags |= TVS_WRAPPED; tem->tvs_c_cursor.col--; tem_send_data(tem); } else { tem->tvs_stateflags &= ~TVS_WRAPPED; } } static void tem_new_line(struct tem_vt_state *tem) { tem_cr(tem); tem_lf(tem); } static void tem_cr(struct tem_vt_state *tem) { tem->tvs_c_cursor.col = 0; tem->tvs_stateflags &= ~TVS_WRAPPED; tem_align_cursor(tem); } static void tem_lf(struct tem_vt_state *tem) { int row; tem->tvs_stateflags &= ~TVS_WRAPPED; /* * Sanity checking notes: * . a_nscroll was validated when it was set. * . Regardless of that, tem_scroll and tem_mv_cursor * will prevent anything bad from happening. */ row = tem->tvs_c_cursor.row + 1; if (row >= tems.ts_c_dimension.height) { if (tem->tvs_nscroll != 0) { tem_scroll(tem, 0, tems.ts_c_dimension.height - 1, tem->tvs_nscroll, TEM_SCROLL_UP); row = tems.ts_c_dimension.height - tem->tvs_nscroll; } else { /* no scroll */ /* * implement Esc[#r when # is zero. This means no * scroll but just return cursor to top of screen, * do not clear screen. */ row = 0; } } tem_mv_cursor(tem, row, tem->tvs_c_cursor.col); if (tem->tvs_nscroll == 0) { /* erase rest of cursor line */ tem_clear_chars(tem, tems.ts_c_dimension.width - tem->tvs_c_cursor.col, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col); } tem_align_cursor(tem); } static void tem_send_data(struct tem_vt_state *tem) { if (tem->tvs_outindex == 0) { tem_align_cursor(tem); return; } tem_virtual_display(tem, tem->tvs_outbuf, tem->tvs_outindex, tem->tvs_s_cursor.row, tem->tvs_s_cursor.col); if (tem->tvs_isactive) { /* * Call the primitive to render this data. */ tem_callback_display(tem, tem->tvs_outbuf, tem->tvs_outindex, tem->tvs_s_cursor.row, tem->tvs_s_cursor.col); } tem->tvs_outindex = 0; tem_align_cursor(tem); } /* * We have just done something to the current output point. Reset the start * point for the buffered data in a_outbuf. There shouldn't be any data * buffered yet. */ static void tem_align_cursor(struct tem_vt_state *tem) { tem->tvs_s_cursor.row = tem->tvs_c_cursor.row; tem->tvs_s_cursor.col = tem->tvs_c_cursor.col; } /* * State machine parser based on the current state and character input * major terminations are to control character or normal character */ static void tem_parse(struct tem_vt_state *tem, tem_char_t ch) { int i; if (tem->tvs_state == A_STATE_START) { /* Normal state? */ if (ch == A_CSI || ch == A_ESC || ch < ' ') { /* Control */ tem_control(tem, ch); } else { /* Display */ tem_outch(tem, ch); } return; } /* In sequence */ if (tem->tvs_state != A_STATE_ESC) { /* Need to get parameters? */ if (tem->tvs_state != A_STATE_CSI) { tem_getparams(tem, ch); return; } switch (ch) { case '?': tem->tvs_state = A_STATE_CSI_QMARK; return; case '=': tem->tvs_state = A_STATE_CSI_EQUAL; return; case 's': /* * As defined below, this sequence * saves the cursor. However, Sun * defines ESC[s as reset. We resolved * the conflict by selecting reset as it * is exported in the termcap file for * sun-mon, while the "save cursor" * definition does not exist anywhere in * /etc/termcap. * However, having no coherent * definition of reset, we have not * implemented it. */ /* * Original code * tem->tvs_r_cursor.row = tem->tvs_c_cursor.row; * tem->tvs_r_cursor.col = tem->tvs_c_cursor.col; * tem->tvs_state = A_STATE_START; */ tem->tvs_state = A_STATE_START; return; case 'u': tem_mv_cursor(tem, tem->tvs_r_cursor.row, tem->tvs_r_cursor.col); tem->tvs_state = A_STATE_START; return; case 'p': /* sunbow */ tem_send_data(tem); /* * Don't set anything if we are * already as we want to be. */ if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) { tem->tvs_flags &= ~TEM_ATTR_SCREEN_REVERSE; /* * If we have switched the characters to be the * inverse from the screen, then switch them as * well to keep them the inverse of the screen. */ if (tem->tvs_flags & TEM_ATTR_REVERSE) tem->tvs_flags &= ~TEM_ATTR_REVERSE; else tem->tvs_flags |= TEM_ATTR_REVERSE; } tem_cls(tem); tem->tvs_state = A_STATE_START; return; case 'q': /* sunwob */ tem_send_data(tem); /* * Don't set anything if we are * already where as we want to be. */ if (!(tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE)) { tem->tvs_flags |= TEM_ATTR_SCREEN_REVERSE; /* * If we have switched the characters to be the * inverse from the screen, then switch them as * well to keep them the inverse of the screen. */ if (!(tem->tvs_flags & TEM_ATTR_REVERSE)) tem->tvs_flags |= TEM_ATTR_REVERSE; else tem->tvs_flags &= ~TEM_ATTR_REVERSE; } tem_cls(tem); tem->tvs_state = A_STATE_START; return; case 'r': /* sunscrl */ /* * Rule exception: check for validity here. */ tem->tvs_nscroll = tem->tvs_paramval; if (tem->tvs_nscroll > tems.ts_c_dimension.height) tem->tvs_nscroll = tems.ts_c_dimension.height; if (tem->tvs_nscroll < 0) tem->tvs_nscroll = 1; tem->tvs_state = A_STATE_START; return; default: tem_getparams(tem, ch); return; } } /* Previous char was */ if (ch == '[') { tem->tvs_curparam = 0; tem->tvs_paramval = 0; tem->tvs_gotparam = false; /* clear the parameters */ for (i = 0; i < TEM_MAXPARAMS; i++) tem->tvs_params[i] = -1; tem->tvs_state = A_STATE_CSI; } else if (ch == 'Q') { /* Q ? */ tem->tvs_state = A_STATE_START; } else if (ch == 'C') { /* C ? */ tem->tvs_state = A_STATE_START; } else { tem->tvs_state = A_STATE_START; if (ch == 'c') { /* ESC c resets display */ tem_reset_display(tem, true, true); } else if (ch == 'H') { /* ESC H sets a tab */ tem_set_tab(tem); } else if (ch == '7') { /* ESC 7 Save Cursor position */ tem->tvs_r_cursor.row = tem->tvs_c_cursor.row; tem->tvs_r_cursor.col = tem->tvs_c_cursor.col; } else if (ch == '8') { /* ESC 8 Restore Cursor position */ tem_mv_cursor(tem, tem->tvs_r_cursor.row, tem->tvs_r_cursor.col); /* check for control chars */ } else if (ch < ' ') { tem_control(tem, ch); } else { tem_outch(tem, ch); } } } /* ARGSUSED */ static void tem_bell(struct tem_vt_state *tem __unused) { /* (void) beep(BEEP_CONSOLE); */ } static void tem_scroll(struct tem_vt_state *tem, int start, int end, int count, int direction) { int row; int lines_affected; lines_affected = end - start + 1; if (count > lines_affected) count = lines_affected; if (count <= 0) return; switch (direction) { case TEM_SCROLL_UP: if (count < lines_affected) { tem_copy_area(tem, 0, start + count, tems.ts_c_dimension.width - 1, end, 0, start); } for (row = (end - count) + 1; row <= end; row++) { tem_clear_chars(tem, tems.ts_c_dimension.width, row, 0); } break; case TEM_SCROLL_DOWN: if (count < lines_affected) { tem_copy_area(tem, 0, start, tems.ts_c_dimension.width - 1, end - count, 0, start + count); } for (row = start; row < start + count; row++) { tem_clear_chars(tem, tems.ts_c_dimension.width, row, 0); } break; } } static int tem_copy_width(term_char_t *src, term_char_t *dst, int cols) { int width = cols - 1; while (width >= 0) { /* We do not have image bits to compare, stop there. */ if (TEM_CHAR_ATTR(src[width].tc_char) == TEM_ATTR_IMAGE || TEM_CHAR_ATTR(dst[width].tc_char) == TEM_ATTR_IMAGE) break; /* * Find difference on line, compare char with its attributes * and colors. */ if (src[width].tc_char != dst[width].tc_char || src[width].tc_fg_color.n != dst[width].tc_fg_color.n || src[width].tc_bg_color.n != dst[width].tc_bg_color.n) { break; } width--; } return (width + 1); } static void tem_copy_area(struct tem_vt_state *tem, screen_pos_t s_col, screen_pos_t s_row, screen_pos_t e_col, screen_pos_t e_row, screen_pos_t t_col, screen_pos_t t_row) { size_t soffset, toffset; term_char_t *src, *dst; int rows; int cols; if (s_col < 0 || s_row < 0 || e_col < 0 || e_row < 0 || t_col < 0 || t_row < 0 || s_col >= tems.ts_c_dimension.width || e_col >= tems.ts_c_dimension.width || t_col >= tems.ts_c_dimension.width || s_row >= tems.ts_c_dimension.height || e_row >= tems.ts_c_dimension.height || t_row >= tems.ts_c_dimension.height) return; if (s_row > e_row || s_col > e_col) return; rows = e_row - s_row + 1; cols = e_col - s_col + 1; if (t_row + rows > tems.ts_c_dimension.height || t_col + cols > tems.ts_c_dimension.width) return; if (tem->tvs_screen_buf == NULL) { if (tem->tvs_isactive) { tem_callback_copy(tem, s_col, s_row, e_col, e_row, t_col, t_row); } return; } soffset = s_col + s_row * tems.ts_c_dimension.width; toffset = t_col + t_row * tems.ts_c_dimension.width; src = tem->tvs_screen_buf + soffset; dst = tem->tvs_screen_buf + toffset; /* * Copy line by line. We determine the length by comparing the * screen content from cached text in tvs_screen_buf. */ if (toffset <= soffset) { for (int i = 0; i < rows; i++) { int increment = i * tems.ts_c_dimension.width; int width; width = tem_copy_width(src + increment, dst + increment, cols); memmove(dst + increment, src + increment, width * sizeof (term_char_t)); if (tem->tvs_isactive) { tem_callback_copy(tem, s_col, s_row + i, e_col - cols + width, s_row + i, t_col, t_row + i); } } } else { for (int i = rows - 1; i >= 0; i--) { int increment = i * tems.ts_c_dimension.width; int width; width = tem_copy_width(src + increment, dst + increment, cols); memmove(dst + increment, src + increment, width * sizeof (term_char_t)); if (tem->tvs_isactive) { tem_callback_copy(tem, s_col, s_row + i, e_col - cols + width, s_row + i, t_col, t_row + i); } } } } static void tem_clear_chars(struct tem_vt_state *tem, int count, screen_pos_t row, screen_pos_t col) { if (row < 0 || row >= tems.ts_c_dimension.height || col < 0 || col >= tems.ts_c_dimension.width || count < 0) return; /* * Note that very large values of "count" could cause col+count * to overflow, so we check "count" independently. */ if (count > tems.ts_c_dimension.width || col + count > tems.ts_c_dimension.width) count = tems.ts_c_dimension.width - col; tem_virtual_cls(tem, count, row, col); if (!tem->tvs_isactive) return; tem_callback_cls(tem, count, row, col); } static void tem_text_display(struct tem_vt_state *tem __unused, term_char_t *string, int count, screen_pos_t row, screen_pos_t col) { struct vis_consdisplay da; int i; tem_char_t c; text_color_t bg, fg; if (count == 0) return; da.data = (unsigned char *)&c; da.width = 1; da.row = row; da.col = col; for (i = 0; i < count; i++) { tem_get_color(tem, &fg, &bg, &string[i]); tem_set_color(&fg, &da.fg_color); tem_set_color(&bg, &da.bg_color); c = TEM_CHAR(string[i].tc_char); tems_display(&da); da.col++; } } /* * This function is used to mark a rectangular image area so the scrolling * will know we need to copy the data from there. */ void tem_image_display(struct tem_vt_state *tem, screen_pos_t s_row, screen_pos_t s_col, screen_pos_t e_row, screen_pos_t e_col) { screen_pos_t i, j; term_char_t c; c.tc_char = TEM_ATTR(TEM_ATTR_IMAGE); for (i = s_row; i <= e_row; i++) { for (j = s_col; j <= e_col; j++) { tem_virtual_display(tem, &c, 1, i, j); } } } /*ARGSUSED*/ static void tem_text_copy(struct tem_vt_state *tem __unused, screen_pos_t s_col, screen_pos_t s_row, screen_pos_t e_col, screen_pos_t e_row, screen_pos_t t_col, screen_pos_t t_row) { struct vis_conscopy da; da.s_row = s_row; da.s_col = s_col; da.e_row = e_row; da.e_col = e_col; da.t_row = t_row; da.t_col = t_col; tems_copy(&da); } static void tem_text_cls(struct tem_vt_state *tem, int count, screen_pos_t row, screen_pos_t col) { text_attr_t attr; term_char_t c; int i; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_SCREEN_REVERSE); c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' '; if (count > tems.ts_c_dimension.width || col + count > tems.ts_c_dimension.width) count = tems.ts_c_dimension.width - col; for (i = 0; i < count; i++) tem_text_display(tem, &c, 1, row, col++); } static void tem_pix_display(struct tem_vt_state *tem, term_char_t *string, int count, screen_pos_t row, screen_pos_t col) { struct vis_consdisplay da; int i; da.data = (uint8_t *)tem->tvs_pix_data; da.width = tems.ts_font.vf_width; da.height = tems.ts_font.vf_height; da.row = (row * da.height) + tems.ts_p_offset.y; da.col = (col * da.width) + tems.ts_p_offset.x; for (i = 0; i < count; i++) { tem_callback_bit2pix(tem, &string[i]); tems_display(&da); da.col += da.width; } } static void tem_pix_copy(struct tem_vt_state *tem, screen_pos_t s_col, screen_pos_t s_row, screen_pos_t e_col, screen_pos_t e_row, screen_pos_t t_col, screen_pos_t t_row) { struct vis_conscopy ma; static bool need_clear = true; if (need_clear && tem->tvs_first_line > 0) { /* * Clear OBP output above our kernel console term * when our kernel console term begins to scroll up, * we hope it is user friendly. * (Also see comments on tem_pix_clear_prom_output) * * This is only one time call. */ tem_pix_clear_prom_output(tem); } need_clear = false; ma.s_row = s_row * tems.ts_font.vf_height + tems.ts_p_offset.y; ma.e_row = (e_row + 1) * tems.ts_font.vf_height + tems.ts_p_offset.y - 1; ma.t_row = t_row * tems.ts_font.vf_height + tems.ts_p_offset.y; /* * Check if we're in process of clearing OBP's columns area, * which only happens when term scrolls up a whole line. */ if (tem->tvs_first_line > 0 && t_row < s_row && t_col == 0 && e_col == tems.ts_c_dimension.width - 1) { /* * We need to clear OBP's columns area outside our kernel * console term. So that we set ma.e_col to entire row here. */ ma.s_col = s_col * tems.ts_font.vf_width; ma.e_col = tems.ts_p_dimension.width - 1; ma.t_col = t_col * tems.ts_font.vf_width; } else { ma.s_col = s_col * tems.ts_font.vf_width + tems.ts_p_offset.x; ma.e_col = (e_col + 1) * tems.ts_font.vf_width + tems.ts_p_offset.x - 1; ma.t_col = t_col * tems.ts_font.vf_width + tems.ts_p_offset.x; } tems_copy(&ma); if (tem->tvs_first_line > 0 && t_row < s_row) { /* We have scrolled up (s_row - t_row) rows. */ tem->tvs_first_line -= (s_row - t_row); if (tem->tvs_first_line <= 0) { /* All OBP rows have been cleared. */ tem->tvs_first_line = 0; } } } static void tem_pix_bit2pix(struct tem_vt_state *tem, term_char_t *c) { text_color_t fg, bg; tem_get_color(tem, &fg, &bg, c); bit_to_pix32(tem, c->tc_char, fg, bg); } /* * This function only clears count of columns in one row */ static void tem_pix_cls(struct tem_vt_state *tem, int count, screen_pos_t row, screen_pos_t col) { tem_pix_cls_range(tem, row, 1, tems.ts_p_offset.y, col, count, tems.ts_p_offset.x, false); } /* * This function clears OBP output above our kernel console term area * because OBP's term may have a bigger terminal window than that of * our kernel console term. So we need to clear OBP output garbage outside * of our kernel console term at a proper time, which is when the first * row output of our kernel console term scrolls at the first screen line. * * _________________________________ * | _____________________ | ---> OBP's bigger term window * | | | | * |___| | | * | | | | | * | | | | | * |_|_|___________________|_______| * | | | ---> first line * | |___________________|---> our kernel console term window * | * |---> columns area to be cleared * * This function only takes care of the output above our kernel console term, * and tem_prom_scroll_up takes care of columns area outside of our kernel * console term. */ static void tem_pix_clear_prom_output(struct tem_vt_state *tem) { int nrows, ncols, width, height, offset; width = tems.ts_font.vf_width; height = tems.ts_font.vf_height; offset = tems.ts_p_offset.y % height; nrows = tems.ts_p_offset.y / height; ncols = (tems.ts_p_dimension.width + (width - 1)) / width; if (nrows > 0) tem_pix_cls_range(tem, 0, nrows, offset, 0, ncols, 0, false); } /* * Clear the whole screen and reset the cursor to start point. */ static void tem_cls(struct tem_vt_state *tem) { struct vis_consclear cl; text_color_t fg_color; text_color_t bg_color; text_attr_t attr; term_char_t c; int row; for (row = 0; row < tems.ts_c_dimension.height; row++) { tem_virtual_cls(tem, tems.ts_c_dimension.width, row, 0); } if (!tem->tvs_isactive) return; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_SCREEN_REVERSE); c.tc_char = TEM_ATTR(attr); tem_get_color(tem, &fg_color, &bg_color, &c); tem_set_color(&bg_color, &cl.bg_color); (void) tems_cls(&cl); tem->tvs_c_cursor.row = 0; tem->tvs_c_cursor.col = 0; tem_align_cursor(tem); } static void tem_back_tab(struct tem_vt_state *tem) { int i; screen_pos_t tabstop; tabstop = 0; for (i = tem->tvs_ntabs - 1; i >= 0; i--) { if (tem->tvs_tabs[i] < tem->tvs_c_cursor.col) { tabstop = tem->tvs_tabs[i]; break; } } tem_mv_cursor(tem, tem->tvs_c_cursor.row, tabstop); } static void tem_tab(struct tem_vt_state *tem) { size_t i; screen_pos_t tabstop; tabstop = tems.ts_c_dimension.width - 1; for (i = 0; i < tem->tvs_ntabs; i++) { if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) { tabstop = tem->tvs_tabs[i]; break; } } tem_mv_cursor(tem, tem->tvs_c_cursor.row, tabstop); } static void tem_set_tab(struct tem_vt_state *tem) { size_t i, j; if (tem->tvs_ntabs == tem->tvs_maxtab) return; if (tem->tvs_ntabs == 0 || tem->tvs_tabs[tem->tvs_ntabs] < tem->tvs_c_cursor.col) { tem->tvs_tabs[tem->tvs_ntabs++] = tem->tvs_c_cursor.col; return; } for (i = 0; i < tem->tvs_ntabs; i++) { if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col) return; if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) { for (j = tem->tvs_ntabs - 1; j >= i; j--) tem->tvs_tabs[j+ 1] = tem->tvs_tabs[j]; tem->tvs_tabs[i] = tem->tvs_c_cursor.col; tem->tvs_ntabs++; return; } } } static void tem_clear_tabs(struct tem_vt_state *tem, int action) { size_t i, j; switch (action) { case 3: /* clear all tabs */ tem->tvs_ntabs = 0; break; case 0: /* clr tab at cursor */ for (i = 0; i < tem->tvs_ntabs; i++) { if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col) { tem->tvs_ntabs--; for (j = i; j < tem->tvs_ntabs; j++) tem->tvs_tabs[j] = tem->tvs_tabs[j + 1]; return; } } break; } } static void tem_mv_cursor(struct tem_vt_state *tem, int row, int col) { /* * Sanity check and bounds enforcement. Out of bounds requests are * clipped to the screen boundaries. This seems to be what SPARC * does. */ if (row < 0) row = 0; if (row >= tems.ts_c_dimension.height) row = tems.ts_c_dimension.height - 1; if (col < 0) col = 0; if (col >= tems.ts_c_dimension.width) { tem->tvs_stateflags |= TVS_WRAPPED; col = tems.ts_c_dimension.width - 1; } else { tem->tvs_stateflags &= ~TVS_WRAPPED; } tem_send_data(tem); tem->tvs_c_cursor.row = (screen_pos_t)row; tem->tvs_c_cursor.col = (screen_pos_t)col; tem_align_cursor(tem); } /* ARGSUSED */ static void tem_reset_emulator(struct tem_vt_state *tem, bool init_color) { int j; tem->tvs_c_cursor.row = 0; tem->tvs_c_cursor.col = 0; tem->tvs_r_cursor.row = 0; tem->tvs_r_cursor.col = 0; tem->tvs_s_cursor.row = 0; tem->tvs_s_cursor.col = 0; tem->tvs_outindex = 0; tem->tvs_state = A_STATE_START; tem->tvs_gotparam = false; tem->tvs_curparam = 0; tem->tvs_paramval = 0; tem->tvs_nscroll = 1; if (init_color) { /* use initial settings */ tem->tvs_alpha = 0xff; tem->tvs_fg_color = tems.ts_init_color.fg_color; tem->tvs_bg_color = tems.ts_init_color.bg_color; tem->tvs_flags = tems.ts_init_color.a_flags; } /* * set up the initial tab stops */ tem->tvs_ntabs = 0; for (j = 8; j < tems.ts_c_dimension.width; j += 8) tem->tvs_tabs[tem->tvs_ntabs++] = (screen_pos_t)j; for (j = 0; j < TEM_MAXPARAMS; j++) tem->tvs_params[j] = 0; } static void tem_reset_display(struct tem_vt_state *tem, bool clear_txt, bool init_color) { tem_reset_emulator(tem, init_color); if (clear_txt) { if (tem->tvs_isactive) tem_callback_cursor(tem, VIS_HIDE_CURSOR); tem_cls(tem); if (tem->tvs_isactive) tem_callback_cursor(tem, VIS_DISPLAY_CURSOR); } } static void tem_shift(struct tem_vt_state *tem, int count, int direction) { int rest_of_line; rest_of_line = tems.ts_c_dimension.width - tem->tvs_c_cursor.col; if (count > rest_of_line) count = rest_of_line; if (count <= 0) return; switch (direction) { case TEM_SHIFT_LEFT: if (count < rest_of_line) { tem_copy_area(tem, tem->tvs_c_cursor.col + count, tem->tvs_c_cursor.row, tems.ts_c_dimension.width - 1, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col, tem->tvs_c_cursor.row); } tem_clear_chars(tem, count, tem->tvs_c_cursor.row, (tems.ts_c_dimension.width - count)); break; case TEM_SHIFT_RIGHT: if (count < rest_of_line) { tem_copy_area(tem, tem->tvs_c_cursor.col, tem->tvs_c_cursor.row, tems.ts_c_dimension.width - count - 1, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col + count, tem->tvs_c_cursor.row); } tem_clear_chars(tem, count, tem->tvs_c_cursor.row, tem->tvs_c_cursor.col); break; } } static void tem_text_cursor(struct tem_vt_state *tem, short action) { struct vis_conscursor ca; ca.row = tem->tvs_c_cursor.row; ca.col = tem->tvs_c_cursor.col; ca.action = action; tems_cursor(&ca); if (action == VIS_GET_CURSOR) { tem->tvs_c_cursor.row = ca.row; tem->tvs_c_cursor.col = ca.col; } } static void tem_pix_cursor(struct tem_vt_state *tem, short action) { struct vis_conscursor ca; text_color_t fg, bg; term_char_t c; text_attr_t attr; ca.row = tem->tvs_c_cursor.row * tems.ts_font.vf_height + tems.ts_p_offset.y; ca.col = tem->tvs_c_cursor.col * tems.ts_font.vf_width + tems.ts_p_offset.x; ca.width = tems.ts_font.vf_width; ca.height = tems.ts_font.vf_height; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_REVERSE); c.tc_char = TEM_ATTR(attr); tem_get_color(tem, &fg, &bg, &c); tem_set_color(&fg, &ca.fg_color); tem_set_color(&bg, &ca.bg_color); ca.action = action; tems_cursor(&ca); if (action == VIS_GET_CURSOR) { tem->tvs_c_cursor.row = 0; tem->tvs_c_cursor.col = 0; if (ca.row != 0) { tem->tvs_c_cursor.row = (ca.row - tems.ts_p_offset.y) / tems.ts_font.vf_height; } if (ca.col != 0) { tem->tvs_c_cursor.col = (ca.col - tems.ts_p_offset.x) / tems.ts_font.vf_width; } } } static void bit_to_pix32(struct tem_vt_state *tem, tem_char_t c, text_color_t fg, text_color_t bg) { uint32_t *dest; dest = (uint32_t *)tem->tvs_pix_data; font_bit_to_pix32(&tems.ts_font, dest, c, fg.n, bg.n); } /* * flag: TEM_ATTR_SCREEN_REVERSE or TEM_ATTR_REVERSE */ static void tem_get_attr(struct tem_vt_state *tem, text_color_t *fg, text_color_t *bg, text_attr_t *attr, uint8_t flag) { if (tem->tvs_flags & flag) { *fg = tem->tvs_bg_color; *bg = tem->tvs_fg_color; } else { *fg = tem->tvs_fg_color; *bg = tem->tvs_bg_color; } if (attr != NULL) *attr = tem->tvs_flags; } static void tem_get_color(struct tem_vt_state *tem, text_color_t *fg, text_color_t *bg, term_char_t *c) { bool bold_font; *fg = c->tc_fg_color; *bg = c->tc_bg_color; bold_font = tems.ts_font.vf_map_count[VFNT_MAP_BOLD] != 0; /* * If we have both normal and bold font components, * we use bold font for TEM_ATTR_BOLD. * The bright color is traditionally used with TEM_ATTR_BOLD, * in case there is no bold font. */ if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG) && c->tc_fg_color.n < XLATE_NCOLORS) { if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_FG) || (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BOLD) && !bold_font)) fg->n = brt_xlate[c->tc_fg_color.n]; else fg->n = dim_xlate[c->tc_fg_color.n]; } if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG) && c->tc_bg_color.n < XLATE_NCOLORS) { if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_BG)) bg->n = brt_xlate[c->tc_bg_color.n]; else bg->n = dim_xlate[c->tc_bg_color.n]; } if (tems.ts_display_mode == VIS_TEXT) return; /* * Translate fg and bg to RGB colors. */ if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG)) { fg->n = rgb_to_color(&rgb_info, fg->rgb.a, fg->rgb.r, fg->rgb.g, fg->rgb.b); } else { fg->n = rgb_color_map(&rgb_info, fg->n, tem->tvs_alpha); } if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG)) { bg->n = rgb_to_color(&rgb_info, bg->rgb.a, bg->rgb.r, bg->rgb.g, bg->rgb.b); } else { bg->n = rgb_color_map(&rgb_info, bg->n, tem->tvs_alpha); } } static void tem_set_color(text_color_t *t, color_t *c) { switch (tems.ts_pdepth) { case 4: c->four = t->n & 0xFF; break; default: /* gfx module is expecting all pixel data in 32-bit colors */ *(uint32_t *)c = t->n; break; } } void tem_get_colors(tem_vt_state_t tem_arg, text_color_t *fg, text_color_t *bg) { struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg; text_attr_t attr; term_char_t c; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_REVERSE); c.tc_char = TEM_ATTR(attr); tem_get_color(tem, fg, bg, &c); } /* * Clear a rectangle of screen for pixel mode. * * arguments: * row: start row# * nrows: the number of rows to clear * offset_y: the offset of height in pixels to begin clear * col: start col# * ncols: the number of cols to clear * offset_x: the offset of width in pixels to begin clear * scroll_up: whether this function is called during sroll up, * which is called only once. */ static void tem_pix_cls_range(struct tem_vt_state *tem, screen_pos_t row, int nrows, int offset_y, screen_pos_t col, int ncols, int offset_x, bool sroll_up) { struct vis_consdisplay da; int i, j; int row_add = 0; term_char_t c; text_attr_t attr; if (sroll_up) row_add = tems.ts_c_dimension.height - 1; da.width = tems.ts_font.vf_width; da.height = tems.ts_font.vf_height; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_SCREEN_REVERSE); /* Make sure we will not draw underlines */ c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' '; tem_callback_bit2pix(tem, &c); da.data = (uint8_t *)tem->tvs_pix_data; for (i = 0; i < nrows; i++, row++) { da.row = (row + row_add) * da.height + offset_y; da.col = col * da.width + offset_x; for (j = 0; j < ncols; j++) { tems_display(&da); da.col += da.width; } } } /* * virtual screen operations */ static void tem_virtual_display(struct tem_vt_state *tem, term_char_t *string, size_t count, screen_pos_t row, screen_pos_t col) { size_t i, width; term_char_t *addr; if (tem->tvs_screen_buf == NULL) return; if (row < 0 || row >= tems.ts_c_dimension.height || col < 0 || col >= tems.ts_c_dimension.width || col + count > (size_t)tems.ts_c_dimension.width) return; width = tems.ts_c_dimension.width; addr = tem->tvs_screen_buf + (row * width + col); for (i = 0; i < count; i++) { *addr++ = string[i]; } } static void tem_virtual_cls(struct tem_vt_state *tem, size_t count, screen_pos_t row, screen_pos_t col) { term_char_t c; text_attr_t attr; tem_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr, TEM_ATTR_SCREEN_REVERSE); /* Make sure we will not draw underlines */ c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' '; while (count > 0) { tem_virtual_display(tem, &c, 1, row, col); col++; count--; } } /*- * Copyright (c) 1998 Robert Nordier * Copyright (c) 2010 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms are freely * permitted provided that the above copyright notice and this * paragraph and the following disclaimer are duplicated in all * such forms. * * This software is provided "AS IS" and without any express or * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. */ #include __FBSDID("$FreeBSD$"); #include #include #include "cons.h" #include "util.h" void memcpy(void *dst, const void *src, int len) { const char *s = src; char *d = dst; while (len--) *d++ = *s++; } void memset(void *b, int c, size_t len) { char *bp = b; while (len--) *bp++ = (unsigned char)c; } int memcmp(const void *b1, const void *b2, size_t len) { const unsigned char *p1, *p2; for (p1 = b1, p2 = b2; len > 0; len--, p1++, p2++) { if (*p1 != *p2) return ((*p1) - (*p2)); } return (0); } int strcmp(const char *s1, const char *s2) { for (; *s1 == *s2 && *s1 != '\0'; s1++, s2++) ; return ((unsigned char)*s1 - (unsigned char)*s2); } int strncmp(const char *s1, const char *s2, size_t len) { for (; len > 0 && *s1 == *s2 && *s1 != '\0'; len--, s1++, s2++) ; return (len == 0 ? 0 : (unsigned char)*s1 - (unsigned char)*s2); } void strcpy(char *dst, const char *src) { while (*src != '\0') *dst++ = *src++; *dst = '\0'; } void strcat(char *dst, const char *src) { while (*dst != '\0') dst++; while (*src != '\0') *dst++ = *src++; *dst = '\0'; } char * strchr(const char *s, char ch) { for (; *s != '\0'; s++) { if (*s == ch) return ((char *)(uintptr_t)(const void *)s); } return (NULL); } size_t strlen(const char *s) { size_t len = 0; while (*s++ != '\0') len++; return (len); } int printf(const char *fmt, ...) { va_list ap; const char *hex = "0123456789abcdef"; char buf[32], *s; uint16_t *S; unsigned long long u; int c, l; va_start(ap, fmt); while ((c = *fmt++) != '\0') { if (c != '%') { putchar(c); continue; } l = 0; nextfmt: c = *fmt++; switch (c) { case 'l': l++; goto nextfmt; case 'c': putchar(va_arg(ap, int)); break; case 's': for (s = va_arg(ap, char *); *s != '\0'; s++) putchar(*s); break; case 'S': /* Assume console can cope with wide chars */ for (S = va_arg(ap, uint16_t *); *S != 0; S++) putchar(*S); break; case 'd': /* A lie, always prints unsigned */ case 'u': case 'x': switch (l) { case 2: u = va_arg(ap, unsigned long long); break; case 1: u = va_arg(ap, unsigned long); break; default: u = va_arg(ap, unsigned int); break; } s = buf; if (c == 'd' || c == 'u') { do *s++ = '0' + (u % 10U); while (u /= 10); } else { do *s++ = hex[u & 0xfu]; while (u >>= 4); } while (--s >= buf) putchar(*s); break; } } va_end(ap); return (0); } /*- * Copyright (c) 2010 Pawel Jakub Dawidek * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. * * $FreeBSD$ */ #ifndef _UTIL_H_ #define _UTIL_H_ #include #include void memcpy(void *dst, const void *src, int len); void memset(void *b, int c, size_t len); int memcmp(const void *b1, const void *b2, size_t len); #define bcopy(src, dst, len) memcpy((dst), (src), (len)) #define bzero(buf, size) memset((buf), 0, (size)) #define bcmp(b1, b2, len) (memcmp((b1), (b2), (len)) != 0) int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t len); void strcpy(char *dst, const char *src); void strcat(char *dst, const char *src); char *strchr(const char *s, char ch); size_t strlen(const char *s); int printf(const char *fmt, ...); #endif /* !_UTIL_H_ */ /* * Copyright 2019 Toomas Soome * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include static int vdisk_init(void); static int vdisk_strategy(void *, int, daddr_t, size_t, char *, size_t *); static int vdisk_open(struct open_file *, ...); static int vdisk_close(struct open_file *); static int vdisk_ioctl(struct open_file *, ulong_t, void *); static int vdisk_print(int); struct devsw vdisk_dev = { .dv_name = "vdisk", .dv_type = DEVT_DISK, .dv_init = vdisk_init, .dv_strategy = vdisk_strategy, .dv_open = vdisk_open, .dv_close = vdisk_close, .dv_ioctl = vdisk_ioctl, .dv_print = vdisk_print, .dv_cleanup = NULL }; typedef STAILQ_HEAD(vdisk_info_list, vdisk_info) vdisk_info_list_t; typedef struct vdisk_info { STAILQ_ENTRY(vdisk_info) vdisk_link; /* link in device list */ char *vdisk_path; int vdisk_unit; int vdisk_fd; uint64_t vdisk_size; /* size in bytes */ uint32_t vdisk_sectorsz; uint32_t vdisk_open; /* reference counter */ } vdisk_info_t; static vdisk_info_list_t vdisk_list; /* list of mapped vdisks. */ static vdisk_info_t * vdisk_get_info(struct devdesc *dev) { vdisk_info_t *vd; STAILQ_FOREACH(vd, &vdisk_list, vdisk_link) { if (vd->vdisk_unit == dev->d_unit) return (vd); } return (vd); } COMMAND_SET(map_vdisk, "map-vdisk", "map file as virtual disk", command_mapvd); static int command_mapvd(int argc, char *argv[]) { vdisk_info_t *vd, *p; struct stat sb; if (argc != 2) { printf("usage: %s filename\n", argv[0]); return (CMD_ERROR); } STAILQ_FOREACH(vd, &vdisk_list, vdisk_link) { if (strcmp(vd->vdisk_path, argv[1]) == 0) { printf("%s: file %s is already mapped as %s%d\n", argv[0], argv[1], vdisk_dev.dv_name, vd->vdisk_unit); return (CMD_ERROR); } } if (stat(argv[1], &sb) < 0) { /* * ENOSYS is really ENOENT because we did try to walk * through devsw list to try to open this file. */ if (errno == ENOSYS) errno = ENOENT; printf("%s: stat failed: %s\n", argv[0], strerror(errno)); return (CMD_ERROR); } /* * Avoid mapping small files. */ if (sb.st_size < 1024 * 1024) { printf("%s: file %s is too small.\n", argv[0], argv[1]); return (CMD_ERROR); } vd = calloc(1, sizeof (*vd)); if (vd == NULL) { printf("%s: out of memory\n", argv[0]); return (CMD_ERROR); } vd->vdisk_path = strdup(argv[1]); if (vd->vdisk_path == NULL) { free(vd); printf("%s: out of memory\n", argv[0]); return (CMD_ERROR); } vd->vdisk_fd = open(vd->vdisk_path, O_RDONLY); if (vd->vdisk_fd < 0) { printf("%s: open failed: %s\n", argv[0], strerror(errno)); free(vd->vdisk_path); free(vd); return (CMD_ERROR); } vd->vdisk_size = sb.st_size; vd->vdisk_sectorsz = DEV_BSIZE; STAILQ_FOREACH(p, &vdisk_list, vdisk_link) { vdisk_info_t *n; if (p->vdisk_unit == vd->vdisk_unit) { vd->vdisk_unit++; continue; } n = STAILQ_NEXT(p, vdisk_link); if (p->vdisk_unit < vd->vdisk_unit) { if (n == NULL) { /* p is last elem */ STAILQ_INSERT_TAIL(&vdisk_list, vd, vdisk_link); break; } if (n->vdisk_unit > vd->vdisk_unit) { /* p < vd < n */ STAILQ_INSERT_AFTER(&vdisk_list, p, vd, vdisk_link); break; } /* else n < vd or n == vd */ vd->vdisk_unit++; continue; } /* p > vd only if p is the first element */ STAILQ_INSERT_HEAD(&vdisk_list, vd, vdisk_link); break; } /* if the list was empty or contiguous */ if (p == NULL) STAILQ_INSERT_TAIL(&vdisk_list, vd, vdisk_link); printf("%s: file %s is mapped as %s%d\n", argv[0], vd->vdisk_path, vdisk_dev.dv_name, vd->vdisk_unit); return (CMD_OK); } COMMAND_SET(unmap_vdisk, "unmap-vdisk", "unmap virtual disk", command_unmapvd); /* * unmap-vdisk vdiskX */ static int command_unmapvd(int argc, char *argv[]) { size_t len; vdisk_info_t *vd; long unit; char *end; if (argc != 2) { printf("usage: %s %sN\n", argv[0], vdisk_dev.dv_name); return (CMD_ERROR); } len = strlen(vdisk_dev.dv_name); if (strncmp(vdisk_dev.dv_name, argv[1], len) != 0) { printf("%s: unknown device %s\n", argv[0], argv[1]); return (CMD_ERROR); } errno = 0; unit = strtol(argv[1] + len, &end, 10); if (errno != 0 || (*end != '\0' && strcmp(end, ":") != 0)) { printf("%s: unknown device %s\n", argv[0], argv[1]); return (CMD_ERROR); } STAILQ_FOREACH(vd, &vdisk_list, vdisk_link) { if (vd->vdisk_unit == unit) break; } if (vd == NULL) { printf("%s: unknown device %s\n", argv[0], argv[1]); return (CMD_ERROR); } if (vd->vdisk_open != 0) { printf("%s: %s is in use, unable to unmap.\n", argv[0], argv[1]); return (CMD_ERROR); } STAILQ_REMOVE(&vdisk_list, vd, vdisk_info, vdisk_link); (void) close(vd->vdisk_fd); printf("%s (%s) unmapped\n", argv[1], vd->vdisk_path); free(vd->vdisk_path); free(vd); return (CMD_OK); } static int vdisk_init(void) { STAILQ_INIT(&vdisk_list); return (0); } static int vdisk_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct disk_devdesc *dev; vdisk_info_t *vd; ssize_t rv; dev = devdata; if (dev == NULL) return (EINVAL); vd = vdisk_get_info((struct devdesc *)dev); if (vd == NULL) return (EINVAL); if (size == 0 || (size % 512) != 0) return (EIO); if (dev->dd.d_dev->dv_type == DEVT_DISK) { daddr_t offset; offset = dev->d_offset * vd->vdisk_sectorsz; offset /= 512; blk += offset; } if (lseek(vd->vdisk_fd, blk << 9, SEEK_SET) == -1) return (EIO); errno = 0; switch (rw & F_MASK) { case F_READ: rv = read(vd->vdisk_fd, buf, size); break; case F_WRITE: rv = write(vd->vdisk_fd, buf, size); break; default: return (ENOSYS); } if (errno == 0 && rsize != NULL) { *rsize = rv; } return (errno); } static int vdisk_open(struct open_file *f, ...) { va_list args; struct disk_devdesc *dev; vdisk_info_t *vd; int rc = 0; va_start(args, f); dev = va_arg(args, struct disk_devdesc *); va_end(args); if (dev == NULL) return (EINVAL); vd = vdisk_get_info((struct devdesc *)dev); if (vd == NULL) return (EINVAL); if (dev->dd.d_dev->dv_type == DEVT_DISK) { rc = disk_open(dev, vd->vdisk_size, vd->vdisk_sectorsz); } if (rc == 0) vd->vdisk_open++; return (rc); } static int vdisk_close(struct open_file *f) { struct disk_devdesc *dev; vdisk_info_t *vd; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); vd = vdisk_get_info((struct devdesc *)dev); if (vd == NULL) return (EINVAL); vd->vdisk_open--; if (dev->dd.d_dev->dv_type == DEVT_DISK) return (disk_close(dev)); return (0); } static int vdisk_ioctl(struct open_file *f, ulong_t cmd, void *data) { struct disk_devdesc *dev; vdisk_info_t *vd; int rc; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); vd = vdisk_get_info((struct devdesc *)dev); if (vd == NULL) return (EINVAL); if (dev->dd.d_dev->dv_type == DEVT_DISK) { rc = disk_ioctl(dev, cmd, data); if (rc != ENOTTY) return (rc); } switch (cmd) { case DIOCGSECTORSIZE: *(uint_t *)data = vd->vdisk_sectorsz; break; case DIOCGMEDIASIZE: *(uint64_t *)data = vd->vdisk_size; break; default: return (ENOTTY); } return (0); } static int vdisk_print(int verbose) { int ret = 0; vdisk_info_t *vd; char line[80]; if (STAILQ_EMPTY(&vdisk_list)) return (ret); printf("%s devices:", vdisk_dev.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); STAILQ_FOREACH(vd, &vdisk_list, vdisk_link) { struct disk_devdesc vd_dev; if (verbose) { printf(" %s", vd->vdisk_path); if ((ret = pager_output("\n")) != 0) break; } snprintf(line, sizeof (line), " %s%d", vdisk_dev.dv_name, vd->vdisk_unit); printf("%s: %" PRIu64 " X %u blocks", line, vd->vdisk_size / vd->vdisk_sectorsz, vd->vdisk_sectorsz); if ((ret = pager_output("\n")) != 0) break; vd_dev.dd.d_dev = &vdisk_dev; vd_dev.dd.d_unit = vd->vdisk_unit; vd_dev.d_slice = -1; vd_dev.d_partition = -1; ret = disk_open(&vd_dev, vd->vdisk_size, vd->vdisk_sectorsz); if (ret == 0) { ret = disk_print(&vd_dev, line, verbose); disk_close(&vd_dev); if (ret != 0) break; } else { ret = 0; } } return (ret); } /* * Copyright (c) 2018 Warner Losh * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include "bootstrap.h" #include "libzfs.h" COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset", command_lszfs); static int command_lszfs(int argc, char *argv[]) { int err; if (argc != 2) { command_errmsg = "a single dataset must be supplied"; return (CMD_ERROR); } err = zfs_list(argv[1]); if (err != 0) { command_errmsg = strerror(err); return (CMD_ERROR); } return (CMD_OK); } uint64_t ldi_get_size(void *priv) { int fd = (uintptr_t) priv; uint64_t size; ioctl(fd, DIOCGMEDIASIZE, &size); return (size); } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2015 Toomas Soome # .KEEP_STATE: include $(SRC)/Makefile.master SUBDIRS = libefi loader all install clean clobber: $(SUBDIRS) all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber install : TARGET = install loader: libefi .PARALLEL: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2015 Toomas Soome # # Options used when building app-specific efi components CFLAGS += -fshort-wchar $(C_BIGPICFLAGS) .PARALLEL: /** @file Root include file for Mde Package Base type modules This is the include file for any module of type base. Base modules only use types defined via this include file and can be ported easily to any environment. There are a set of base libraries in the Mde Package that can be used to implement base modules. Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __BASE_H__ #define __BASE_H__ // // Include processor specific binding // #include #if defined (_MSC_EXTENSIONS) // // Disable warning when last field of data structure is a zero sized array. // #pragma warning ( disable : 4200 ) #endif // // The Microsoft* C compiler can removed references to unreferenced data items // if the /OPT:REF linker option is used. We defined a macro as this is a // a non standard extension // #if defined (_MSC_VER) && _MSC_VER < 1800 && !defined (MDE_CPU_EBC) /// /// Remove global variable from the linked image if there are no references to /// it after all compiler and linker optimizations have been performed. /// /// #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) #else /// /// Remove the global variable from the linked image if there are no references /// to it after all compiler and linker optimizations have been performed. /// /// #define GLOBAL_REMOVE_IF_UNREFERENCED #endif // // Should be used in combination with NORETURN to avoid 'noreturn' returns // warnings. // #ifndef UNREACHABLE #ifdef __GNUC__ /// /// Signal compilers and analyzers that this call is not reachable. It is /// up to the compiler to remove any code past that point. /// #define UNREACHABLE() __builtin_unreachable () #elif defined (__has_feature) #if __has_builtin (__builtin_unreachable) /// /// Signal compilers and analyzers that this call is not reachable. It is /// up to the compiler to remove any code past that point. /// #define UNREACHABLE() __builtin_unreachable () #endif #endif #ifndef UNREACHABLE /// /// Signal compilers and analyzers that this call is not reachable. It is /// up to the compiler to remove any code past that point. /// #define UNREACHABLE() #endif #endif // // Signaling compilers and analyzers that a certain function cannot return may // remove all following code and thus lead to better optimization and less // false positives. // #ifndef NORETURN #if defined (__GNUC__) || defined (__clang__) /// /// Signal compilers and analyzers that the function cannot return. /// It is up to the compiler to remove any code past a call to functions /// flagged with this attribute. /// #define NORETURN __attribute__((noreturn)) #elif defined (_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC) /// /// Signal compilers and analyzers that the function cannot return. /// It is up to the compiler to remove any code past a call to functions /// flagged with this attribute. /// #define NORETURN __declspec(noreturn) #else /// /// Signal compilers and analyzers that the function cannot return. /// It is up to the compiler to remove any code past a call to functions /// flagged with this attribute. /// #define NORETURN #endif #endif // // Should be used in combination with ANALYZER_NORETURN to avoid 'noreturn' // returns warnings. // #ifndef ANALYZER_UNREACHABLE #ifdef __clang_analyzer__ #if __has_builtin (__builtin_unreachable) /// /// Signal the analyzer that this call is not reachable. /// This excludes compilers. /// #define ANALYZER_UNREACHABLE() __builtin_unreachable () #endif #endif #ifndef ANALYZER_UNREACHABLE /// /// Signal the analyzer that this call is not reachable. /// This excludes compilers. /// #define ANALYZER_UNREACHABLE() #endif #endif // // Static Analyzers may issue errors about potential NULL-dereferences when // dereferencing a pointer, that has been checked before, outside of a // NULL-check. This may lead to false positives, such as when using ASSERT() // for verification. // #ifndef ANALYZER_NORETURN #ifdef __has_feature #if __has_feature (attribute_analyzer_noreturn) /// /// Signal analyzers that the function cannot return. /// This excludes compilers. /// #define ANALYZER_NORETURN __attribute__((analyzer_noreturn)) #endif #endif #ifndef ANALYZER_NORETURN /// /// Signal the analyzer that the function cannot return. /// This excludes compilers. /// #define ANALYZER_NORETURN #endif #endif /// /// Tell the code optimizer that the function will return twice. /// This prevents wrong optimizations which can cause bugs. /// #ifndef RETURNS_TWICE #if defined (__GNUC__) || defined (__clang__) /// /// Tell the code optimizer that the function will return twice. /// This prevents wrong optimizations which can cause bugs. /// #define RETURNS_TWICE __attribute__((returns_twice)) #else /// /// Tell the code optimizer that the function will return twice. /// This prevents wrong optimizations which can cause bugs. /// #define RETURNS_TWICE #endif #endif // // For symbol name in assembly code, an extra "_" is sometimes necessary // /// /// Private worker functions for ASM_PFX() /// #define _CONCATENATE(a, b) __CONCATENATE(a, b) #define __CONCATENATE(a, b) a ## b /// /// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix /// on symbols in assembly language. /// #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name) #ifdef __APPLE__ // // Apple extension that is used by the linker to optimize code size // with assembly functions. Put at the end of your .S files // #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED .subsections_via_symbols #else #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED #endif #ifdef __CC_ARM // // Older RVCT ARM compilers don't fully support #pragma pack and require __packed // as a prefix for the structure. // #define PACKED __packed #else #define PACKED #endif /// /// 128 bit buffer containing a unique identifier value. /// Unless otherwise specified, aligned on a 64 bit boundary. /// typedef struct { UINT32 Data1; UINT16 Data2; UINT16 Data3; UINT8 Data4[8]; } GUID; /// /// 4-byte buffer. An IPv4 internet protocol address. /// typedef struct { UINT8 Addr[4]; } IPv4_ADDRESS; /// /// 16-byte buffer. An IPv6 internet protocol address. /// typedef struct { UINT8 Addr[16]; } IPv6_ADDRESS; // // 8-bytes unsigned value that represents a physical system address. // typedef UINT64 PHYSICAL_ADDRESS; /// /// LIST_ENTRY structure definition. /// typedef struct _LIST_ENTRY LIST_ENTRY; /// /// _LIST_ENTRY structure definition. /// struct _LIST_ENTRY { LIST_ENTRY *ForwardLink; LIST_ENTRY *BackLink; }; // // Modifiers to abstract standard types to aid in debug of problems // /// /// Datum is read-only. /// #define CONST const /// /// Datum is scoped to the current file or function. /// #define STATIC static /// /// Undeclared type. /// #define VOID void // // Modifiers for Data Types used to self document code. // This concept is borrowed for UEFI specification. // /// /// Datum is passed to the function. /// #define IN /// /// Datum is returned from the function. /// #define OUT /// /// Passing the datum to the function is optional, and a NULL /// is passed if the value is not supplied. /// #define OPTIONAL // // UEFI specification claims 1 and 0. We are concerned about the // compiler portability so we did it this way. // /// /// Boolean true value. UEFI Specification defines this value to be 1, /// but this form is more portable. /// #define TRUE ((BOOLEAN)(1==1)) /// /// Boolean false value. UEFI Specification defines this value to be 0, /// but this form is more portable. /// #define FALSE ((BOOLEAN)(0==1)) /// /// NULL pointer (VOID *) /// #ifndef NULL #define NULL ((VOID *) 0) #endif // // Null character // #define CHAR_NULL 0x0000 /// /// Maximum values for common UEFI Data Types /// #define MAX_INT8 ((INT8)0x7F) #define MAX_UINT8 ((UINT8)0xFF) #define MAX_INT16 ((INT16)0x7FFF) #define MAX_UINT16 ((UINT16)0xFFFF) #define MAX_INT32 ((INT32)0x7FFFFFFF) #define MAX_UINT32 ((UINT32)0xFFFFFFFF) #define MAX_INT64 ((INT64)0x7FFFFFFFFFFFFFFFULL) #define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL) /// /// Minimum values for the signed UEFI Data Types /// #define MIN_INT8 (((INT8) -127) - 1) #define MIN_INT16 (((INT16) -32767) - 1) #define MIN_INT32 (((INT32) -2147483647) - 1) #define MIN_INT64 (((INT64) -9223372036854775807LL) - 1) #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 #define BIT3 0x00000008 #define BIT4 0x00000010 #define BIT5 0x00000020 #define BIT6 0x00000040 #define BIT7 0x00000080 #define BIT8 0x00000100 #define BIT9 0x00000200 #define BIT10 0x00000400 #define BIT11 0x00000800 #define BIT12 0x00001000 #define BIT13 0x00002000 #define BIT14 0x00004000 #define BIT15 0x00008000 #define BIT16 0x00010000 #define BIT17 0x00020000 #define BIT18 0x00040000 #define BIT19 0x00080000 #define BIT20 0x00100000 #define BIT21 0x00200000 #define BIT22 0x00400000 #define BIT23 0x00800000 #define BIT24 0x01000000 #define BIT25 0x02000000 #define BIT26 0x04000000 #define BIT27 0x08000000 #define BIT28 0x10000000 #define BIT29 0x20000000 #define BIT30 0x40000000 #define BIT31 0x80000000 #define BIT32 0x0000000100000000ULL #define BIT33 0x0000000200000000ULL #define BIT34 0x0000000400000000ULL #define BIT35 0x0000000800000000ULL #define BIT36 0x0000001000000000ULL #define BIT37 0x0000002000000000ULL #define BIT38 0x0000004000000000ULL #define BIT39 0x0000008000000000ULL #define BIT40 0x0000010000000000ULL #define BIT41 0x0000020000000000ULL #define BIT42 0x0000040000000000ULL #define BIT43 0x0000080000000000ULL #define BIT44 0x0000100000000000ULL #define BIT45 0x0000200000000000ULL #define BIT46 0x0000400000000000ULL #define BIT47 0x0000800000000000ULL #define BIT48 0x0001000000000000ULL #define BIT49 0x0002000000000000ULL #define BIT50 0x0004000000000000ULL #define BIT51 0x0008000000000000ULL #define BIT52 0x0010000000000000ULL #define BIT53 0x0020000000000000ULL #define BIT54 0x0040000000000000ULL #define BIT55 0x0080000000000000ULL #define BIT56 0x0100000000000000ULL #define BIT57 0x0200000000000000ULL #define BIT58 0x0400000000000000ULL #define BIT59 0x0800000000000000ULL #define BIT60 0x1000000000000000ULL #define BIT61 0x2000000000000000ULL #define BIT62 0x4000000000000000ULL #define BIT63 0x8000000000000000ULL #define SIZE_1KB 0x00000400 #define SIZE_2KB 0x00000800 #define SIZE_4KB 0x00001000 #define SIZE_8KB 0x00002000 #define SIZE_16KB 0x00004000 #define SIZE_32KB 0x00008000 #define SIZE_64KB 0x00010000 #define SIZE_128KB 0x00020000 #define SIZE_256KB 0x00040000 #define SIZE_512KB 0x00080000 #define SIZE_1MB 0x00100000 #define SIZE_2MB 0x00200000 #define SIZE_4MB 0x00400000 #define SIZE_8MB 0x00800000 #define SIZE_16MB 0x01000000 #define SIZE_32MB 0x02000000 #define SIZE_64MB 0x04000000 #define SIZE_128MB 0x08000000 #define SIZE_256MB 0x10000000 #define SIZE_512MB 0x20000000 #define SIZE_1GB 0x40000000 #define SIZE_2GB 0x80000000 #define SIZE_4GB 0x0000000100000000ULL #define SIZE_8GB 0x0000000200000000ULL #define SIZE_16GB 0x0000000400000000ULL #define SIZE_32GB 0x0000000800000000ULL #define SIZE_64GB 0x0000001000000000ULL #define SIZE_128GB 0x0000002000000000ULL #define SIZE_256GB 0x0000004000000000ULL #define SIZE_512GB 0x0000008000000000ULL #define SIZE_1TB 0x0000010000000000ULL #define SIZE_2TB 0x0000020000000000ULL #define SIZE_4TB 0x0000040000000000ULL #define SIZE_8TB 0x0000080000000000ULL #define SIZE_16TB 0x0000100000000000ULL #define SIZE_32TB 0x0000200000000000ULL #define SIZE_64TB 0x0000400000000000ULL #define SIZE_128TB 0x0000800000000000ULL #define SIZE_256TB 0x0001000000000000ULL #define SIZE_512TB 0x0002000000000000ULL #define SIZE_1PB 0x0004000000000000ULL #define SIZE_2PB 0x0008000000000000ULL #define SIZE_4PB 0x0010000000000000ULL #define SIZE_8PB 0x0020000000000000ULL #define SIZE_16PB 0x0040000000000000ULL #define SIZE_32PB 0x0080000000000000ULL #define SIZE_64PB 0x0100000000000000ULL #define SIZE_128PB 0x0200000000000000ULL #define SIZE_256PB 0x0400000000000000ULL #define SIZE_512PB 0x0800000000000000ULL #define SIZE_1EB 0x1000000000000000ULL #define SIZE_2EB 0x2000000000000000ULL #define SIZE_4EB 0x4000000000000000ULL #define SIZE_8EB 0x8000000000000000ULL #define BASE_1KB 0x00000400 #define BASE_2KB 0x00000800 #define BASE_4KB 0x00001000 #define BASE_8KB 0x00002000 #define BASE_16KB 0x00004000 #define BASE_32KB 0x00008000 #define BASE_64KB 0x00010000 #define BASE_128KB 0x00020000 #define BASE_256KB 0x00040000 #define BASE_512KB 0x00080000 #define BASE_1MB 0x00100000 #define BASE_2MB 0x00200000 #define BASE_4MB 0x00400000 #define BASE_8MB 0x00800000 #define BASE_16MB 0x01000000 #define BASE_32MB 0x02000000 #define BASE_64MB 0x04000000 #define BASE_128MB 0x08000000 #define BASE_256MB 0x10000000 #define BASE_512MB 0x20000000 #define BASE_1GB 0x40000000 #define BASE_2GB 0x80000000 #define BASE_4GB 0x0000000100000000ULL #define BASE_8GB 0x0000000200000000ULL #define BASE_16GB 0x0000000400000000ULL #define BASE_32GB 0x0000000800000000ULL #define BASE_64GB 0x0000001000000000ULL #define BASE_128GB 0x0000002000000000ULL #define BASE_256GB 0x0000004000000000ULL #define BASE_512GB 0x0000008000000000ULL #define BASE_1TB 0x0000010000000000ULL #define BASE_2TB 0x0000020000000000ULL #define BASE_4TB 0x0000040000000000ULL #define BASE_8TB 0x0000080000000000ULL #define BASE_16TB 0x0000100000000000ULL #define BASE_32TB 0x0000200000000000ULL #define BASE_64TB 0x0000400000000000ULL #define BASE_128TB 0x0000800000000000ULL #define BASE_256TB 0x0001000000000000ULL #define BASE_512TB 0x0002000000000000ULL #define BASE_1PB 0x0004000000000000ULL #define BASE_2PB 0x0008000000000000ULL #define BASE_4PB 0x0010000000000000ULL #define BASE_8PB 0x0020000000000000ULL #define BASE_16PB 0x0040000000000000ULL #define BASE_32PB 0x0080000000000000ULL #define BASE_64PB 0x0100000000000000ULL #define BASE_128PB 0x0200000000000000ULL #define BASE_256PB 0x0400000000000000ULL #define BASE_512PB 0x0800000000000000ULL #define BASE_1EB 0x1000000000000000ULL #define BASE_2EB 0x2000000000000000ULL #define BASE_4EB 0x4000000000000000ULL #define BASE_8EB 0x8000000000000000ULL // // Support for variable argument lists in freestanding edk2 modules. // // For modules that use the ISO C library interfaces for variable // argument lists, refer to "StdLib/Include/stdarg.h". // // VA_LIST - typedef for argument list. // VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use. // VA_END (VA_LIST Marker) - Clear Marker // VA_ARG (VA_LIST Marker, var arg type) - Use Marker to get an argument from // the ... list. You must know the type and pass it in this macro. Type // must be compatible with the type of the actual next argument (as promoted // according to the default argument promotions.) // VA_COPY (VA_LIST Dest, VA_LIST Start) - Initialize Dest as a copy of Start. // // Example: // // UINTN // EFIAPI // ExampleVarArg ( // IN UINTN NumberOfArgs, // ... // ) // { // VA_LIST Marker; // UINTN Index; // UINTN Result; // // // // // Initialize the Marker // // // VA_START (Marker, NumberOfArgs); // for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) { // // // // The ... list is a series of UINTN values, so sum them up. // // // Result += VA_ARG (Marker, UINTN); // } // // VA_END (Marker); // return Result; // } // // Notes: // - Functions that call VA_START() / VA_END() must have a variable // argument list and must be declared EFIAPI. // - Functions that call VA_COPY() / VA_END() must be declared EFIAPI. // - Functions that only use VA_LIST and VA_ARG() need not be EFIAPI. // /** Return the size of argument that has been aligned to sizeof (UINTN). @param n The parameter size to be aligned. @return The aligned size. **/ #define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) #if defined (__CC_ARM) // // RVCT ARM variable argument list support. // /// /// Variable used to traverse the list of arguments. This type can vary by /// implementation and could be an array or structure. /// #ifdef __APCS_ADSABI typedef int *va_list[1]; #define VA_LIST va_list #else typedef struct __va_list { void *__ap; } va_list; #define VA_LIST va_list #endif #define VA_START(Marker, Parameter) __va_start(Marker, Parameter) #define VA_ARG(Marker, TYPE) __va_arg(Marker, TYPE) #define VA_END(Marker) ((void)0) // For some ARM RVCT compilers, __va_copy is not defined #ifndef __va_copy #define __va_copy(dest, src) ((void)((dest) = (src))) #endif #define VA_COPY(Dest, Start) __va_copy (Dest, Start) #elif defined (_M_ARM) || defined (_M_ARM64) // // MSFT ARM variable argument list support. // typedef char *VA_LIST; #define VA_START(Marker, Parameter) __va_start (&Marker, &Parameter, _INT_SIZE_OF (Parameter), __alignof(Parameter), &Parameter) #define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE) + ((-(INTN)Marker) & (sizeof(TYPE) - 1))) - _INT_SIZE_OF (TYPE))) #define VA_END(Marker) (Marker = (VA_LIST) 0) #define VA_COPY(Dest, Start) ((void)((Dest) = (Start))) #elif defined (__GNUC__) || defined (__clang__) #if defined (MDE_CPU_X64) && !defined (NO_MSABI_VA_FUNCS) // // X64 only. Use MS ABI version of GCC built-in macros for variable argument lists. // /// /// Both GCC and LLVM 3.8 for X64 support new variable argument intrinsics for Microsoft ABI /// /// /// Variable used to traverse the list of arguments. This type can vary by /// implementation and could be an array or structure. /// typedef __builtin_ms_va_list VA_LIST; #define VA_START(Marker, Parameter) __builtin_ms_va_start (Marker, Parameter) #define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE))) #define VA_END(Marker) __builtin_ms_va_end (Marker) #define VA_COPY(Dest, Start) __builtin_ms_va_copy (Dest, Start) #else // // Use GCC built-in macros for variable argument lists. // /// /// Variable used to traverse the list of arguments. This type can vary by /// implementation and could be an array or structure. /// typedef __builtin_va_list VA_LIST; #define VA_START(Marker, Parameter) __builtin_va_start (Marker, Parameter) #define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE))) #define VA_END(Marker) __builtin_va_end (Marker) #define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start) #endif #else /// /// Variable used to traverse the list of arguments. This type can vary by /// implementation and could be an array or structure. /// typedef CHAR8 *VA_LIST; /** Retrieves a pointer to the beginning of a variable argument list, based on the name of the parameter that immediately precedes the variable argument list. This function initializes Marker to point to the beginning of the variable argument list that immediately follows Parameter. The method for computing the pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI. @param Marker The VA_LIST used to traverse the list of arguments. @param Parameter The name of the parameter that immediately precedes the variable argument list. @return A pointer to the beginning of a variable argument list. **/ #define VA_START(Marker, Parameter) (Marker = (VA_LIST) ((UINTN) & (Parameter) + _INT_SIZE_OF (Parameter))) /** Returns an argument of a specified type from a variable argument list and updates the pointer to the variable argument list to point to the next argument. This function returns an argument of the type specified by TYPE from the beginning of the variable argument list specified by Marker. Marker is then updated to point to the next argument in the variable argument list. The method for computing the pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI. @param Marker VA_LIST used to traverse the list of arguments. @param TYPE The type of argument to retrieve from the beginning of the variable argument list. @return An argument of the type specified by TYPE. **/ #define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE))) /** Terminates the use of a variable argument list. This function initializes Marker so it can no longer be used with VA_ARG(). After this macro is used, the only way to access the variable argument list is by using VA_START() again. @param Marker VA_LIST used to traverse the list of arguments. **/ #define VA_END(Marker) (Marker = (VA_LIST) 0) /** Initializes a VA_LIST as a copy of an existing VA_LIST. This macro initializes Dest as a copy of Start, as if the VA_START macro had been applied to Dest followed by the same sequence of uses of the VA_ARG macro as had previously been used to reach the present state of Start. @param Dest VA_LIST used to traverse the list of arguments. @param Start VA_LIST used to traverse the list of arguments. **/ #define VA_COPY(Dest, Start) ((void)((Dest) = (Start))) #endif /// /// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *. /// typedef UINTN *BASE_LIST; /** Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary. @param TYPE The date type to determine the size of. @return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary. **/ #define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN)) /** Returns an argument of a specified type from a variable argument list and updates the pointer to the variable argument list to point to the next argument. This function returns an argument of the type specified by TYPE from the beginning of the variable argument list specified by Marker. Marker is then updated to point to the next argument in the variable argument list. The method for computing the pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI. @param Marker The pointer to the beginning of a variable argument list. @param TYPE The type of argument to retrieve from the beginning of the variable argument list. @return An argument of the type specified by TYPE. **/ #define BASE_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE))) /** The macro that returns the byte offset of a field in a data structure. This function returns the offset, in bytes, of field specified by Field from the beginning of the data structure specified by TYPE. If TYPE does not contain Field, the module will not compile. @param TYPE The name of the data structure that contains the field specified by Field. @param Field The name of the field in the data structure. @return Offset, in bytes, of field. **/ #if (defined (__GNUC__) && __GNUC__ >= 4) || defined (__clang__) #define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field)) #endif #ifndef OFFSET_OF #define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field)) #endif /** Portable definition for compile time assertions. Equivalent to C11 static_assert macro from assert.h. @param Expression Boolean expression. @param Message Raised compiler diagnostic message when expression is false. **/ #ifdef MDE_CPU_EBC #define STATIC_ASSERT(Expression, Message) #elif defined (_MSC_EXTENSIONS) #define STATIC_ASSERT static_assert #else #define STATIC_ASSERT _Static_assert #endif // // Verify that ProcessorBind.h produced UEFI Data Types that are compliant with // Section 2.3.1 of the UEFI 2.3 Specification. // STATIC_ASSERT (sizeof (BOOLEAN) == 1, "sizeof (BOOLEAN) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (INT8) == 1, "sizeof (INT8) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (UINT8) == 1, "sizeof (UINT8) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (INT16) == 2, "sizeof (INT16) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (UINT16) == 2, "sizeof (UINT16) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (INT32) == 4, "sizeof (INT32) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (UINT32) == 4, "sizeof (UINT32) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (INT64) == 8, "sizeof (INT64) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (UINT64) == 8, "sizeof (UINT64) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (CHAR8) == 1, "sizeof (CHAR8) does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (CHAR16) == 2, "sizeof (CHAR16) does not meet UEFI Specification Data Type requirements"); // Apparently, gcc 7 and gcc 10 fail with those, gcc 12 seems to be ok. // STATIC_ASSERT (sizeof (L'A') == 2, "sizeof (L'A') does not meet UEFI Specification Data Type requirements"); // STATIC_ASSERT (sizeof (L"A") == 4, "sizeof (L\"A\") does not meet UEFI Specification Data Type requirements"); // // The following three enum types are used to verify that the compiler // configuration for enum types is compliant with Section 2.3.1 of the // UEFI 2.3 Specification. These enum types and enum values are not // intended to be used. A prefix of '__' is used avoid conflicts with // other types. // typedef enum { __VerifyUint8EnumValue = 0xff } __VERIFY_UINT8_ENUM_SIZE; typedef enum { __VerifyUint16EnumValue = 0xffff } __VERIFY_UINT16_ENUM_SIZE; typedef enum { __VerifyUint32EnumValue = 0xffffffff } __VERIFY_UINT32_ENUM_SIZE; STATIC_ASSERT (sizeof (__VERIFY_UINT8_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (__VERIFY_UINT16_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (__VERIFY_UINT32_ENUM_SIZE) == 4, "Size of enum does not meet UEFI Specification Data Type requirements"); /** Macro that returns a pointer to the data structure that contains a specified field of that data structure. This is a lightweight method to hide information by placing a public data structure inside a larger private data structure and using a pointer to the public data structure to retrieve a pointer to the private data structure. This function computes the offset, in bytes, of field specified by Field from the beginning of the data structure specified by TYPE. This offset is subtracted from Record, and is used to return a pointer to a data structure of the type specified by TYPE. If the data type specified by TYPE does not contain the field specified by Field, then the module will not compile. @param Record Pointer to the field specified by Field within a data structure of type TYPE. @param TYPE The name of the data structure type to return. This data structure must contain the field specified by Field. @param Field The name of the field in the data structure specified by TYPE to which Record points. @return A pointer to the structure from one of it's elements. **/ #define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field))) /** Rounds a value up to the next boundary using a specified alignment. This function rounds Value up to the next boundary using the specified Alignment. This aligned value is returned. @param Value The value to round up. @param Alignment The alignment boundary used to return the aligned value. @return A value up to the next boundary. **/ #define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1))) /** Adjust a pointer by adding the minimum offset required for it to be aligned on a specified alignment boundary. This function rounds the pointer specified by Pointer to the next alignment boundary specified by Alignment. The pointer to the aligned address is returned. @param Pointer The pointer to round up. @param Alignment The alignment boundary to use to return an aligned pointer. @return Pointer to the aligned address. **/ #define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment)))) /** Rounds a value up to the next natural boundary for the current CPU. This is 4-bytes for 32-bit CPUs and 8-bytes for 64-bit CPUs. This function rounds the value specified by Value up to the next natural boundary for the current CPU. This rounded value is returned. @param Value The value to round up. @return Rounded value specified by Value. **/ #define ALIGN_VARIABLE(Value) ALIGN_VALUE ((Value), sizeof (UINTN)) /** Return the absolute value of a signed operand. This macro returns the absolute value of the signed operand specified by a. @param a The signed operand. @return The absolute value of the signed operand. **/ #define ABS(a) \ (((a) < 0) ? (-(a)) : (a)) // // Status codes common to all execution phases // typedef UINTN RETURN_STATUS; /** Produces a RETURN_STATUS code with the highest bit set. @param StatusCode The status code value to convert into a warning code. StatusCode must be in the range 0x00000000..0x7FFFFFFF. @return The value specified by StatusCode with the highest bit set. **/ #define ENCODE_ERROR(StatusCode) ((RETURN_STATUS)(MAX_BIT | (StatusCode))) /** Produces a RETURN_STATUS code with the highest bit clear. @param StatusCode The status code value to convert into a warning code. StatusCode must be in the range 0x00000000..0x7FFFFFFF. @return The value specified by StatusCode with the highest bit clear. **/ #define ENCODE_WARNING(StatusCode) ((RETURN_STATUS)(StatusCode)) /** Returns TRUE if a specified RETURN_STATUS code is an error code. This function returns TRUE if StatusCode has the high bit set. Otherwise, FALSE is returned. @param StatusCode The status code value to evaluate. @retval TRUE The high bit of StatusCode is set. @retval FALSE The high bit of StatusCode is clear. **/ #define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0) /// /// The operation completed successfully. /// #define RETURN_SUCCESS 0 /// /// The image failed to load. /// #define RETURN_LOAD_ERROR ENCODE_ERROR (1) /// /// The parameter was incorrect. /// #define RETURN_INVALID_PARAMETER ENCODE_ERROR (2) /// /// The operation is not supported. /// #define RETURN_UNSUPPORTED ENCODE_ERROR (3) /// /// The buffer was not the proper size for the request. /// #define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4) /// /// The buffer was not large enough to hold the requested data. /// The required buffer size is returned in the appropriate /// parameter when this error occurs. /// #define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5) /// /// There is no data pending upon return. /// #define RETURN_NOT_READY ENCODE_ERROR (6) /// /// The physical device reported an error while attempting the /// operation. /// #define RETURN_DEVICE_ERROR ENCODE_ERROR (7) /// /// The device can not be written to. /// #define RETURN_WRITE_PROTECTED ENCODE_ERROR (8) /// /// The resource has run out. /// #define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9) /// /// An inconsistency was detected on the file system causing the /// operation to fail. /// #define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10) /// /// There is no more space on the file system. /// #define RETURN_VOLUME_FULL ENCODE_ERROR (11) /// /// The device does not contain any medium to perform the /// operation. /// #define RETURN_NO_MEDIA ENCODE_ERROR (12) /// /// The medium in the device has changed since the last /// access. /// #define RETURN_MEDIA_CHANGED ENCODE_ERROR (13) /// /// The item was not found. /// #define RETURN_NOT_FOUND ENCODE_ERROR (14) /// /// Access was denied. /// #define RETURN_ACCESS_DENIED ENCODE_ERROR (15) /// /// The server was not found or did not respond to the request. /// #define RETURN_NO_RESPONSE ENCODE_ERROR (16) /// /// A mapping to the device does not exist. /// #define RETURN_NO_MAPPING ENCODE_ERROR (17) /// /// A timeout time expired. /// #define RETURN_TIMEOUT ENCODE_ERROR (18) /// /// The protocol has not been started. /// #define RETURN_NOT_STARTED ENCODE_ERROR (19) /// /// The protocol has already been started. /// #define RETURN_ALREADY_STARTED ENCODE_ERROR (20) /// /// The operation was aborted. /// #define RETURN_ABORTED ENCODE_ERROR (21) /// /// An ICMP error occurred during the network operation. /// #define RETURN_ICMP_ERROR ENCODE_ERROR (22) /// /// A TFTP error occurred during the network operation. /// #define RETURN_TFTP_ERROR ENCODE_ERROR (23) /// /// A protocol error occurred during the network operation. /// #define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24) /// /// A function encountered an internal version that was /// incompatible with a version requested by the caller. /// #define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25) /// /// The function was not performed due to a security violation. /// #define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26) /// /// A CRC error was detected. /// #define RETURN_CRC_ERROR ENCODE_ERROR (27) /// /// The beginning or end of media was reached. /// #define RETURN_END_OF_MEDIA ENCODE_ERROR (28) /// /// The end of the file was reached. /// #define RETURN_END_OF_FILE ENCODE_ERROR (31) /// /// The language specified was invalid. /// #define RETURN_INVALID_LANGUAGE ENCODE_ERROR (32) /// /// The security status of the data is unknown or compromised /// and the data must be updated or replaced to restore a valid /// security status. /// #define RETURN_COMPROMISED_DATA ENCODE_ERROR (33) /// /// A HTTP error occurred during the network operation. /// #define RETURN_HTTP_ERROR ENCODE_ERROR (35) /// /// The string contained one or more characters that /// the device could not render and were skipped. /// #define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1) /// /// The handle was closed, but the file was not deleted. /// #define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2) /// /// The handle was closed, but the data to the file was not /// flushed properly. /// #define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3) /// /// The resulting buffer was too small, and the data was /// truncated to the buffer size. /// #define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4) /// /// The data has not been updated within the timeframe set by /// local policy for this type of data. /// #define RETURN_WARN_STALE_DATA ENCODE_WARNING (5) /// /// The resulting buffer contains UEFI-compliant file system. /// #define RETURN_WARN_FILE_SYSTEM ENCODE_WARNING (6) /** Returns a 16-bit signature built from 2 ASCII characters. This macro returns a 16-bit value built from the two ASCII characters specified by A and B. @param A The first ASCII character. @param B The second ASCII character. @return A 16-bit value built from the two ASCII characters specified by A and B. **/ #define SIGNATURE_16(A, B) ((A) | (B << 8)) /** Returns a 32-bit signature built from 4 ASCII characters. This macro returns a 32-bit value built from the four ASCII characters specified by A, B, C, and D. @param A The first ASCII character. @param B The second ASCII character. @param C The third ASCII character. @param D The fourth ASCII character. @return A 32-bit value built from the two ASCII characters specified by A, B, C and D. **/ #define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) /** Returns a 64-bit signature built from 8 ASCII characters. This macro returns a 64-bit value built from the eight ASCII characters specified by A, B, C, D, E, F, G,and H. @param A The first ASCII character. @param B The second ASCII character. @param C The third ASCII character. @param D The fourth ASCII character. @param E The fifth ASCII character. @param F The sixth ASCII character. @param G The seventh ASCII character. @param H The eighth ASCII character. @return A 64-bit value built from the two ASCII characters specified by A, B, C, D, E, F, G and H. **/ #define SIGNATURE_64(A, B, C, D, E, F, G, H) \ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32)) #if defined (_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC) void * _ReturnAddress ( void ); #pragma intrinsic(_ReturnAddress) /** Get the return address of the calling function. Based on intrinsic function _ReturnAddress that provides the address of the instruction in the calling function that will be executed after control returns to the caller. @param L Return Level. @return The return address of the calling function or 0 if L != 0. **/ #define RETURN_ADDRESS(L) ((L == 0) ? _ReturnAddress() : (VOID *) 0) #elif defined (__GNUC__) || defined (__clang__) /** Get the return address of the calling function. Based on built-in Function __builtin_return_address that returns the return address of the current function, or of one of its callers. @param L Return Level. @return The return address of the calling function. **/ #define RETURN_ADDRESS(L) __builtin_return_address (L) #else /** Get the return address of the calling function. @param L Return Level. @return 0 as compilers don't support this feature. **/ #define RETURN_ADDRESS(L) ((VOID *) 0) #endif /** Return the number of elements in an array. @param Array An object of array type. Array is only used as an argument to the sizeof operator, therefore Array is never evaluated. The caller is responsible for ensuring that Array's type is not incomplete; that is, Array must have known constant size. @return The number of elements in Array. The result has type UINTN. **/ #define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0])) #endif /* __BASE_H__ */ /** @file GUIDs used for ACPI entries in the EFI system table These GUIDs point the ACPI tables as defined in the ACPI specifications. ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the ACPI 2.0 Table GUID and ACPI Table GUID. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUIDs defined in UEFI 2.0 spec. **/ #ifndef __ACPI_GUID_H__ #define __ACPI_GUID_H__ #define ACPI_TABLE_GUID \ { \ 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define EFI_ACPI_TABLE_GUID \ { \ 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ } #define ACPI_10_TABLE_GUID ACPI_TABLE_GUID // // ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID. // #define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID extern EFI_GUID gEfiAcpiTableGuid; extern EFI_GUID gEfiAcpi10TableGuid; extern EFI_GUID gEfiAcpi20TableGuid; #endif /** @file This GUID can be installed to the device handle to specify that the device is the console-in device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __CONSOLE_IN_DEVICE_H__ #define __CONSOLE_IN_DEVICE_H__ #define EFI_CONSOLE_IN_DEVICE_GUID \ { 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } extern EFI_GUID gEfiConsoleInDeviceGuid; #endif /** @file This GUID can be installed to the device handle to specify that the device is the console-out device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __CONSOLE_OUT_DEVICE_H__ #define __CONSOLE_OUT_DEVICE_H__ #define EFI_CONSOLE_OUT_DEVICE_GUID \ { 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } extern EFI_GUID gEfiConsoleOutDeviceGuid; #endif /** @file GUID and related data structures used with the Debug Image Info Table. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID defined in UEFI 2.0 spec. **/ #ifndef __DEBUG_IMAGE_INFO_GUID_H__ #define __DEBUG_IMAGE_INFO_GUID_H__ #include /// /// EFI_DEBUG_IMAGE_INFO_TABLE configuration table GUID declaration. /// #define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ { \ 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \ } #define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01 #define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02 #define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 typedef struct { UINT64 Signature; ///< A constant UINT64 that has the value EFI_SYSTEM_TABLE_SIGNATURE EFI_PHYSICAL_ADDRESS EfiSystemTableBase; ///< The physical address of the EFI system table. UINT32 Crc32; ///< A 32-bit CRC value that is used to verify the EFI_SYSTEM_TABLE_POINTER structure is valid. } EFI_SYSTEM_TABLE_POINTER; typedef struct { /// /// Indicates the type of image info structure. For PE32 EFI images, /// this is set to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL. /// UINT32 ImageInfoType; /// /// A pointer to an instance of the loaded image protocol for the associated image. /// EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolInstance; /// /// Indicates the image handle of the associated image. /// EFI_HANDLE ImageHandle; } EFI_DEBUG_IMAGE_INFO_NORMAL; typedef union { UINT32 *ImageInfoType; EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; } EFI_DEBUG_IMAGE_INFO; typedef struct { /// /// UpdateStatus is used by the system to indicate the state of the debug image info table. /// volatile UINT32 UpdateStatus; /// /// The number of EFI_DEBUG_IMAGE_INFO elements in the array pointed to by EfiDebugImageInfoTable. /// UINT32 TableSize; /// /// A pointer to the first element of an array of EFI_DEBUG_IMAGE_INFO structures. /// EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable; } EFI_DEBUG_IMAGE_INFO_TABLE_HEADER; extern EFI_GUID gEfiDebugImageInfoTableGuid; #endif /** @file GUID used to identify the DXE Services Table Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID introduced in PI Version 1.0. **/ #ifndef __DXE_SERVICES_GUID_H__ #define __DXE_SERVICES_GUID_H__ #define DXE_SERVICES_TABLE_GUID \ { \ 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \ } extern EFI_GUID gEfiDxeServicesTableGuid; #endif /** @file * * Copyright (c) 2013-2014, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #ifndef __FDT_H__ #define __FDT_H__ #define FDT_TABLE_GUID \ { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } } extern EFI_GUID gFdtTableGuid; #define FDT_VARIABLE_GUID \ { 0x25a4fd4a, 0x9703, 0x4ba9, { 0xa1, 0x90, 0xb7, 0xc8, 0x4e, 0xfb, 0x3e, 0x57 } } extern EFI_GUID gFdtVariableGuid; #endif /* __FDT_H__ */ /** @file GUID for EFI (NVRAM) Variables. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID defined in UEFI 2.1 **/ #ifndef __GLOBAL_VARIABLE_GUID_H__ #define __GLOBAL_VARIABLE_GUID_H__ #define EFI_GLOBAL_VARIABLE \ { \ 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \ } extern EFI_GUID gEfiGlobalVariableGuid; // // Follow UEFI 2.4 spec: // To prevent name collisions with possible future globally defined variables, // other internal firmware data variables that are not defined here must be // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or // any other GUID defined by the UEFI Specification. Implementations must // only permit the creation of variables with a UEFI Specification-defined // VendorGuid when these variables are documented in the UEFI Specification. // // Note: except the globally defined variables defined below, the spec also defines // L"Boot####" - A boot load option. // L"Driver####" - A driver load option. // L"SysPrep####" - A System Prep application load option. // L"Key####" - Describes hot key relationship with a Boot#### load option. // The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h // is included in the hex value. They can not be expressed as a #define like other globally // defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one. // /// /// The language codes that the firmware supports. This value is deprecated. /// Its attribute is BS+RT. /// #define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes" /// /// The language code that the system is configured for. This value is deprecated. /// Its attribute is NV+BS+RT. /// #define EFI_LANG_VARIABLE_NAME L"Lang" /// /// The firmware's boot managers timeout, in seconds, before initiating the default boot selection. /// Its attribute is NV+BS+RT. /// #define EFI_TIME_OUT_VARIABLE_NAME L"Timeout" /// /// The language codes that the firmware supports. /// Its attribute is BS+RT. /// #define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes" /// /// The language code that the system is configured for. /// Its attribute is NV+BS+RT. /// #define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang" /// /// The device path of the default input/output/error output console. /// Its attribute is NV+BS+RT. /// #define EFI_CON_IN_VARIABLE_NAME L"ConIn" #define EFI_CON_OUT_VARIABLE_NAME L"ConOut" #define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut" /// /// The device path of all possible input/output/error output devices. /// Its attribute is BS+RT. /// #define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev" #define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev" #define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev" /// /// The ordered boot option load list. /// Its attribute is NV+BS+RT. /// #define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder" /// /// The boot option for the next boot only. /// Its attribute is NV+BS+RT. /// #define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext" /// /// The boot option that was selected for the current boot. /// Its attribute is BS+RT. /// #define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent" /// /// The types of boot options supported by the boot manager. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport" /// /// The ordered driver load option list. /// Its attribute is NV+BS+RT. /// #define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder" /// /// The ordered System Prep Application load option list. /// Its attribute is NV+BS+RT. /// #define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder" /// /// Identifies the level of hardware error record persistence /// support implemented by the platform. This variable is /// only modified by firmware and is read-only to the OS. /// Its attribute is NV+BS+RT. /// #define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport" /// /// Whether the system is operating in setup mode (1) or not (0). /// All other values are reserved. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_SETUP_MODE_NAME L"SetupMode" /// /// The Key Exchange Key Signature Database. /// Its attribute is NV+BS+RT+AT. /// #define EFI_KEY_EXCHANGE_KEY_NAME L"KEK" /// /// The public Platform Key. /// Its attribute is NV+BS+RT+AT. /// #define EFI_PLATFORM_KEY_NAME L"PK" /// /// Array of GUIDs representing the type of signatures supported /// by the platform firmware. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport" /// /// Whether the platform firmware is operating in Secure boot mode (1) or not (0). /// All other values are reserved. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot" /// /// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault" /// /// The OEM's default public Platform Key. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault" /// /// The OEM's default secure boot signature store. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault" /// /// The OEM's default secure boot blacklist signature store. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault" /// /// The OEM's default secure boot timestamp signature store. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault" /// /// Allows the firmware to indicate supported features and actions to the OS. /// Its attribute is BS+RT. /// #define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported" /// /// Allows the OS to request the firmware to enable certain features and to take certain actions. /// Its attribute is NV+BS+RT. /// #define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications" /// /// Whether the system is configured to use only vendor provided /// keys or not. Should be treated as read-only. /// Its attribute is BS+RT. /// #define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys" #endif /** @file Guids used for the GPT (GUID Partition Table) GPT defines a new disk partitioning scheme and also describes usage of the legacy Master Boot Record (MBR) partitioning scheme. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUIDs defined in UEFI 2.1 spec. **/ #ifndef __GPT_GUID_H__ #define __GPT_GUID_H__ #define EFI_PART_TYPE_UNUSED_GUID \ { \ 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } \ } #define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \ { \ 0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } \ } #define EFI_PART_TYPE_LEGACY_MBR_GUID \ { \ 0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f } \ } extern EFI_GUID gEfiPartTypeUnusedGuid; extern EFI_GUID gEfiPartTypeSystemPartGuid; extern EFI_GUID gEfiPartTypeLegacyMbrGuid; #endif /** @file Guid used to identify HII FormMap configuration method. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID defined in UEFI 2.2 spec. **/ #ifndef __EFI_HII_FORMMAP_GUID_H__ #define __EFI_HII_FORMMAP_GUID_H__ #define EFI_HII_STANDARD_FORM_GUID \ { 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } } extern EFI_GUID gEfiHiiStandardFormGuid; #endif /** @file GUID indicates that the form set contains forms designed to be used for platform configuration and this form set will be displayed. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID defined in UEFI 2.1. **/ #ifndef __HII_PLATFORM_SETUP_FORMSET_GUID_H__ #define __HII_PLATFORM_SETUP_FORMSET_GUID_H__ #define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \ { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } } #define EFI_HII_DRIVER_HEALTH_FORMSET_GUID \ { 0xf22fc20c, 0x8cf4, 0x45eb, { 0x8e, 0x6, 0xad, 0x4e, 0x50, 0xb9, 0x5d, 0xd3 } } #define EFI_HII_USER_CREDENTIAL_FORMSET_GUID \ { 0x337f4407, 0x5aee, 0x4b83, { 0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd } } #define EFI_HII_REST_STYLE_FORMSET_GUID \ { 0x790217bd, 0xbecf, 0x485b, { 0x91, 0x70, 0x5f, 0xf7, 0x11, 0x31, 0x8b, 0x27 } } extern EFI_GUID gEfiHiiPlatformSetupFormsetGuid; extern EFI_GUID gEfiHiiDriverHealthFormsetGuid; extern EFI_GUID gEfiHiiUserCredentialFormsetGuid; extern EFI_GUID gEfiHiiRestStyleFormsetGuid; #endif /** @file GUIDs used for HOB List entries These GUIDs point the HOB List passed from PEI to DXE. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID introduced in PI Version 1.0. **/ #ifndef __HOB_LIST_GUID_H__ #define __HOB_LIST_GUID_H__ #define HOB_LIST_GUID \ { \ 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } extern EFI_GUID gEfiHobListGuid; #endif /** @file This file defines: * Memory Type Information GUID for HOB and Variable. * Memory Type Information Variable Name. * Memory Type Information GUID HOB data structure. The memory type information HOB and variable can be used to store the information for each memory type in Variable or HOB. Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __MEMORY_TYPE_INFORMATION_GUID_H__ #define __MEMORY_TYPE_INFORMATION_GUID_H__ #define EFI_MEMORY_TYPE_INFORMATION_GUID \ { 0x4c19049f,0x4137,0x4dd3, { 0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa } } #define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME "MemoryTypeInformation" extern EFI_GUID gEfiMemoryTypeInformationGuid; typedef struct { UINT32 Type; ///< EFI memory type defined in UEFI specification. UINT32 NumberOfPages; ///< The pages of this type memory. } EFI_MEMORY_TYPE_INFORMATION; #endif /** @file GUIDs used for MPS entries in the UEFI 2.0 system table ACPI is the primary means of exporting MPS information to the OS. MPS only was included to support Itanium-based platform power on. So don't use it if you don't have too. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUIDs defined in UEFI 2.0 spec. **/ #ifndef __MPS_GUID_H__ #define __MPS_GUID_H__ #define EFI_MPS_TABLE_GUID \ { \ 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } // // GUID name defined in spec. // #define MPS_TABLE_GUID EFI_MPS_TABLE_GUID extern EFI_GUID gEfiMpsTableGuid; #endif /** @file GUID is for MTC variable. Copyright (c) 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __MTC_VENDOR_GUID_H__ #define __MTC_VENDOR_GUID_H__ // // Vendor GUID of the variable for the high part of monotonic counter (UINT32). // #define MTC_VENDOR_GUID \ { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } // // Name of the variable for the high part of monotonic counter // #define MTC_VARIABLE_NAME "MTC" extern EFI_GUID gMtcVendorGuid; #endif /** @file Terminal Device Path Vendor Guid. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUIDs defined in UEFI 2.0 spec. **/ #ifndef __PC_ANSI_H__ #define __PC_ANSI_H__ #define EFI_PC_ANSI_GUID \ { \ 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define EFI_VT_100_GUID \ { \ 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define EFI_VT_100_PLUS_GUID \ { \ 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } \ } #define EFI_VT_UTF8_GUID \ { \ 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \ } #define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL \ { \ 0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \ } #define EFI_SAS_DEVICE_PATH_GUID \ { \ 0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \ } extern EFI_GUID gEfiPcAnsiGuid; extern EFI_GUID gEfiVT100Guid; extern EFI_GUID gEfiVT100PlusGuid; extern EFI_GUID gEfiVTUTF8Guid; extern EFI_GUID gEfiUartDevicePathGuid; extern EFI_GUID gEfiSasDevicePathGuid; #endif /** @file GUIDs used to locate the SMBIOS tables in the UEFI 2.5 system table. These GUIDs in the system table are the only legal ways to search for and locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS tables. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUIDs defined in UEFI 2.5 spec. **/ #ifndef __SMBIOS_GUID_H__ #define __SMBIOS_GUID_H__ #define SMBIOS_TABLE_GUID \ { \ 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define SMBIOS3_TABLE_GUID \ { \ 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \ } extern EFI_GUID gEfiSmbiosTableGuid; extern EFI_GUID gEfiSmbios3TableGuid; #endif /** @file This GUID is installed to the device handler to specify that the device is a StdErr device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __STANDARD_ERROR_DEVICE_H__ #define __STANDARD_ERROR_DEVICE_H__ #define EFI_STANDARD_ERROR_DEVICE_GUID \ { 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } extern EFI_GUID gEfiStandardErrorDeviceGuid; #endif /** @file GUID for UEFI WIN_CERTIFICATE structure. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: GUID defined in UEFI 2.0 spec. **/ #ifndef __EFI_WIN_CERTIFICATE_H__ #define __EFI_WIN_CERTIFICATE_H__ // // _WIN_CERTIFICATE.wCertificateType // #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 #define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0 #define WIN_CERT_TYPE_EFI_GUID 0x0EF1 /// /// The WIN_CERTIFICATE structure is part of the PE/COFF specification. /// typedef struct { /// /// The length of the entire certificate, /// including the length of the header, in bytes. /// UINT32 dwLength; /// /// The revision level of the WIN_CERTIFICATE /// structure. The current revision level is 0x0200. /// UINT16 wRevision; /// /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI /// certificate types. The UEFI specification reserves the range of /// certificate type values from 0x0EF0 to 0x0EFF. /// UINT16 wCertificateType; /// /// The following is the actual certificate. The format of /// the certificate depends on wCertificateType. /// /// UINT8 bCertificate[ANYSIZE_ARRAY]; /// } WIN_CERTIFICATE; /// /// WIN_CERTIFICATE_UEFI_GUID.CertType /// #define EFI_CERT_TYPE_RSA2048_SHA256_GUID \ {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } } /// /// WIN_CERTIFICATE_UEFI_GUID.CertData /// typedef struct { EFI_GUID HashType; UINT8 PublicKey[256]; UINT8 Signature[256]; } EFI_CERT_BLOCK_RSA_2048_SHA256; /// /// Certificate which encapsulates a GUID-specific digital signature /// typedef struct { /// /// This is the standard WIN_CERTIFICATE header, where /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID. /// WIN_CERTIFICATE Hdr; /// /// This is the unique id which determines the /// format of the CertData. . /// EFI_GUID CertType; /// /// The following is the certificate data. The format of /// the data is determined by the CertType. /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID, /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure. /// UINT8 CertData[1]; } WIN_CERTIFICATE_UEFI_GUID; /// /// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature. /// /// The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from /// WIN_CERTIFICATE and encapsulate the information needed to /// implement the RSASSA-PKCS1-v1_5 digital signature algorithm as /// specified in RFC2437. /// typedef struct { /// /// This is the standard WIN_CERTIFICATE header, where /// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15. /// WIN_CERTIFICATE Hdr; /// /// This is the hashing algorithm which was performed on the /// UEFI executable when creating the digital signature. /// EFI_GUID HashAlgorithm; /// /// The following is the actual digital signature. The /// size of the signature is the same size as the key /// (1024-bit key is 128 bytes) and can be determined by /// subtracting the length of the other parts of this header /// from the total length of the certificate as found in /// Hdr.dwLength. /// /// UINT8 Signature[]; /// } WIN_CERTIFICATE_EFI_PKCS1_15; extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid; #endif /** @file GUID has all zero values. Copyright (c) 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __ZERO_GUID_H__ #define __ZERO_GUID_H__ #define ZERO_GUID \ { \ 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} \ } extern EFI_GUID gZeroGuid; #endif /** @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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_H_ #define _ACPI_H_ #include #endif /** @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 /// /// 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 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 // // 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 ACPI 3.0 definitions from the ACPI Specification Revision 3.0b October 10, 2006 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_3_0_H_ #define _ACPI_3_0_H_ #include // // Define for Descriptor // #define ACPI_LARGE_EXTENDED_ADDRESS_SPACE_DESCRIPTOR_NAME 0x0B #define ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR 0x8B // // 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 ACPI 4.0 definitions from the ACPI Specification Revision 4.0a April 5, 2010 Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_4_0_H_ #define _ACPI_4_0_H_ #include // // 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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_5_0_H_ #define _ACPI_5_0_H_ #include // // 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 #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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_5_1_H_ #define _ACPI_5_1_H_ #include // // 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_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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_0_H_ #define _ACPI_6_0_H_ #include // // 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_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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_1_H_ #define _ACPI_6_1_H_ #include // // 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_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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_2_H_ #define _ACPI_6_2_H_ #include // // 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 #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 // // 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; /// /// 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_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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ACPI_6_3_H_ #define _ACPI_6_3_H_ #include // // 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 // // 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; /// /// 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_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 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.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef ACPI_6_4_H_ #define ACPI_6_4_H_ #include // // 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 // // 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; /// /// 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_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 // // 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') /// /// "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') /// /// "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 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 This file contains just some basic definitions that are needed by drivers that dealing with ATA/ATAPI interface. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _ATAPI_H_ #define _ATAPI_H_ #pragma pack(1) /// /// ATA5_IDENTIFY_DATA is defined in ATA-5. /// (This structure is provided mainly for backward-compatibility support. /// Old drivers may reference fields that are marked "obsolete" in /// ATA_IDENTIFY_DATA, which currently conforms to ATA-8.) /// typedef struct { UINT16 config; ///< General Configuration. UINT16 cylinders; ///< Number of Cylinders. UINT16 reserved_2; UINT16 heads; ///< Number of logical heads. UINT16 vendor_data1; UINT16 vendor_data2; UINT16 sectors_per_track; UINT16 vendor_specific_7_9[3]; CHAR8 SerialNo[20]; ///< ASCII UINT16 vendor_specific_20_21[2]; UINT16 ecc_bytes_available; CHAR8 FirmwareVer[8]; ///< ASCII CHAR8 ModelName[40]; ///< ASCII UINT16 multi_sector_cmd_max_sct_cnt; UINT16 reserved_48; UINT16 capabilities; UINT16 reserved_50; UINT16 pio_cycle_timing; UINT16 reserved_52; UINT16 field_validity; UINT16 current_cylinders; UINT16 current_heads; UINT16 current_sectors; UINT16 CurrentCapacityLsb; UINT16 CurrentCapacityMsb; UINT16 reserved_59; UINT16 user_addressable_sectors_lo; UINT16 user_addressable_sectors_hi; UINT16 reserved_62; UINT16 multi_word_dma_mode; UINT16 advanced_pio_modes; UINT16 min_multi_word_dma_cycle_time; UINT16 rec_multi_word_dma_cycle_time; UINT16 min_pio_cycle_time_without_flow_control; UINT16 min_pio_cycle_time_with_flow_control; UINT16 reserved_69_79[11]; UINT16 major_version_no; UINT16 minor_version_no; UINT16 command_set_supported_82; ///< word 82 UINT16 command_set_supported_83; ///< word 83 UINT16 command_set_feature_extn; ///< word 84 UINT16 command_set_feature_enb_85; ///< word 85 UINT16 command_set_feature_enb_86; ///< word 86 UINT16 command_set_feature_default; ///< word 87 UINT16 ultra_dma_mode; ///< word 88 UINT16 reserved_89_127[39]; UINT16 security_status; UINT16 vendor_data_129_159[31]; UINT16 reserved_160_255[96]; } ATA5_IDENTIFY_DATA; /// /// ATA_IDENTIFY_DATA strictly complies with ATA/ATAPI-8 Spec /// to define the data returned by an ATA device upon successful /// completion of the ATA IDENTIFY_DEVICE command. /// typedef struct { UINT16 config; ///< General Configuration. UINT16 obsolete_1; UINT16 specific_config; ///< Specific Configuration. UINT16 obsolete_3; UINT16 retired_4_5[2]; UINT16 obsolete_6; UINT16 cfa_reserved_7_8[2]; UINT16 retired_9; CHAR8 SerialNo[20]; ///< word 10~19 UINT16 retired_20_21[2]; UINT16 obsolete_22; CHAR8 FirmwareVer[8]; ///< word 23~26 CHAR8 ModelName[40]; ///< word 27~46 UINT16 multi_sector_cmd_max_sct_cnt; UINT16 trusted_computing_support; UINT16 capabilities_49; UINT16 capabilities_50; UINT16 obsolete_51_52[2]; UINT16 field_validity; UINT16 obsolete_54_58[5]; UINT16 multi_sector_setting; UINT16 user_addressable_sectors_lo; UINT16 user_addressable_sectors_hi; UINT16 obsolete_62; UINT16 multi_word_dma_mode; UINT16 advanced_pio_modes; UINT16 min_multi_word_dma_cycle_time; UINT16 rec_multi_word_dma_cycle_time; UINT16 min_pio_cycle_time_without_flow_control; UINT16 min_pio_cycle_time_with_flow_control; UINT16 additional_supported; ///< word 69 UINT16 reserved_70; UINT16 reserved_71_74[4]; ///< Reserved for IDENTIFY PACKET DEVICE cmd. UINT16 queue_depth; UINT16 serial_ata_capabilities; UINT16 reserved_77; ///< Reserved for Serial ATA UINT16 serial_ata_features_supported; UINT16 serial_ata_features_enabled; UINT16 major_version_no; UINT16 minor_version_no; UINT16 command_set_supported_82; ///< word 82 UINT16 command_set_supported_83; ///< word 83 UINT16 command_set_feature_extn; ///< word 84 UINT16 command_set_feature_enb_85; ///< word 85 UINT16 command_set_feature_enb_86; ///< word 86 UINT16 command_set_feature_default; ///< word 87 UINT16 ultra_dma_mode; ///< word 88 UINT16 time_for_security_erase_unit; UINT16 time_for_enhanced_security_erase_unit; UINT16 advanced_power_management_level; UINT16 master_password_identifier; UINT16 hardware_configuration_test_result; UINT16 obsolete_94; UINT16 stream_minimum_request_size; UINT16 streaming_transfer_time_for_dma; UINT16 streaming_access_latency_for_dma_and_pio; UINT16 streaming_performance_granularity[2]; ///< word 98~99 UINT16 maximum_lba_for_48bit_addressing[4]; ///< word 100~103 UINT16 streaming_transfer_time_for_pio; UINT16 max_no_of_512byte_blocks_per_data_set_cmd; UINT16 phy_logic_sector_support; ///< word 106 UINT16 interseek_delay_for_iso7779; UINT16 world_wide_name[4]; ///< word 108~111 UINT16 reserved_for_128bit_wwn_112_115[4]; UINT16 reserved_for_technical_report; UINT16 logic_sector_size_lo; ///< word 117 UINT16 logic_sector_size_hi; ///< word 118 UINT16 features_and_command_sets_supported_ext; ///< word 119 UINT16 features_and_command_sets_enabled_ext; ///< word 120 UINT16 reserved_121_126[6]; UINT16 obsolete_127; UINT16 security_status; ///< word 128 UINT16 vendor_specific_129_159[31]; UINT16 cfa_power_mode; ///< word 160 UINT16 reserved_for_compactflash_161_167[7]; UINT16 device_nominal_form_factor; UINT16 is_data_set_cmd_supported; CHAR8 additional_product_identifier[8]; UINT16 reserved_174_175[2]; CHAR8 media_serial_number[60]; ///< word 176~205 UINT16 sct_command_transport; ///< word 206 UINT16 reserved_207_208[2]; UINT16 alignment_logic_in_phy_blocks; ///< word 209 UINT16 write_read_verify_sector_count_mode3[2]; ///< word 210~211 UINT16 verify_sector_count_mode2[2]; UINT16 nv_cache_capabilities; UINT16 nv_cache_size_in_logical_block_lsw; ///< word 215 UINT16 nv_cache_size_in_logical_block_msw; ///< word 216 UINT16 nominal_media_rotation_rate; UINT16 reserved_218; UINT16 nv_cache_options; ///< word 219 UINT16 write_read_verify_mode; ///< word 220 UINT16 reserved_221; UINT16 transport_major_revision_number; UINT16 transport_minor_revision_number; UINT16 reserved_224_229[6]; UINT64 extended_no_of_addressable_sectors; UINT16 min_number_per_download_microcode_mode3; ///< word 234 UINT16 max_number_per_download_microcode_mode3; ///< word 235 UINT16 reserved_236_254[19]; UINT16 integrity_word; } ATA_IDENTIFY_DATA; /// /// ATAPI_IDENTIFY_DATA strictly complies with ATA/ATAPI-8 Spec /// to define the data returned by an ATAPI device upon successful /// completion of the ATA IDENTIFY_PACKET_DEVICE command. /// typedef struct { UINT16 config; ///< General Configuration. UINT16 reserved_1; UINT16 specific_config; ///< Specific Configuration. UINT16 reserved_3_9[7]; CHAR8 SerialNo[20]; ///< word 10~19 UINT16 reserved_20_22[3]; CHAR8 FirmwareVer[8]; ///< word 23~26 CHAR8 ModelName[40]; ///< word 27~46 UINT16 reserved_47_48[2]; UINT16 capabilities_49; UINT16 capabilities_50; UINT16 obsolete_51; UINT16 reserved_52; UINT16 field_validity; ///< word 53 UINT16 reserved_54_61[8]; UINT16 dma_dir; UINT16 multi_word_dma_mode; ///< word 63 UINT16 advanced_pio_modes; ///< word 64 UINT16 min_multi_word_dma_cycle_time; UINT16 rec_multi_word_dma_cycle_time; UINT16 min_pio_cycle_time_without_flow_control; UINT16 min_pio_cycle_time_with_flow_control; UINT16 reserved_69_70[2]; UINT16 obsolete_71_72[2]; UINT16 reserved_73_74[2]; UINT16 obsolete_75; UINT16 serial_ata_capabilities; UINT16 reserved_77; ///< Reserved for Serial ATA UINT16 serial_ata_features_supported; UINT16 serial_ata_features_enabled; UINT16 major_version_no; ///< word 80 UINT16 minor_version_no; ///< word 81 UINT16 cmd_set_support_82; UINT16 cmd_set_support_83; UINT16 cmd_feature_support; UINT16 cmd_feature_enable_85; UINT16 cmd_feature_enable_86; UINT16 cmd_feature_default; UINT16 ultra_dma_select; UINT16 time_required_for_sec_erase; ///< word 89 UINT16 time_required_for_enhanced_sec_erase; ///< word 90 UINT16 advanced_power_management_level; UINT16 master_pwd_revison_code; UINT16 hardware_reset_result; ///< word 93 UINT16 obsolete_94; UINT16 reserved_95_107[13]; UINT16 world_wide_name[4]; ///< word 108~111 UINT16 reserved_for_128bit_wwn_112_115[4]; UINT16 reserved_116_118[3]; UINT16 command_and_feature_sets_supported; ///< word 119 UINT16 command_and_feature_sets_supported_enabled; UINT16 reserved_121_124[4]; UINT16 atapi_byte_count_0_behavior; ///< word 125 UINT16 obsolete_126_127[2]; UINT16 security_status; UINT16 reserved_129_159[31]; UINT16 cfa_reserved_160_175[16]; UINT16 reserved_176_221[46]; UINT16 transport_major_version; UINT16 transport_minor_version; UINT16 reserved_224_254[31]; UINT16 integrity_word; } ATAPI_IDENTIFY_DATA; /// /// Standard Quiry Data format, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 peripheral_type; UINT8 RMB; UINT8 version; UINT8 response_data_format; UINT8 addnl_length; ///< n - 4, Numbers of bytes following this one. UINT8 reserved_5; UINT8 reserved_6; UINT8 reserved_7; UINT8 vendor_info[8]; UINT8 product_id[16]; UINT8 product_revision_level[4]; UINT8 vendor_specific_36_55[55 - 36 + 1]; UINT8 reserved_56_95[95 - 56 + 1]; /// /// Vendor-specific parameters fields. The sizeof (ATAPI_INQUIRY_DATA) is 254 /// since allocation_length is one byte in ATAPI_INQUIRY_CMD. /// UINT8 vendor_specific_96_253[253 - 96 + 1]; } ATAPI_INQUIRY_DATA; /// /// Request Sense Standard Data, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 error_code : 7; UINT8 valid : 1; UINT8 reserved_1; UINT8 sense_key : 4; UINT8 reserved_2 : 1; UINT8 Vendor_specifc_1 : 3; UINT8 vendor_specific_3; UINT8 vendor_specific_4; UINT8 vendor_specific_5; UINT8 vendor_specific_6; UINT8 addnl_sense_length; ///< n - 7 UINT8 vendor_specific_8; UINT8 vendor_specific_9; UINT8 vendor_specific_10; UINT8 vendor_specific_11; UINT8 addnl_sense_code; ///< mandatory UINT8 addnl_sense_code_qualifier; ///< mandatory UINT8 field_replaceable_unit_code; ///< optional UINT8 sense_key_specific_15 : 7; UINT8 SKSV : 1; UINT8 sense_key_specific_16; UINT8 sense_key_specific_17; } ATAPI_REQUEST_SENSE_DATA; /// /// READ CAPACITY Data, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 LastLba3; UINT8 LastLba2; UINT8 LastLba1; UINT8 LastLba0; UINT8 BlockSize3; UINT8 BlockSize2; UINT8 BlockSize1; UINT8 BlockSize0; } ATAPI_READ_CAPACITY_DATA; /// /// Capacity List Header + Current/Maximum Capacity Descriptor, /// defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 reserved_0; UINT8 reserved_1; UINT8 reserved_2; UINT8 Capacity_Length; UINT8 LastLba3; UINT8 LastLba2; UINT8 LastLba1; UINT8 LastLba0; UINT8 DesCode : 2; UINT8 reserved_9 : 6; UINT8 BlockSize2; UINT8 BlockSize1; UINT8 BlockSize0; } ATAPI_READ_FORMAT_CAPACITY_DATA; /// /// Test Unit Ready Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1; UINT8 reserved_2; UINT8 reserved_3; UINT8 reserved_4; UINT8 reserved_5; UINT8 reserved_6; UINT8 reserved_7; UINT8 reserved_8; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_TEST_UNIT_READY_CMD; /// /// INQUIRY Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1 : 5; UINT8 lun : 3; UINT8 page_code; ///< defined in SFF8090i, V6 UINT8 reserved_3; UINT8 allocation_length; UINT8 reserved_5; UINT8 reserved_6; UINT8 reserved_7; UINT8 reserved_8; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_INQUIRY_CMD; /// /// REQUEST SENSE Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1 : 5; UINT8 lun : 3; UINT8 reserved_2; UINT8 reserved_3; UINT8 allocation_length; UINT8 reserved_5; UINT8 reserved_6; UINT8 reserved_7; UINT8 reserved_8; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_REQUEST_SENSE_CMD; /// /// READ (10) Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1 : 5; UINT8 lun : 3; UINT8 Lba0; UINT8 Lba1; UINT8 Lba2; UINT8 Lba3; UINT8 reserved_6; UINT8 TranLen0; UINT8 TranLen1; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_READ10_CMD; /// /// READ Format Capacity Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1 : 5; UINT8 lun : 3; UINT8 reserved_2; UINT8 reserved_3; UINT8 reserved_4; UINT8 reserved_5; UINT8 reserved_6; UINT8 allocation_length_hi; UINT8 allocation_length_lo; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_READ_FORMAT_CAP_CMD; /// /// MODE SENSE Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). /// typedef struct { UINT8 opcode; UINT8 reserved_1 : 5; UINT8 lun : 3; UINT8 page_code : 6; UINT8 page_control : 2; UINT8 reserved_3; UINT8 reserved_4; UINT8 reserved_5; UINT8 reserved_6; UINT8 parameter_list_length_hi; UINT8 parameter_list_length_lo; UINT8 reserved_9; UINT8 reserved_10; UINT8 reserved_11; } ATAPI_MODE_SENSE_CMD; /// /// ATAPI_PACKET_COMMAND is not defined in the ATA specification. /// We add it here for the convenience of ATA/ATAPI module writers. /// typedef union { UINT16 Data16[6]; ATAPI_TEST_UNIT_READY_CMD TestUnitReady; ATAPI_READ10_CMD Read10; ATAPI_REQUEST_SENSE_CMD RequestSence; ATAPI_INQUIRY_CMD Inquiry; ATAPI_MODE_SENSE_CMD ModeSense; ATAPI_READ_FORMAT_CAP_CMD ReadFormatCapacity; } ATAPI_PACKET_COMMAND; #pragma pack() #define ATAPI_MAX_DMA_EXT_CMD_SECTORS 0x10000 #define ATAPI_MAX_DMA_CMD_SECTORS 0x100 // ATA/ATAPI Signature equates #define ATA_SIGNATURE 0x0101 ///< defined in ACS-3 #define ATAPI_SIGNATURE 0xeb14 ///< defined in ACS-3 #define ATAPI_SIGNATURE_32 0xeb140101 ///< defined in ACS-3 // Spin Up Configuration definitions #define ATA_SPINUP_CFG_REQUIRED_IDD_INCOMPLETE 0x37c8 ///< defined in ACS-3 #define ATA_SPINUP_CFG_REQUIRED_IDD_COMPLETE 0x738c ///< defined in ACS-3 #define ATA_SPINUP_CFG_NOT_REQUIRED_IDD_INCOMPLETE 0x8c73 ///< defined in ACS-3 #define ATA_SPINUP_CFG_NOT_REQUIRED_IDD_COMPLETE 0xc837 ///< defined in ACS-3 // // ATA Packet Command Code // #define ATA_CMD_FORMAT_UNIT 0x04 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_SOFT_RESET 0x08 ///< defined from ATA-3 #define ATA_CMD_PACKET 0xA0 ///< defined from ATA-3 #define ATA_CMD_IDENTIFY_DEVICE 0xA1 ///< defined from ATA-3 #define ATA_CMD_SERVICE 0xA2 ///< defined from ATA-3 #define ATA_CMD_TEST_UNIT_READY 0x00 ///< defined from ATA-1 #define ATA_CMD_REQUEST_SENSE 0x03 ///< defined from ATA-4 #define ATA_CMD_INQUIRY 0x12 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_READ_FORMAT_CAPACITY 0x23 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_READ_CAPACITY 0x25 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_READ_10 0x28 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_WRITE_10 0x2A ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_ATAPI_SEEK 0x2B ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_WRITE_AND_VERIFY 0x2E ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_VERIFY 0x2F ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_READ_12 0xA8 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_WRITE_12 0xAA ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_START_STOP_UNIT 0x1B ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_PREVENT_ALLOW_MEDIA_REMOVAL 0x1E ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_MODE_SELECT 0x55 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_MODE_SENSE 0x5A ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_PAGE_CODE_READ_WRITE_ERROR 0x01 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_PAGE_CODE_CACHING_PAGE 0x08 ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_PAGE_CODE_REMOVABLE_BLOCK_CAPABILITIES 0x1B ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_PAGE_CODE_TIMER_PROTECT_PAGE 0x1C ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_PAGE_CODE_RETURN_ALL_PAGES 0x3F ///< defined in ATAPI Removable Rewritable Media Devices #define ATA_CMD_GET_CONFIGURATION 0x46 ///< defined in ATAPI Multimedia Devices #define ATA_GCCD_RT_FIELD_VALUE_ALL 0x00 ///< defined in ATAPI Multimedia Devices #define ATA_GCCD_RT_FIELD_VALUE_CURRENT 0x01 ///< defined in ATAPI Multimedia Devices #define ATA_GCCD_RT_FIELD_VALUE_SINGLE 0x02 ///< defined in ATAPI Multimedia Devices #define ATA_GCCD_RT_FIELD_VALUE_RESERVED 0x03 ///< defined in ATAPI Multimedia Devices #define ATA_FEATURE_LIST_PROFILE_LIST 0x0000 ///< defined in ATAPI Multimedia Devices #define ATA_FEATURE_LIST_CORE 0x0001 ///< defined in ATAPI Multimedia Devices #define ATA_FEATURE_LIST_MORPHING 0x0002 ///< defined in ATAPI Multimedia Devices #define ATA_FEATURE_LIST_REMOVEABLE_MEDIUM 0x0003 ///< defined in ATAPI Multimedia Devices #define ATA_FEATURE_LIST_WRITE_PROTECT 0x0004 ///< defined in ATAPI Multimedia Devices /// /// Start/Stop and Eject Operations /// ///@{ #define ATA_CMD_SUBOP_STOP_DISC 0x00 ///< Stop the Disc #define ATA_CMD_SUBOP_START_DISC 0x01 ///< Start the Disc and acquire the format type #define ATA_CMD_SUBOP_EJECT_DISC 0x02 ///< Eject the Disc if possible #define ATA_CMD_SUBOP_CLOSE_TRAY 0x03 ///< Load the Disc (Close Tray) ///@} // // ATA Commands Code // // // Class 1: PIO Data-In Commands // #define ATA_CMD_IDENTIFY_DRIVE 0xec ///< defined from ATA-3 #define ATA_CMD_READ_BUFFER 0xe4 ///< defined from ATA-1 #define ATA_CMD_READ_SECTORS 0x20 ///< defined from ATA-1 #define ATA_CMD_READ_SECTORS_WITH_RETRY 0x21 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_READ_LONG 0x22 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_READ_LONG_WITH_RETRY 0x23 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_READ_SECTORS_EXT 0x24 ///< defined from ATA-6 #define ATA_CMD_READ_MULTIPLE 0xc4 ///< defined in ACS-3 #define ATA_CMD_READ_MULTIPLE_EXT 0x29 ///< defined in ACS-3 #define ATA_CMD_READ_LOG_EXT 0x2f ///< defined in ACS-3 // // Class 2: PIO Data-Out Commands // #define ATA_CMD_FORMAT_TRACK 0x50 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_WRITE_BUFFER 0xe8 ///< defined from ATA-1 #define ATA_CMD_WRITE_SECTORS 0x30 ///< defined from ATA-1 #define ATA_CMD_WRITE_SECTORS_WITH_RETRY 0x31 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_WRITE_LONG 0x32 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_WRITE_LONG_WITH_RETRY 0x33 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_WRITE_VERIFY 0x3c ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_WRITE_SECTORS_EXT 0x34 ///< defined from ATA-6 #define ATA_CMD_WRITE_MULTIPLE 0xc5 ///< defined in ACS-3 #define ATA_CMD_WRITE_MULTIPLE_EXT 0x39 ///< defined in ACS-3 // // Class 3 No Data Command // #define ATA_CMD_ACK_MEDIA_CHANGE 0xdb ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_BOOT_POST_BOOT 0xdc ///< defined from ATA-1, obsoleted from ATA-3 #define ATA_CMD_BOOT_PRE_BOOT 0xdd ///< defined from ATA-1, obsoleted from ATA-3 #define ATA_CMD_CHECK_POWER_MODE 0x98 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_CHECK_POWER_MODE_ALIAS 0xe5 ///< defined from ATA-1 #define ATA_CMD_DOOR_LOCK 0xde ///< defined from ATA-1 #define ATA_CMD_DOOR_UNLOCK 0xdf ///< defined from ATA-1 #define ATA_CMD_EXEC_DRIVE_DIAG 0x90 ///< defined from ATA-1 #define ATA_CMD_IDLE_ALIAS 0x97 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_IDLE 0xe3 ///< defined from ATA-1 #define ATA_CMD_IDLE_IMMEDIATE 0x95 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_IDLE_IMMEDIATE_ALIAS 0xe1 ///< defined from ATA-1 #define ATA_CMD_INIT_DRIVE_PARAM 0x91 ///< defined from ATA-1, obsoleted from ATA-6 #define ATA_CMD_RECALIBRATE 0x10 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_READ_DRIVE_STATE 0xe9 ///< defined from ATA-1, obsoleted from ATA-3 #define ATA_CMD_SET_MULTIPLE_MODE 0xC6 ///< defined from ATA-2 #define ATA_CMD_READ_VERIFY 0x40 ///< defined from ATA-1 #define ATA_CMD_READ_VERIFY_WITH_RETRY 0x41 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_SEEK 0x70 ///< defined from ATA-1 #define ATA_CMD_SET_FEATURES 0xef ///< defined from ATA-1 #define ATA_CMD_STANDBY 0x96 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_STANDBY_ALIAS 0xe2 ///< defined from ATA-1 #define ATA_CMD_STANDBY_IMMEDIATE 0x94 ///< defined from ATA-1, obsoleted from ATA-4 #define ATA_CMD_STANDBY_IMMEDIATE_ALIAS 0xe0 ///< defined from ATA-1 #define ATA_CMD_SLEEP 0xe6 ///< defined in ACS-3 #define ATA_CMD_READ_NATIVE_MAX_ADDRESS 0xf8 ///< defined in ATA-6 #define ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT 0x27 ///< defined in ATA-6 // // Set Features Sub Command // #define ATA_SUB_CMD_ENABLE_VOLATILE_WRITE_CACHE 0x02 ///< defined in ACS-3 #define ATA_SUB_CMD_SET_TRANSFER_MODE 0x03 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_APM 0x05 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_PUIS 0x06 ///< defined in ACS-3 #define ATA_SUB_CMD_PUIS_SET_DEVICE_SPINUP 0x07 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_WRITE_READ_VERIFY 0x0b ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_SATA_FEATURE 0x10 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_MEDIA_STATUS_NOTIFICATION 0x31 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_FREE_FALL_CONTROL 0x41 ///< defined in ACS-3 #define ATA_SUB_CMD_ACOUSTIC_MANAGEMENT_ENABLE 0x42 ///< defined in ACS-3 #define ATA_SUB_CMD_SET_MAX_HOST_INTERFACE_SECTOR_TIMES 0x43 ///< defined in ACS-3 #define ATA_SUB_CMD_EXTENDED_POWER_CONDITIONS 0x4a ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_READ_LOOK_AHEAD 0x55 ///< defined in ACS-3 #define ATA_SUB_CMD_EN_DIS_DSN_FEATURE 0x63 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_REVERT_TO_POWER_ON_DEFAULTS 0x66 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_VOLATILE_WRITE_CACHE 0x82 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_APM 0x85 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_PUIS 0x86 ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_WRITE_READ_VERIFY 0x8b ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_SATA_FEATURE 0x90 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_MEDIA_STATUS_NOTIFICATION 0x95 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_READ_LOOK_AHEAD 0xaa ///< defined in ACS-3 #define ATA_SUB_CMD_DISABLE_FREE_FALL_CONTROL 0xc1 ///< defined in ACS-3 #define ATA_SUB_CMD_ACOUSTIC_MANAGEMENT_DISABLE 0xc2 ///< defined in ACS-3 #define ATA_SUB_CMD_EN_DIS_SENSE_DATA_REPORTING 0xc3 ///< defined in ACS-3 #define ATA_SUB_CMD_ENABLE_REVERT_TO_POWER_ON_DEFAULTS 0xcc ///< defined in ACS-3 // // S.M.A.R.T // #define ATA_CMD_SMART 0xb0 ///< defined from ATA-3 #define ATA_CONSTANT_C2 0xc2 ///< reserved #define ATA_CONSTANT_4F 0x4f ///< reserved #define ATA_SMART_READ_DATA 0xd0 ///< defined in ACS-3 #define ATA_SMART_AUTOSAVE 0xd2 ///< defined in ACS-3 #define ATA_AUTOSAVE_DISABLE_ATTR 0x00 #define ATA_AUTOSAVE_ENABLE_ATTR 0xf1 #define ATA_SMART_EXECUTE_OFFLINE_IMMEDIATE 0xd4 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_OFFLINE_ROUTINE 0x00 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_OFFLINE_SHORT_SELFTEST 0x01 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_OFFLINE_EXTENDED_SELFTEST 0x02 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_OFFLINE_CONVEYANCE_SELFTEST 0x03 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_OFFLINE_SELECTIVE_SELFTEST 0x04 ///< defined in ACS-3 #define ATA_SMART_ABORT_SELF_TEST_SUBROUTINE 0x7f ///< defined in ACS-3 #define ATA_EXECUTE_SMART_CAPTIVE_SHORT_SELFTEST 0x81 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_CAPTIVE_EXTENDED_SELFTEST 0x82 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_CAPTIVE_CONVEYANCE_SELFTEST 0x83 ///< defined in ACS-3 #define ATA_EXECUTE_SMART_CAPTIVE_SELECTIVE_SELFTEST 0x84 ///< defined in ACS-3 #define ATA_SMART_READLOG 0xd5 ///< defined in ACS-3 #define ATA_SMART_WRITELOG 0xd6 ///< defined in ACS-3 #define ATA_SMART_ENABLE_OPERATION 0xd8 ///< reserved #define ATA_SMART_DISABLE_OPERATION 0xd9 ///< defined in ACS-3 #define ATA_SMART_RETURN_STATUS 0xda ///< defined from ATA-3 #define ATA_SMART_THRESHOLD_NOT_EXCEEDED_VALUE 0xc24f ///< defined in ACS-3 #define ATA_SMART_THRESHOLD_EXCEEDED_VALUE 0x2cf4 ///< defined in ACS-3 // SMART Log Definitions #define ATA_SMART_LOG_DIRECTORY 0x00 ///< defined in ACS-3 #define ATA_SMART_SUM_SMART_ERROR_LOG 0x01 ///< defined in ACS-3 #define ATA_SMART_COMP_SMART_ERROR_LOG 0x02 ///< defined in ACS-3 #define ATA_SMART_EXT_COMP_SMART_ERROR_LOG 0x03 ///< defined in ACS-3 #define ATA_SMART_SMART_SELFTEST_LOG 0x06 ///< defined in ACS-3 #define ATA_SMART_EXT_SMART_SELFTEST_LOG 0x07 ///< defined in ACS-3 #define ATA_SMART_SELECTIVE_SELFTEST_LOG 0x09 ///< defined in ACS-3 #define ATA_SMART_HOST_VENDOR_SPECIFIC 0x80 ///< defined in ACS-3 #define ATA_SMART_DEVICE_VENDOR_SPECIFIC 0xa0 ///< defined in ACS-3 // // Class 4: DMA Command // #define ATA_CMD_READ_DMA 0xc8 ///< defined from ATA-1 #define ATA_CMD_READ_DMA_WITH_RETRY 0xc9 ///< defined from ATA-1, obsoleted from ATA-5 #define ATA_CMD_READ_DMA_EXT 0x25 ///< defined from ATA-6 #define ATA_CMD_WRITE_DMA 0xca ///< defined from ATA-1 #define ATA_CMD_WRITE_DMA_WITH_RETRY 0xcb ///< defined from ATA-1, obsoleted from ATA- #define ATA_CMD_WRITE_DMA_EXT 0x35 ///< defined from ATA-6 // // ATA Security commands // #define ATA_CMD_SECURITY_SET_PASSWORD 0xf1 ///< defined in ACS-3 #define ATA_CMD_SECURITY_UNLOCK 0xf2 ///< defined in ACS-3 #define ATA_CMD_SECURITY_ERASE_PREPARE 0xf3 ///< defined in ACS-3 #define ATA_CMD_SECURITY_ERASE_UNIT 0xf4 ///< defined in ACS-3 #define ATA_CMD_SECURITY_FREEZE_LOCK 0xf5 ///< defined in ACS-3 #define ATA_CMD_SECURITY_DISABLE_PASSWORD 0xf6 ///< defined in ACS-3 #define ATA_SECURITY_BUFFER_LENGTH 512 ///< defined in ACS-3 // // ATA Device Config Overlay // #define ATA_CMD_DEV_CONFIG_OVERLAY 0xb1 ///< defined from ATA-6 #define ATA_CMD_DEV_CONFIG_RESTORE_FEATURE 0xc0 ///< defined from ATA-6 #define ATA_CMD_DEV_CONFIG_FREEZELOCK_FEATURE 0xc1 ///< defined from ATA-6 #define ATA_CMD_DEV_CONFIG_IDENTIFY_FEATURE 0xc2 ///< defined from ATA-6 #define ATA_CMD_DEV_CONFIG_SET_FEATURE 0xc3 ///< defined from ATA-6 // // ATA Trusted Computing Feature Set Commands // #define ATA_CMD_TRUSTED_NON_DATA 0x5b ///< defined in ACS-3 #define ATA_CMD_TRUSTED_RECEIVE 0x5c ///< defined in ACS-3 #define ATA_CMD_TRUSTED_RECEIVE_DMA 0x5d ///< defined in ACS-3 #define ATA_CMD_TRUSTED_SEND 0x5e ///< defined in ACS-3 #define ATA_CMD_TRUSTED_SEND_DMA 0x5f ///< defined in ACS-3 // // ATA Trusted Receive Fields // #define ATA_TR_RETURN_SECURITY_PROTOCOL_INFORMATION 0x00 ///< defined in ACS-3 #define ATA_TR_SECURITY_PROTOCOL_JEDEC_RESERVED 0xec ///< defined in ACS-3 #define ATA_TR_SECURITY_PROTOCOL_SDCARD_RESERVED 0xed ///< defined in ACS-3 #define ATA_TR_SECURITY_PROTOCOL_IEEE1667_RESERVED 0xee ///< defined in ACS-3 // // Equates used for Acoustic Flags // #define ATA_ACOUSTIC_LEVEL_BYPASS 0xff ///< defined from ATA-6 #define ATA_ACOUSTIC_LEVEL_MAXIMUM_PERFORMANCE 0xfe ///< defined from ATA-6 #define ATA_ACOUSTIC_LEVEL_QUIET 0x80 ///< defined from ATA-6 // // Equates used for DiPM Support // #define ATA_CMD_DIPM_SUB 0x03 // defined in ACS-3 : Count value in SetFeature identification : 03h Device-initiated interface power state transitions #define ATA_DIPM_ENABLE 0x10 // defined in ACS-3 #define ATA_DIPM_DISABLE 0x90 // defined in ACS-3 // // Equates used for DevSleep Support // #define ATA_CMD_DEVSLEEP_SUB 0x09 // defined in SATA 3.2 Gold Spec : Count value in SetFeature identification : 09h Device Sleep #define ATA_DEVSLEEP_ENABLE 0x10 // defined in SATA 3.2 Gold Spec #define ATA_DEVSLEEP_DISABLE 0x90 // defined in SATA 3.2 Gold Spec #define ATA_DEVSLP_EXIT_TIMEOUT 20 // MDAT - 20 ms #define ATA_DEVSLP_MINIMUM_DETECTION_TIME 10 // DMDT - 10 us #define ATA_DEVSLP_MINIMUM_ASSERTION_TIME 10 // DETO - 10 ms // // Set MAX Commands // #define ATA_CMD_SET_MAX_ADDRESS_EXT 0x37 ///< defined from ATA-6 #define ATA_CMD_SET_MAX_ADDRESS 0xf9 ///< defined from ATA-6 #define ATA_SET_MAX_SET_PASSWORD 0x01 ///< defined from ATA-6 #define ATA_SET_MAX_LOCK 0x02 ///< defined from ATA-6 #define ATA_SET_MAX_UNLOCK 0x03 ///< defined from ATA-6 #define ATA_SET_MAX_FREEZE_LOCK 0x04 ///< defined from ATA-6 /// /// Default content of device control register, disable INT, /// Bit3 is set to 1 according ATA-1 /// #define ATA_DEFAULT_CTL (0x0a) /// /// Default context of Device/Head Register, /// Bit7 and Bit5 are set to 1 for back-compatibilities. /// #define ATA_DEFAULT_CMD (0xa0) #define ATAPI_MAX_BYTE_COUNT (0xfffe) #define ATA_REQUEST_SENSE_ERROR (0x70) ///< defined in SFF-8070i // // Sense Key, Additional Sense Codes and Additional Sense Code Qualifier // defined in MultiMedia Commands (MMC, MMC-2) // // Sense Key // #define ATA_SK_NO_SENSE (0x0) #define ATA_SK_RECOVERY_ERROR (0x1) #define ATA_SK_NOT_READY (0x2) #define ATA_SK_MEDIUM_ERROR (0x3) #define ATA_SK_HARDWARE_ERROR (0x4) #define ATA_SK_ILLEGAL_REQUEST (0x5) #define ATA_SK_UNIT_ATTENTION (0x6) #define ATA_SK_DATA_PROTECT (0x7) #define ATA_SK_BLANK_CHECK (0x8) #define ATA_SK_VENDOR_SPECIFIC (0x9) #define ATA_SK_RESERVED_A (0xA) #define ATA_SK_ABORT (0xB) #define ATA_SK_RESERVED_C (0xC) #define ATA_SK_OVERFLOW (0xD) #define ATA_SK_MISCOMPARE (0xE) #define ATA_SK_RESERVED_F (0xF) // // Additional Sense Codes // #define ATA_ASC_NOT_READY (0x04) #define ATA_ASC_MEDIA_ERR1 (0x10) #define ATA_ASC_MEDIA_ERR2 (0x11) #define ATA_ASC_MEDIA_ERR3 (0x14) #define ATA_ASC_MEDIA_ERR4 (0x30) #define ATA_ASC_MEDIA_UPSIDE_DOWN (0x06) #define ATA_ASC_INVALID_CMD (0x20) #define ATA_ASC_LBA_OUT_OF_RANGE (0x21) #define ATA_ASC_INVALID_FIELD (0x24) #define ATA_ASC_WRITE_PROTECTED (0x27) #define ATA_ASC_MEDIA_CHANGE (0x28) #define ATA_ASC_RESET (0x29) ///< Power On Reset or Bus Reset occurred. #define ATA_ASC_ILLEGAL_FIELD (0x26) #define ATA_ASC_NO_MEDIA (0x3A) #define ATA_ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64) // // Additional Sense Code Qualifier // #define ATA_ASCQ_IN_PROGRESS (0x01) // // Error Register // #define ATA_ERRREG_BBK BIT7 ///< Bad block detected defined from ATA-1, obsoleted from ATA-2 #define ATA_ERRREG_UNC BIT6 ///< Uncorrectable Data defined from ATA-1, obsoleted from ATA-4 #define ATA_ERRREG_MC BIT5 ///< Media Change defined from ATA-1, obsoleted from ATA-4 #define ATA_ERRREG_IDNF BIT4 ///< ID Not Found defined from ATA-1, obsoleted from ATA-4 #define ATA_ERRREG_MCR BIT3 ///< Media Change Requested defined from ATA-1, obsoleted from ATA-4 #define ATA_ERRREG_ABRT BIT2 ///< Aborted Command defined from ATA-1 #define ATA_ERRREG_TK0NF BIT1 ///< Track 0 Not Found defined from ATA-1, obsoleted from ATA-4 #define ATA_ERRREG_AMNF BIT0 ///< Address Mark Not Found defined from ATA-1, obsoleted from ATA-4 // // Status Register // #define ATA_STSREG_BSY BIT7 ///< Controller Busy defined from ATA-1 #define ATA_STSREG_DRDY BIT6 ///< Drive Ready defined from ATA-1 #define ATA_STSREG_DWF BIT5 ///< Drive Write Fault defined from ATA-1, obsoleted from ATA-4 #define ATA_STSREG_DF BIT5 ///< Drive Fault defined from ATA-6 #define ATA_STSREG_DSC BIT4 ///< Disk Seek Complete defined from ATA-1, obsoleted from ATA-4 #define ATA_STSREG_DRQ BIT3 ///< Data Request defined from ATA-1 #define ATA_STSREG_CORR BIT2 ///< Corrected Data defined from ATA-1, obsoleted from ATA-4 #define ATA_STSREG_IDX BIT1 ///< Index defined from ATA-1, obsoleted from ATA-4 #define ATA_STSREG_ERR BIT0 ///< Error defined from ATA-1 // // Device Control Register // #define ATA_CTLREG_SRST BIT2 ///< Software Reset. #define ATA_CTLREG_IEN_L BIT1 ///< Interrupt Enable #. #endif /** @file This file contains the Bluetooth definitions that are consumed by drivers. These definitions are from Bluetooth Core Specification Version 4.0 June, 2010 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _BLUETOOTH_H_ #define _BLUETOOTH_H_ #pragma pack(1) /// /// BLUETOOTH_ADDRESS /// typedef struct { /// /// 48bit Bluetooth device address. /// UINT8 Address[6]; } BLUETOOTH_ADDRESS; /// /// BLUETOOTH_CLASS_OF_DEVICE. See Bluetooth specification for detail. /// typedef struct { UINT8 FormatType : 2; UINT8 MinorDeviceClass : 6; UINT16 MajorDeviceClass : 5; UINT16 MajorServiceClass : 11; } BLUETOOTH_CLASS_OF_DEVICE; /// /// BLUETOOTH_LE_ADDRESS /// typedef struct { /// /// 48-bit Bluetooth device address /// UINT8 Address[6]; /// /// 0x00 - Public Device Address /// 0x01 - Random Device Address /// UINT8 Type; } BLUETOOTH_LE_ADDRESS; #pragma pack() #define BLUETOOTH_HCI_COMMAND_LOCAL_READABLE_NAME_MAX_SIZE 248 #define BLUETOOTH_HCI_LINK_KEY_SIZE 16 #endif /** @file EFI image format for PE32, PE32+ and TE. Please note some data structures are different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and EFI_IMAGE_NT_HEADERS64 is for PE32+. This file is coded to the Visual Studio, Microsoft Portable Executable and Common Object File Format Specification, Revision 8.3 - February 6, 2013. This file also includes some definitions in PI Specification, Revision 1.0. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
Portions Copyright (c) 2016 - 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PE_IMAGE_H__ #define __PE_IMAGE_H__ // // PE32+ Subsystem type for EFI images // #define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 #define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 #define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 #define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13///< defined PI Specification, 1.0 // // PE32+ Machine type for EFI images // #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_IA64 0x0200 #define IMAGE_FILE_MACHINE_EBC 0x0EBC #define IMAGE_FILE_MACHINE_X64 0x8664 #define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2 #define IMAGE_FILE_MACHINE_ARM64 0xAA64 #define IMAGE_FILE_MACHINE_RISCV32 0x5032 #define IMAGE_FILE_MACHINE_RISCV64 0x5064 #define IMAGE_FILE_MACHINE_RISCV128 0x5128 // // EXE file formats // #define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z') #define EFI_IMAGE_OS2_SIGNATURE SIGNATURE_16('N', 'E') #define EFI_IMAGE_OS2_SIGNATURE_LE SIGNATURE_16('L', 'E') #define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0') /// /// PE images can start with an optional DOS header, so if an image is run /// under DOS it can print an error message. /// typedef struct { UINT16 e_magic; ///< Magic number. UINT16 e_cblp; ///< Bytes on last page of file. UINT16 e_cp; ///< Pages in file. UINT16 e_crlc; ///< Relocations. UINT16 e_cparhdr; ///< Size of header in paragraphs. UINT16 e_minalloc; ///< Minimum extra paragraphs needed. UINT16 e_maxalloc; ///< Maximum extra paragraphs needed. UINT16 e_ss; ///< Initial (relative) SS value. UINT16 e_sp; ///< Initial SP value. UINT16 e_csum; ///< Checksum. UINT16 e_ip; ///< Initial IP value. UINT16 e_cs; ///< Initial (relative) CS value. UINT16 e_lfarlc; ///< File address of relocation table. UINT16 e_ovno; ///< Overlay number. UINT16 e_res[4]; ///< Reserved words. UINT16 e_oemid; ///< OEM identifier (for e_oeminfo). UINT16 e_oeminfo; ///< OEM information; e_oemid specific. UINT16 e_res2[10]; ///< Reserved words. UINT32 e_lfanew; ///< File address of new exe header. } EFI_IMAGE_DOS_HEADER; /// /// COFF File Header (Object and Image). /// typedef struct { UINT16 Machine; UINT16 NumberOfSections; UINT32 TimeDateStamp; UINT32 PointerToSymbolTable; UINT32 NumberOfSymbols; UINT16 SizeOfOptionalHeader; UINT16 Characteristics; } EFI_IMAGE_FILE_HEADER; /// /// Size of EFI_IMAGE_FILE_HEADER. /// #define EFI_IMAGE_SIZEOF_FILE_HEADER 20 // // Characteristics // #define EFI_IMAGE_FILE_RELOCS_STRIPPED BIT0 ///< 0x0001 Relocation info stripped from file. #define EFI_IMAGE_FILE_EXECUTABLE_IMAGE BIT1 ///< 0x0002 File is executable (i.e. no unresolved externel references). #define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED BIT2 ///< 0x0004 Line numbers stripped from file. #define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED BIT3 ///< 0x0008 Local symbols stripped from file. #define EFI_IMAGE_FILE_BYTES_REVERSED_LO BIT7 ///< 0x0080 Bytes of machine word are reversed. #define EFI_IMAGE_FILE_32BIT_MACHINE BIT8 ///< 0x0100 32 bit word machine. #define EFI_IMAGE_FILE_DEBUG_STRIPPED BIT9 ///< 0x0200 Debugging info stripped from file in .DBG file. #define EFI_IMAGE_FILE_SYSTEM BIT12 ///< 0x1000 System File. #define EFI_IMAGE_FILE_DLL BIT13 ///< 0x2000 File is a DLL. #define EFI_IMAGE_FILE_BYTES_REVERSED_HI BIT15 ///< 0x8000 Bytes of machine word are reversed. /// /// Header Data Directories. /// typedef struct { UINT32 VirtualAddress; UINT32 Size; } EFI_IMAGE_DATA_DIRECTORY; // // Directory Entries // #define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 #define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 #define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 #define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 #define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 #define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 #define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 #define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 #define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 #define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 #define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 #define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 /// /// @attention /// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and /// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary /// after NT additional fields. /// #define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b /// /// Optional Header Standard Fields for PE32. /// typedef struct { /// /// Standard fields. /// UINT16 Magic; UINT8 MajorLinkerVersion; UINT8 MinorLinkerVersion; UINT32 SizeOfCode; UINT32 SizeOfInitializedData; UINT32 SizeOfUninitializedData; UINT32 AddressOfEntryPoint; UINT32 BaseOfCode; UINT32 BaseOfData; ///< PE32 contains this additional field, which is absent in PE32+. /// /// Optional Header Windows-Specific Fields. /// UINT32 ImageBase; UINT32 SectionAlignment; UINT32 FileAlignment; UINT16 MajorOperatingSystemVersion; UINT16 MinorOperatingSystemVersion; UINT16 MajorImageVersion; UINT16 MinorImageVersion; UINT16 MajorSubsystemVersion; UINT16 MinorSubsystemVersion; UINT32 Win32VersionValue; UINT32 SizeOfImage; UINT32 SizeOfHeaders; UINT32 CheckSum; UINT16 Subsystem; UINT16 DllCharacteristics; UINT32 SizeOfStackReserve; UINT32 SizeOfStackCommit; UINT32 SizeOfHeapReserve; UINT32 SizeOfHeapCommit; UINT32 LoaderFlags; UINT32 NumberOfRvaAndSizes; EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; } EFI_IMAGE_OPTIONAL_HEADER32; /// /// @attention /// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and /// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary /// after NT additional fields. /// #define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b /// /// Optional Header Standard Fields for PE32+. /// typedef struct { /// /// Standard fields. /// UINT16 Magic; UINT8 MajorLinkerVersion; UINT8 MinorLinkerVersion; UINT32 SizeOfCode; UINT32 SizeOfInitializedData; UINT32 SizeOfUninitializedData; UINT32 AddressOfEntryPoint; UINT32 BaseOfCode; /// /// Optional Header Windows-Specific Fields. /// UINT64 ImageBase; UINT32 SectionAlignment; UINT32 FileAlignment; UINT16 MajorOperatingSystemVersion; UINT16 MinorOperatingSystemVersion; UINT16 MajorImageVersion; UINT16 MinorImageVersion; UINT16 MajorSubsystemVersion; UINT16 MinorSubsystemVersion; UINT32 Win32VersionValue; UINT32 SizeOfImage; UINT32 SizeOfHeaders; UINT32 CheckSum; UINT16 Subsystem; UINT16 DllCharacteristics; UINT64 SizeOfStackReserve; UINT64 SizeOfStackCommit; UINT64 SizeOfHeapReserve; UINT64 SizeOfHeapCommit; UINT32 LoaderFlags; UINT32 NumberOfRvaAndSizes; EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; } EFI_IMAGE_OPTIONAL_HEADER64; /// /// @attention /// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools. /// typedef struct { UINT32 Signature; EFI_IMAGE_FILE_HEADER FileHeader; EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; } EFI_IMAGE_NT_HEADERS32; #define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) /// /// @attention /// EFI_IMAGE_HEADERS64 is for use ONLY by tools. /// typedef struct { UINT32 Signature; EFI_IMAGE_FILE_HEADER FileHeader; EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; } EFI_IMAGE_NT_HEADERS64; #define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) // // Other Windows Subsystem Values // #define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 #define EFI_IMAGE_SUBSYSTEM_NATIVE 1 #define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 #define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3 #define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 #define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 /// /// Length of ShortName. /// #define EFI_IMAGE_SIZEOF_SHORT_NAME 8 /// /// Section Table. This table immediately follows the optional header. /// typedef struct { UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; union { UINT32 PhysicalAddress; UINT32 VirtualSize; } Misc; UINT32 VirtualAddress; UINT32 SizeOfRawData; UINT32 PointerToRawData; UINT32 PointerToRelocations; UINT32 PointerToLinenumbers; UINT16 NumberOfRelocations; UINT16 NumberOfLinenumbers; UINT32 Characteristics; } EFI_IMAGE_SECTION_HEADER; /// /// Size of EFI_IMAGE_SECTION_HEADER. /// #define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 // // Section Flags Values // #define EFI_IMAGE_SCN_TYPE_NO_PAD BIT3 ///< 0x00000008 ///< Reserved. #define EFI_IMAGE_SCN_CNT_CODE BIT5 ///< 0x00000020 #define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA BIT6 ///< 0x00000040 #define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA BIT7 ///< 0x00000080 #define EFI_IMAGE_SCN_LNK_OTHER BIT8 ///< 0x00000100 ///< Reserved. #define EFI_IMAGE_SCN_LNK_INFO BIT9 ///< 0x00000200 ///< Section contains comments or some other type of information. #define EFI_IMAGE_SCN_LNK_REMOVE BIT11 ///< 0x00000800 ///< Section contents will not become part of image. #define EFI_IMAGE_SCN_LNK_COMDAT BIT12 ///< 0x00001000 #define EFI_IMAGE_SCN_ALIGN_1BYTES BIT20 ///< 0x00100000 #define EFI_IMAGE_SCN_ALIGN_2BYTES BIT21 ///< 0x00200000 #define EFI_IMAGE_SCN_ALIGN_4BYTES (BIT20|BIT21) ///< 0x00300000 #define EFI_IMAGE_SCN_ALIGN_8BYTES BIT22 ///< 0x00400000 #define EFI_IMAGE_SCN_ALIGN_16BYTES (BIT20|BIT22) ///< 0x00500000 #define EFI_IMAGE_SCN_ALIGN_32BYTES (BIT21|BIT22) ///< 0x00600000 #define EFI_IMAGE_SCN_ALIGN_64BYTES (BIT20|BIT21|BIT22) ///< 0x00700000 #define EFI_IMAGE_SCN_MEM_DISCARDABLE BIT25 ///< 0x02000000 #define EFI_IMAGE_SCN_MEM_NOT_CACHED BIT26 ///< 0x04000000 #define EFI_IMAGE_SCN_MEM_NOT_PAGED BIT27 ///< 0x08000000 #define EFI_IMAGE_SCN_MEM_SHARED BIT28 ///< 0x10000000 #define EFI_IMAGE_SCN_MEM_EXECUTE BIT29 ///< 0x20000000 #define EFI_IMAGE_SCN_MEM_READ BIT30 ///< 0x40000000 #define EFI_IMAGE_SCN_MEM_WRITE BIT31 ///< 0x80000000 /// /// Size of a Symbol Table Record. /// #define EFI_IMAGE_SIZEOF_SYMBOL 18 // // Symbols have a section number of the section in which they are // defined. Otherwise, section numbers have the following meanings: // #define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common. #define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value. #define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item. // // Symbol Type (fundamental) values. // #define EFI_IMAGE_SYM_TYPE_NULL 0 ///< no type. #define EFI_IMAGE_SYM_TYPE_VOID 1 ///< no valid type. #define EFI_IMAGE_SYM_TYPE_CHAR 2 ///< type character. #define EFI_IMAGE_SYM_TYPE_SHORT 3 ///< type short integer. #define EFI_IMAGE_SYM_TYPE_INT 4 #define EFI_IMAGE_SYM_TYPE_LONG 5 #define EFI_IMAGE_SYM_TYPE_FLOAT 6 #define EFI_IMAGE_SYM_TYPE_DOUBLE 7 #define EFI_IMAGE_SYM_TYPE_STRUCT 8 #define EFI_IMAGE_SYM_TYPE_UNION 9 #define EFI_IMAGE_SYM_TYPE_ENUM 10 ///< enumeration. #define EFI_IMAGE_SYM_TYPE_MOE 11 ///< member of enumeration. #define EFI_IMAGE_SYM_TYPE_BYTE 12 #define EFI_IMAGE_SYM_TYPE_WORD 13 #define EFI_IMAGE_SYM_TYPE_UINT 14 #define EFI_IMAGE_SYM_TYPE_DWORD 15 // // Symbol Type (derived) values. // #define EFI_IMAGE_SYM_DTYPE_NULL 0 ///< no derived type. #define EFI_IMAGE_SYM_DTYPE_POINTER 1 #define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 #define EFI_IMAGE_SYM_DTYPE_ARRAY 3 // // Storage classes. // #define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1) #define EFI_IMAGE_SYM_CLASS_NULL 0 #define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 #define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 #define EFI_IMAGE_SYM_CLASS_STATIC 3 #define EFI_IMAGE_SYM_CLASS_REGISTER 4 #define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 #define EFI_IMAGE_SYM_CLASS_LABEL 6 #define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 #define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 #define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 #define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 #define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 #define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 #define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 #define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 #define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 #define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 #define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 #define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 #define EFI_IMAGE_SYM_CLASS_BLOCK 100 #define EFI_IMAGE_SYM_CLASS_FUNCTION 101 #define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 #define EFI_IMAGE_SYM_CLASS_FILE 103 #define EFI_IMAGE_SYM_CLASS_SECTION 104 #define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 // // type packing constants // #define EFI_IMAGE_N_BTMASK 017 #define EFI_IMAGE_N_TMASK 060 #define EFI_IMAGE_N_TMASK1 0300 #define EFI_IMAGE_N_TMASK2 0360 #define EFI_IMAGE_N_BTSHFT 4 #define EFI_IMAGE_N_TSHIFT 2 // // Communal selection types. // #define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 #define EFI_IMAGE_COMDAT_SELECT_ANY 2 #define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 #define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 #define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 // // the following values only be referred in PeCoff, not defined in PECOFF. // #define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 #define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 #define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 /// /// Relocation format. /// typedef struct { UINT32 VirtualAddress; UINT32 SymbolTableIndex; UINT16 Type; } EFI_IMAGE_RELOCATION; /// /// Size of EFI_IMAGE_RELOCATION /// #define EFI_IMAGE_SIZEOF_RELOCATION 10 // // I386 relocation types. // #define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 ///< Reference is absolute, no relocation is necessary. #define EFI_IMAGE_REL_I386_DIR16 0x0001 ///< Direct 16-bit reference to the symbols virtual address. #define EFI_IMAGE_REL_I386_REL16 0x0002 ///< PC-relative 16-bit reference to the symbols virtual address. #define EFI_IMAGE_REL_I386_DIR32 0x0006 ///< Direct 32-bit reference to the symbols virtual address. #define EFI_IMAGE_REL_I386_DIR32NB 0x0007 ///< Direct 32-bit reference to the symbols virtual address, base not included. #define EFI_IMAGE_REL_I386_SEG12 0x0009 ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address. #define EFI_IMAGE_REL_I386_SECTION 0x000A #define EFI_IMAGE_REL_I386_SECREL 0x000B #define EFI_IMAGE_REL_I386_REL32 0x0014 ///< PC-relative 32-bit reference to the symbols virtual address. // // x64 processor relocation types. // #define IMAGE_REL_AMD64_ABSOLUTE 0x0000 #define IMAGE_REL_AMD64_ADDR64 0x0001 #define IMAGE_REL_AMD64_ADDR32 0x0002 #define IMAGE_REL_AMD64_ADDR32NB 0x0003 #define IMAGE_REL_AMD64_REL32 0x0004 #define IMAGE_REL_AMD64_REL32_1 0x0005 #define IMAGE_REL_AMD64_REL32_2 0x0006 #define IMAGE_REL_AMD64_REL32_3 0x0007 #define IMAGE_REL_AMD64_REL32_4 0x0008 #define IMAGE_REL_AMD64_REL32_5 0x0009 #define IMAGE_REL_AMD64_SECTION 0x000A #define IMAGE_REL_AMD64_SECREL 0x000B #define IMAGE_REL_AMD64_SECREL7 0x000C #define IMAGE_REL_AMD64_TOKEN 0x000D #define IMAGE_REL_AMD64_SREL32 0x000E #define IMAGE_REL_AMD64_PAIR 0x000F #define IMAGE_REL_AMD64_SSPAN32 0x0010 /// /// Based relocation format. /// typedef struct { UINT32 VirtualAddress; UINT32 SizeOfBlock; } EFI_IMAGE_BASE_RELOCATION; /// /// Size of EFI_IMAGE_BASE_RELOCATION. /// #define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 // // Based relocation types. // #define EFI_IMAGE_REL_BASED_ABSOLUTE 0 #define EFI_IMAGE_REL_BASED_HIGH 1 #define EFI_IMAGE_REL_BASED_LOW 2 #define EFI_IMAGE_REL_BASED_HIGHLOW 3 #define EFI_IMAGE_REL_BASED_HIGHADJ 4 #define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 #define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 #define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 #define EFI_IMAGE_REL_BASED_IA64_IMM64 9 #define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9 #define EFI_IMAGE_REL_BASED_DIR64 10 /// /// Relocation types of RISC-V processor. /// #define EFI_IMAGE_REL_BASED_RISCV_HI20 5 #define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 #define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 /// /// Line number format. /// typedef struct { union { UINT32 SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0. UINT32 VirtualAddress; ///< Virtual address of line number. } Type; UINT16 Linenumber; ///< Line number. } EFI_IMAGE_LINENUMBER; /// /// Size of EFI_IMAGE_LINENUMBER. /// #define EFI_IMAGE_SIZEOF_LINENUMBER 6 // // Archive format. // #define EFI_IMAGE_ARCHIVE_START_SIZE 8 #define EFI_IMAGE_ARCHIVE_START "!\n" #define EFI_IMAGE_ARCHIVE_END "`\n" #define EFI_IMAGE_ARCHIVE_PAD "\n" #define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " #define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " /// /// Archive Member Headers /// typedef struct { UINT8 Name[16]; ///< File member name - `/' terminated. UINT8 Date[12]; ///< File member date - decimal. UINT8 UserID[6]; ///< File member user id - decimal. UINT8 GroupID[6]; ///< File member group id - decimal. UINT8 Mode[8]; ///< File member mode - octal. UINT8 Size[10]; ///< File member size - decimal. UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A). } EFI_IMAGE_ARCHIVE_MEMBER_HEADER; /// /// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER. /// #define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 // // DLL Support // /// /// Export Directory Table. /// typedef struct { UINT32 Characteristics; UINT32 TimeDateStamp; UINT16 MajorVersion; UINT16 MinorVersion; UINT32 Name; UINT32 Base; UINT32 NumberOfFunctions; UINT32 NumberOfNames; UINT32 AddressOfFunctions; UINT32 AddressOfNames; UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; /// /// Hint/Name Table. /// typedef struct { UINT16 Hint; UINT8 Name[1]; } EFI_IMAGE_IMPORT_BY_NAME; /// /// Import Address Table RVA (Thunk Table). /// typedef struct { union { UINT32 Function; UINT32 Ordinal; EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; } u1; } EFI_IMAGE_THUNK_DATA; #define EFI_IMAGE_ORDINAL_FLAG BIT31 ///< Flag for PE32. #define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) #define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) /// /// Import Directory Table /// typedef struct { UINT32 Characteristics; UINT32 TimeDateStamp; UINT32 ForwarderChain; UINT32 Name; EFI_IMAGE_THUNK_DATA *FirstThunk; } EFI_IMAGE_IMPORT_DESCRIPTOR; /// /// Debug Directory Format. /// typedef struct { UINT32 Characteristics; UINT32 TimeDateStamp; UINT16 MajorVersion; UINT16 MinorVersion; UINT32 Type; UINT32 SizeOfData; UINT32 RVA; ///< The address of the debug data when loaded, relative to the image base. UINT32 FileOffset; ///< The file pointer to the debug data. } EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; #define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 ///< The Visual C++ debug information. /// /// Debug Data Structure defined in Microsoft C++. /// #define CODEVIEW_SIGNATURE_NB10 SIGNATURE_32('N', 'B', '1', '0') typedef struct { UINT32 Signature; ///< "NB10" UINT32 Unknown; UINT32 Unknown2; UINT32 Unknown3; // // Filename of .PDB goes here // } EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; /// /// Debug Data Structure defined in Microsoft C++. /// #define CODEVIEW_SIGNATURE_RSDS SIGNATURE_32('R', 'S', 'D', 'S') typedef struct { UINT32 Signature; ///< "RSDS". UINT32 Unknown; UINT32 Unknown2; UINT32 Unknown3; UINT32 Unknown4; UINT32 Unknown5; // // Filename of .PDB goes here // } EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; /// /// Debug Data Structure defined by Apple Mach-O to Coff utility. /// #define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C') typedef struct { UINT32 Signature; ///< "MTOC". GUID MachOUuid; // // Filename of .DLL (Mach-O with debug info) goes here // } EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY; /// /// Resource format. /// typedef struct { UINT32 Characteristics; UINT32 TimeDateStamp; UINT16 MajorVersion; UINT16 MinorVersion; UINT16 NumberOfNamedEntries; UINT16 NumberOfIdEntries; // // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here. // } EFI_IMAGE_RESOURCE_DIRECTORY; /// /// Resource directory entry format. /// typedef struct { union { struct { UINT32 NameOffset : 31; UINT32 NameIsString : 1; } s; UINT32 Id; } u1; union { UINT32 OffsetToData; struct { UINT32 OffsetToDirectory : 31; UINT32 DataIsDirectory : 1; } s; } u2; } EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY; /// /// Resource directory entry for string. /// typedef struct { UINT16 Length; CHAR16 String[1]; } EFI_IMAGE_RESOURCE_DIRECTORY_STRING; /// /// Resource directory entry for data array. /// typedef struct { UINT32 OffsetToData; UINT32 Size; UINT32 CodePage; UINT32 Reserved; } EFI_IMAGE_RESOURCE_DATA_ENTRY; /// /// Header format for TE images, defined in the PI Specification, 1.0. /// typedef struct { UINT16 Signature; ///< The signature for TE format = "VZ". UINT16 Machine; ///< From the original file header. UINT8 NumberOfSections; ///< From the original file header. UINT8 Subsystem; ///< From original optional header. UINT16 StrippedSize; ///< Number of bytes we removed from the header. UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header. UINT32 BaseOfCode; ///< From original image -- required for ITP debug. UINT64 ImageBase; ///< From original file header. EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory. } EFI_TE_IMAGE_HEADER; #define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z') // // Data directory indexes in our TE image header // #define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 #define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 /// /// Union of PE32, PE32+, and TE headers. /// typedef union { EFI_IMAGE_NT_HEADERS32 Pe32; EFI_IMAGE_NT_HEADERS64 Pe32Plus; EFI_TE_IMAGE_HEADER Te; } EFI_IMAGE_OPTIONAL_HEADER_UNION; typedef union { EFI_IMAGE_NT_HEADERS32 *Pe32; EFI_IMAGE_NT_HEADERS64 *Pe32Plus; EFI_TE_IMAGE_HEADER *Te; EFI_IMAGE_OPTIONAL_HEADER_UNION *Union; } EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION; #endif /** @file TPM Specification data structures (TCG TPM Specification Version 1.2 Revision 103) See http://trustedcomputinggroup.org for latest specification updates Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _TPM12_H_ #define _TPM12_H_ /// /// The start of TPM return codes /// #define TPM_BASE 0 // // All structures MUST be packed on a byte boundary. // #pragma pack (1) // // Part 2, section 2.2.3: Helper redefinitions // /// /// Indicates the conditions where it is required that authorization be presented /// typedef UINT8 TPM_AUTH_DATA_USAGE; /// /// The information as to what the payload is in an encrypted structure /// typedef UINT8 TPM_PAYLOAD_TYPE; /// /// The version info breakdown /// typedef UINT8 TPM_VERSION_BYTE; /// /// The state of the dictionary attack mitigation logic /// typedef UINT8 TPM_DA_STATE; /// /// The request or response authorization type /// typedef UINT16 TPM_TAG; /// /// The protocol in use /// typedef UINT16 TPM_PROTOCOL_ID; /// /// Indicates the start state /// typedef UINT16 TPM_STARTUP_TYPE; /// /// The definition of the encryption scheme /// typedef UINT16 TPM_ENC_SCHEME; /// /// The definition of the signature scheme /// typedef UINT16 TPM_SIG_SCHEME; /// /// The definition of the migration scheme /// typedef UINT16 TPM_MIGRATE_SCHEME; /// /// Sets the state of the physical presence mechanism /// typedef UINT16 TPM_PHYSICAL_PRESENCE; /// /// Indicates the types of entity that are supported by the TPM /// typedef UINT16 TPM_ENTITY_TYPE; /// /// Indicates the permitted usage of the key /// typedef UINT16 TPM_KEY_USAGE; /// /// The type of asymmetric encrypted structure in use by the endorsement key /// typedef UINT16 TPM_EK_TYPE; /// /// The tag for the structure /// typedef UINT16 TPM_STRUCTURE_TAG; /// /// The platform specific spec to which the information relates to /// typedef UINT16 TPM_PLATFORM_SPECIFIC; /// /// The command ordinal /// typedef UINT32 TPM_COMMAND_CODE; /// /// Identifies a TPM capability area /// typedef UINT32 TPM_CAPABILITY_AREA; /// /// Indicates information regarding a key /// typedef UINT32 TPM_KEY_FLAGS; /// /// Indicates the type of algorithm /// typedef UINT32 TPM_ALGORITHM_ID; /// /// The locality modifier /// typedef UINT32 TPM_MODIFIER_INDICATOR; /// /// The actual number of a counter /// typedef UINT32 TPM_ACTUAL_COUNT; /// /// Attributes that define what options are in use for a transport session /// typedef UINT32 TPM_TRANSPORT_ATTRIBUTES; /// /// Handle to an authorization session /// typedef UINT32 TPM_AUTHHANDLE; /// /// Index to a DIR register /// typedef UINT32 TPM_DIRINDEX; /// /// The area where a key is held assigned by the TPM /// typedef UINT32 TPM_KEY_HANDLE; /// /// Index to a PCR register /// typedef UINT32 TPM_PCRINDEX; /// /// The return code from a function /// typedef UINT32 TPM_RESULT; /// /// The types of resources that a TPM may have using internal resources /// typedef UINT32 TPM_RESOURCE_TYPE; /// /// Allows for controlling of the key when loaded and how to handle TPM_Startup issues /// typedef UINT32 TPM_KEY_CONTROL; /// /// The index into the NV storage area /// typedef UINT32 TPM_NV_INDEX; /// /// The family ID. Family IDs are automatically assigned a sequence number by the TPM. /// A trusted process can set the FamilyID value in an individual row to NULL, which /// invalidates that row. The family ID resets to NULL on each change of TPM Owner. /// typedef UINT32 TPM_FAMILY_ID; /// /// IA value used as a label for the most recent verification of this family. Set to zero when not in use. /// typedef UINT32 TPM_FAMILY_VERIFICATION; /// /// How the TPM handles var /// typedef UINT32 TPM_STARTUP_EFFECTS; /// /// The mode of a symmetric encryption /// typedef UINT32 TPM_SYM_MODE; /// /// The family flags /// typedef UINT32 TPM_FAMILY_FLAGS; /// /// The index value for the delegate NV table /// typedef UINT32 TPM_DELEGATE_INDEX; /// /// The restrictions placed on delegation of CMK commands /// typedef UINT32 TPM_CMK_DELEGATE; /// /// The ID value of a monotonic counter /// typedef UINT32 TPM_COUNT_ID; /// /// A command to execute /// typedef UINT32 TPM_REDIT_COMMAND; /// /// A transport session handle /// typedef UINT32 TPM_TRANSHANDLE; /// /// A generic handle could be key, transport etc /// typedef UINT32 TPM_HANDLE; /// /// What operation is happening /// typedef UINT32 TPM_FAMILY_OPERATION; // // Part 2, section 2.2.4: Vendor specific // The following defines allow for the quick specification of a // vendor specific item. // #define TPM_Vendor_Specific32 ((UINT32) 0x00000400) #define TPM_Vendor_Specific8 ((UINT8) 0x80) // // Part 2, section 3.1: TPM_STRUCTURE_TAG // #define TPM_TAG_CONTEXTBLOB ((TPM_STRUCTURE_TAG) 0x0001) #define TPM_TAG_CONTEXT_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0002) #define TPM_TAG_CONTEXTPOINTER ((TPM_STRUCTURE_TAG) 0x0003) #define TPM_TAG_CONTEXTLIST ((TPM_STRUCTURE_TAG) 0x0004) #define TPM_TAG_SIGNINFO ((TPM_STRUCTURE_TAG) 0x0005) #define TPM_TAG_PCR_INFO_LONG ((TPM_STRUCTURE_TAG) 0x0006) #define TPM_TAG_PERSISTENT_FLAGS ((TPM_STRUCTURE_TAG) 0x0007) #define TPM_TAG_VOLATILE_FLAGS ((TPM_STRUCTURE_TAG) 0x0008) #define TPM_TAG_PERSISTENT_DATA ((TPM_STRUCTURE_TAG) 0x0009) #define TPM_TAG_VOLATILE_DATA ((TPM_STRUCTURE_TAG) 0x000A) #define TPM_TAG_SV_DATA ((TPM_STRUCTURE_TAG) 0x000B) #define TPM_TAG_EK_BLOB ((TPM_STRUCTURE_TAG) 0x000C) #define TPM_TAG_EK_BLOB_AUTH ((TPM_STRUCTURE_TAG) 0x000D) #define TPM_TAG_COUNTER_VALUE ((TPM_STRUCTURE_TAG) 0x000E) #define TPM_TAG_TRANSPORT_INTERNAL ((TPM_STRUCTURE_TAG) 0x000F) #define TPM_TAG_TRANSPORT_LOG_IN ((TPM_STRUCTURE_TAG) 0x0010) #define TPM_TAG_TRANSPORT_LOG_OUT ((TPM_STRUCTURE_TAG) 0x0011) #define TPM_TAG_AUDIT_EVENT_IN ((TPM_STRUCTURE_TAG) 0x0012) #define TPM_TAG_AUDIT_EVENT_OUT ((TPM_STRUCTURE_TAG) 0x0013) #define TPM_TAG_CURRENT_TICKS ((TPM_STRUCTURE_TAG) 0x0014) #define TPM_TAG_KEY ((TPM_STRUCTURE_TAG) 0x0015) #define TPM_TAG_STORED_DATA12 ((TPM_STRUCTURE_TAG) 0x0016) #define TPM_TAG_NV_ATTRIBUTES ((TPM_STRUCTURE_TAG) 0x0017) #define TPM_TAG_NV_DATA_PUBLIC ((TPM_STRUCTURE_TAG) 0x0018) #define TPM_TAG_NV_DATA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0019) #define TPM_TAG_DELEGATIONS ((TPM_STRUCTURE_TAG) 0x001A) #define TPM_TAG_DELEGATE_PUBLIC ((TPM_STRUCTURE_TAG) 0x001B) #define TPM_TAG_DELEGATE_TABLE_ROW ((TPM_STRUCTURE_TAG) 0x001C) #define TPM_TAG_TRANSPORT_AUTH ((TPM_STRUCTURE_TAG) 0x001D) #define TPM_TAG_TRANSPORT_PUBLIC ((TPM_STRUCTURE_TAG) 0x001E) #define TPM_TAG_PERMANENT_FLAGS ((TPM_STRUCTURE_TAG) 0x001F) #define TPM_TAG_STCLEAR_FLAGS ((TPM_STRUCTURE_TAG) 0x0020) #define TPM_TAG_STANY_FLAGS ((TPM_STRUCTURE_TAG) 0x0021) #define TPM_TAG_PERMANENT_DATA ((TPM_STRUCTURE_TAG) 0x0022) #define TPM_TAG_STCLEAR_DATA ((TPM_STRUCTURE_TAG) 0x0023) #define TPM_TAG_STANY_DATA ((TPM_STRUCTURE_TAG) 0x0024) #define TPM_TAG_FAMILY_TABLE_ENTRY ((TPM_STRUCTURE_TAG) 0x0025) #define TPM_TAG_DELEGATE_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0026) #define TPM_TAG_DELG_KEY_BLOB ((TPM_STRUCTURE_TAG) 0x0027) #define TPM_TAG_KEY12 ((TPM_STRUCTURE_TAG) 0x0028) #define TPM_TAG_CERTIFY_INFO2 ((TPM_STRUCTURE_TAG) 0x0029) #define TPM_TAG_DELEGATE_OWNER_BLOB ((TPM_STRUCTURE_TAG) 0x002A) #define TPM_TAG_EK_BLOB_ACTIVATE ((TPM_STRUCTURE_TAG) 0x002B) #define TPM_TAG_DAA_BLOB ((TPM_STRUCTURE_TAG) 0x002C) #define TPM_TAG_DAA_CONTEXT ((TPM_STRUCTURE_TAG) 0x002D) #define TPM_TAG_DAA_ENFORCE ((TPM_STRUCTURE_TAG) 0x002E) #define TPM_TAG_DAA_ISSUER ((TPM_STRUCTURE_TAG) 0x002F) #define TPM_TAG_CAP_VERSION_INFO ((TPM_STRUCTURE_TAG) 0x0030) #define TPM_TAG_DAA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0031) #define TPM_TAG_DAA_TPM ((TPM_STRUCTURE_TAG) 0x0032) #define TPM_TAG_CMK_MIGAUTH ((TPM_STRUCTURE_TAG) 0x0033) #define TPM_TAG_CMK_SIGTICKET ((TPM_STRUCTURE_TAG) 0x0034) #define TPM_TAG_CMK_MA_APPROVAL ((TPM_STRUCTURE_TAG) 0x0035) #define TPM_TAG_QUOTE_INFO2 ((TPM_STRUCTURE_TAG) 0x0036) #define TPM_TAG_DA_INFO ((TPM_STRUCTURE_TAG) 0x0037) #define TPM_TAG_DA_LIMITED ((TPM_STRUCTURE_TAG) 0x0038) #define TPM_TAG_DA_ACTION_TYPE ((TPM_STRUCTURE_TAG) 0x0039) // // Part 2, section 4: TPM Types // // // Part 2, section 4.1: TPM_RESOURCE_TYPE // #define TPM_RT_KEY ((TPM_RESOURCE_TYPE) 0x00000001) ///< The handle is a key handle and is the result of a LoadKey type operation #define TPM_RT_AUTH ((TPM_RESOURCE_TYPE) 0x00000002) ///< The handle is an authorization handle. Auth handles come from TPM_OIAP, TPM_OSAP and TPM_DSAP #define TPM_RT_HASH ((TPM_RESOURCE_TYPE) 0x00000003) ///< Reserved for hashes #define TPM_RT_TRANS ((TPM_RESOURCE_TYPE) 0x00000004) ///< The handle is for a transport session. Transport handles come from TPM_EstablishTransport #define TPM_RT_CONTEXT ((TPM_RESOURCE_TYPE) 0x00000005) ///< Resource wrapped and held outside the TPM using the context save/restore commands #define TPM_RT_COUNTER ((TPM_RESOURCE_TYPE) 0x00000006) ///< Reserved for counters #define TPM_RT_DELEGATE ((TPM_RESOURCE_TYPE) 0x00000007) ///< The handle is for a delegate row. These are the internal rows held in NV storage by the TPM #define TPM_RT_DAA_TPM ((TPM_RESOURCE_TYPE) 0x00000008) ///< The value is a DAA TPM specific blob #define TPM_RT_DAA_V0 ((TPM_RESOURCE_TYPE) 0x00000009) ///< The value is a DAA V0 parameter #define TPM_RT_DAA_V1 ((TPM_RESOURCE_TYPE) 0x0000000A) ///< The value is a DAA V1 parameter // // Part 2, section 4.2: TPM_PAYLOAD_TYPE // #define TPM_PT_ASYM ((TPM_PAYLOAD_TYPE) 0x01) ///< The entity is an asymmetric key #define TPM_PT_BIND ((TPM_PAYLOAD_TYPE) 0x02) ///< The entity is bound data #define TPM_PT_MIGRATE ((TPM_PAYLOAD_TYPE) 0x03) ///< The entity is a migration blob #define TPM_PT_MAINT ((TPM_PAYLOAD_TYPE) 0x04) ///< The entity is a maintenance blob #define TPM_PT_SEAL ((TPM_PAYLOAD_TYPE) 0x05) ///< The entity is sealed data #define TPM_PT_MIGRATE_RESTRICTED ((TPM_PAYLOAD_TYPE) 0x06) ///< The entity is a restricted-migration asymmetric key #define TPM_PT_MIGRATE_EXTERNAL ((TPM_PAYLOAD_TYPE) 0x07) ///< The entity is a external migratable key #define TPM_PT_CMK_MIGRATE ((TPM_PAYLOAD_TYPE) 0x08) ///< The entity is a CMK migratable blob #define TPM_PT_VENDOR_SPECIFIC ((TPM_PAYLOAD_TYPE) 0x80) ///< 0x80 - 0xFF Vendor specific payloads // // Part 2, section 4.3: TPM_ENTITY_TYPE // #define TPM_ET_KEYHANDLE ((UINT16) 0x0001) ///< The entity is a keyHandle or key #define TPM_ET_OWNER ((UINT16) 0x0002) ///< The entity is the TPM Owner #define TPM_ET_DATA ((UINT16) 0x0003) ///< The entity is some data #define TPM_ET_SRK ((UINT16) 0x0004) ///< The entity is the SRK #define TPM_ET_KEY ((UINT16) 0x0005) ///< The entity is a key or keyHandle #define TPM_ET_REVOKE ((UINT16) 0x0006) ///< The entity is the RevokeTrust value #define TPM_ET_DEL_OWNER_BLOB ((UINT16) 0x0007) ///< The entity is a delegate owner blob #define TPM_ET_DEL_ROW ((UINT16) 0x0008) ///< The entity is a delegate row #define TPM_ET_DEL_KEY_BLOB ((UINT16) 0x0009) ///< The entity is a delegate key blob #define TPM_ET_COUNTER ((UINT16) 0x000A) ///< The entity is a counter #define TPM_ET_NV ((UINT16) 0x000B) ///< The entity is a NV index #define TPM_ET_OPERATOR ((UINT16) 0x000C) ///< The entity is the operator #define TPM_ET_RESERVED_HANDLE ((UINT16) 0x0040) ///< Reserved. This value avoids collisions with the handle MSB setting. // // TPM_ENTITY_TYPE MSB Values: The MSB is used to indicate the ADIP encryption sheme when applicable // #define TPM_ET_XOR ((UINT16) 0x0000) ///< ADIP encryption scheme: XOR #define TPM_ET_AES128 ((UINT16) 0x0006) ///< ADIP encryption scheme: AES 128 bits // // Part 2, section 4.4.1: Reserved Key Handles // #define TPM_KH_SRK ((TPM_KEY_HANDLE) 0x40000000) ///< The handle points to the SRK #define TPM_KH_OWNER ((TPM_KEY_HANDLE) 0x40000001) ///< The handle points to the TPM Owner #define TPM_KH_REVOKE ((TPM_KEY_HANDLE) 0x40000002) ///< The handle points to the RevokeTrust value #define TPM_KH_TRANSPORT ((TPM_KEY_HANDLE) 0x40000003) ///< The handle points to the EstablishTransport static authorization #define TPM_KH_OPERATOR ((TPM_KEY_HANDLE) 0x40000004) ///< The handle points to the Operator auth #define TPM_KH_ADMIN ((TPM_KEY_HANDLE) 0x40000005) ///< The handle points to the delegation administration auth #define TPM_KH_EK ((TPM_KEY_HANDLE) 0x40000006) ///< The handle points to the PUBEK, only usable with TPM_OwnerReadInternalPub // // Part 2, section 4.5: TPM_STARTUP_TYPE // #define TPM_ST_CLEAR ((TPM_STARTUP_TYPE) 0x0001) ///< The TPM is starting up from a clean state #define TPM_ST_STATE ((TPM_STARTUP_TYPE) 0x0002) ///< The TPM is starting up from a saved state #define TPM_ST_DEACTIVATED ((TPM_STARTUP_TYPE) 0x0003) ///< The TPM is to startup and set the deactivated flag to TRUE // // Part 2, section 4.6: TPM_STATUP_EFFECTS // The table makeup is still an open issue. // // // Part 2, section 4.7: TPM_PROTOCOL_ID // #define TPM_PID_OIAP ((TPM_PROTOCOL_ID) 0x0001) ///< The OIAP protocol. #define TPM_PID_OSAP ((TPM_PROTOCOL_ID) 0x0002) ///< The OSAP protocol. #define TPM_PID_ADIP ((TPM_PROTOCOL_ID) 0x0003) ///< The ADIP protocol. #define TPM_PID_ADCP ((TPM_PROTOCOL_ID) 0x0004) ///< The ADCP protocol. #define TPM_PID_OWNER ((TPM_PROTOCOL_ID) 0x0005) ///< The protocol for taking ownership of a TPM. #define TPM_PID_DSAP ((TPM_PROTOCOL_ID) 0x0006) ///< The DSAP protocol #define TPM_PID_TRANSPORT ((TPM_PROTOCOL_ID) 0x0007) ///< The transport protocol // // Part 2, section 4.8: TPM_ALGORITHM_ID // The TPM MUST support the algorithms TPM_ALG_RSA, TPM_ALG_SHA, TPM_ALG_HMAC, // TPM_ALG_MGF1 // #define TPM_ALG_RSA ((TPM_ALGORITHM_ID) 0x00000001) ///< The RSA algorithm. #define TPM_ALG_DES ((TPM_ALGORITHM_ID) 0x00000002) ///< The DES algorithm #define TPM_ALG_3DES ((TPM_ALGORITHM_ID) 0x00000003) ///< The 3DES algorithm in EDE mode #define TPM_ALG_SHA ((TPM_ALGORITHM_ID) 0x00000004) ///< The SHA1 algorithm #define TPM_ALG_HMAC ((TPM_ALGORITHM_ID) 0x00000005) ///< The RFC 2104 HMAC algorithm #define TPM_ALG_AES128 ((TPM_ALGORITHM_ID) 0x00000006) ///< The AES algorithm, key size 128 #define TPM_ALG_MGF1 ((TPM_ALGORITHM_ID) 0x00000007) ///< The XOR algorithm using MGF1 to create a string the size of the encrypted block #define TPM_ALG_AES192 ((TPM_ALGORITHM_ID) 0x00000008) ///< AES, key size 192 #define TPM_ALG_AES256 ((TPM_ALGORITHM_ID) 0x00000009) ///< AES, key size 256 #define TPM_ALG_XOR ((TPM_ALGORITHM_ID) 0x0000000A) ///< XOR using the rolling nonces // // Part 2, section 4.9: TPM_PHYSICAL_PRESENCE // #define TPM_PHYSICAL_PRESENCE_HW_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0200) ///< Sets the physicalPresenceHWEnable to FALSE #define TPM_PHYSICAL_PRESENCE_CMD_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0100) ///< Sets the physicalPresenceCMDEnable to FALSE #define TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0080) ///< Sets the physicalPresenceLifetimeLock to TRUE #define TPM_PHYSICAL_PRESENCE_HW_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0040) ///< Sets the physicalPresenceHWEnable to TRUE #define TPM_PHYSICAL_PRESENCE_CMD_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0020) ///< Sets the physicalPresenceCMDEnable to TRUE #define TPM_PHYSICAL_PRESENCE_NOTPRESENT ((TPM_PHYSICAL_PRESENCE) 0x0010) ///< Sets PhysicalPresence = FALSE #define TPM_PHYSICAL_PRESENCE_PRESENT ((TPM_PHYSICAL_PRESENCE) 0x0008) ///< Sets PhysicalPresence = TRUE #define TPM_PHYSICAL_PRESENCE_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0004) ///< Sets PhysicalPresenceLock = TRUE // // Part 2, section 4.10: TPM_MIGRATE_SCHEME // #define TPM_MS_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0001) ///< A public key that can be used with all TPM migration commands other than 'ReWrap' mode. #define TPM_MS_REWRAP ((TPM_MIGRATE_SCHEME) 0x0002) ///< A public key that can be used for the ReWrap mode of TPM_CreateMigrationBlob. #define TPM_MS_MAINT ((TPM_MIGRATE_SCHEME) 0x0003) ///< A public key that can be used for the Maintenance commands #define TPM_MS_RESTRICT_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0004) ///< The key is to be migrated to a Migration Authority. #define TPM_MS_RESTRICT_APPROVE_DOUBLE ((TPM_MIGRATE_SCHEME) 0x0005) ///< The key is to be migrated to an entity approved by a Migration Authority using double wrapping // // Part 2, section 4.11: TPM_EK_TYPE // #define TPM_EK_TYPE_ACTIVATE ((TPM_EK_TYPE) 0x0001) ///< The blob MUST be TPM_EK_BLOB_ACTIVATE #define TPM_EK_TYPE_AUTH ((TPM_EK_TYPE) 0x0002) ///< The blob MUST be TPM_EK_BLOB_AUTH // // Part 2, section 4.12: TPM_PLATFORM_SPECIFIC // #define TPM_PS_PC_11 ((TPM_PLATFORM_SPECIFIC) 0x0001) ///< PC Specific version 1.1 #define TPM_PS_PC_12 ((TPM_PLATFORM_SPECIFIC) 0x0002) ///< PC Specific version 1.2 #define TPM_PS_PDA_12 ((TPM_PLATFORM_SPECIFIC) 0x0003) ///< PDA Specific version 1.2 #define TPM_PS_Server_12 ((TPM_PLATFORM_SPECIFIC) 0x0004) ///< Server Specific version 1.2 #define TPM_PS_Mobile_12 ((TPM_PLATFORM_SPECIFIC) 0x0005) ///< Mobil Specific version 1.2 // // Part 2, section 5: Basic Structures // /// /// Part 2, section 5.1: TPM_STRUCT_VER /// typedef struct tdTPM_STRUCT_VER { UINT8 major; UINT8 minor; UINT8 revMajor; UINT8 revMinor; } TPM_STRUCT_VER; /// /// Part 2, section 5.3: TPM_VERSION /// typedef struct tdTPM_VERSION { TPM_VERSION_BYTE major; TPM_VERSION_BYTE minor; UINT8 revMajor; UINT8 revMinor; } TPM_VERSION; #define TPM_SHA1_160_HASH_LEN 0x14 #define TPM_SHA1BASED_NONCE_LEN TPM_SHA1_160_HASH_LEN /// /// Part 2, section 5.4: TPM_DIGEST /// typedef struct tdTPM_DIGEST { UINT8 digest[TPM_SHA1_160_HASH_LEN]; } TPM_DIGEST; /// /// This SHALL be the digest of the chosen identityLabel and privacyCA for a new TPM identity /// typedef TPM_DIGEST TPM_CHOSENID_HASH; /// /// This SHALL be the hash of a list of PCR indexes and PCR values that a key or data is bound to /// typedef TPM_DIGEST TPM_COMPOSITE_HASH; /// /// This SHALL be the value of a DIR register /// typedef TPM_DIGEST TPM_DIRVALUE; typedef TPM_DIGEST TPM_HMAC; /// /// The value inside of the PCR /// typedef TPM_DIGEST TPM_PCRVALUE; /// /// This SHALL be the value of the current internal audit state /// typedef TPM_DIGEST TPM_AUDITDIGEST; /// /// Part 2, section 5.5: TPM_NONCE /// typedef struct tdTPM_NONCE { UINT8 nonce[20]; } TPM_NONCE; /// /// This SHALL be a random value generated by a TPM immediately after the EK is installed /// in that TPM, whenever an EK is installed in that TPM /// typedef TPM_NONCE TPM_DAA_TPM_SEED; /// /// This SHALL be a random value /// typedef TPM_NONCE TPM_DAA_CONTEXT_SEED; // // Part 2, section 5.6: TPM_AUTHDATA // /// /// The AuthData data is the information that is saved or passed to provide proof of ownership /// 296 of an entity /// typedef UINT8 tdTPM_AUTHDATA[20]; typedef tdTPM_AUTHDATA TPM_AUTHDATA; /// /// A secret plaintext value used in the authorization process /// typedef TPM_AUTHDATA TPM_SECRET; /// /// A ciphertext (encrypted) version of AuthData data. The encryption mechanism depends on the context /// typedef TPM_AUTHDATA TPM_ENCAUTH; /// /// Part 2, section 5.7: TPM_KEY_HANDLE_LIST /// Size of handle is loaded * sizeof(TPM_KEY_HANDLE) /// typedef struct tdTPM_KEY_HANDLE_LIST { UINT16 loaded; TPM_KEY_HANDLE handle[1]; } TPM_KEY_HANDLE_LIST; // // Part 2, section 5.8: TPM_KEY_USAGE values // /// /// TPM_KEY_SIGNING SHALL indicate a signing key. The [private] key SHALL be /// used for signing operations, only. This means that it MUST be a leaf of the /// Protected Storage key hierarchy. /// #define TPM_KEY_SIGNING ((UINT16) 0x0010) /// /// TPM_KEY_STORAGE SHALL indicate a storage key. The key SHALL be used to wrap /// and unwrap other keys in the Protected Storage hierarchy /// #define TPM_KEY_STORAGE ((UINT16) 0x0011) /// /// TPM_KEY_IDENTITY SHALL indicate an identity key. The key SHALL be used for /// operations that require a TPM identity, only. /// #define TPM_KEY_IDENTITY ((UINT16) 0x0012) /// /// TPM_KEY_AUTHCHANGE SHALL indicate an ephemeral key that is in use during /// the ChangeAuthAsym process, only. /// #define TPM_KEY_AUTHCHANGE ((UINT16) 0x0013) /// /// TPM_KEY_BIND SHALL indicate a key that can be used for TPM_Bind and /// TPM_Unbind operations only. /// #define TPM_KEY_BIND ((UINT16) 0x0014) /// /// TPM_KEY_LEGACY SHALL indicate a key that can perform signing and binding /// operations. The key MAY be used for both signing and binding operations. /// The TPM_KEY_LEGACY key type is to allow for use by applications where both /// signing and encryption operations occur with the same key. The use of this /// key type is not recommended TPM_KEY_MIGRATE 0x0016 This SHALL indicate a /// key in use for TPM_MigrateKey /// #define TPM_KEY_LEGACY ((UINT16) 0x0015) /// /// TPM_KEY_MIGRAGE SHALL indicate a key in use for TPM_MigrateKey /// #define TPM_KEY_MIGRATE ((UINT16) 0x0016) // // Part 2, section 5.8.1: Mandatory Key Usage Schemes // #define TPM_ES_NONE ((TPM_ENC_SCHEME) 0x0001) #define TPM_ES_RSAESPKCSv15 ((TPM_ENC_SCHEME) 0x0002) #define TPM_ES_RSAESOAEP_SHA1_MGF1 ((TPM_ENC_SCHEME) 0x0003) #define TPM_ES_SYM_CNT ((TPM_ENC_SCHEME) 0x0004) ///< rev94 defined #define TPM_ES_SYM_CTR ((TPM_ENC_SCHEME) 0x0004) #define TPM_ES_SYM_OFB ((TPM_ENC_SCHEME) 0x0005) #define TPM_SS_NONE ((TPM_SIG_SCHEME) 0x0001) #define TPM_SS_RSASSAPKCS1v15_SHA1 ((TPM_SIG_SCHEME) 0x0002) #define TPM_SS_RSASSAPKCS1v15_DER ((TPM_SIG_SCHEME) 0x0003) #define TPM_SS_RSASSAPKCS1v15_INFO ((TPM_SIG_SCHEME) 0x0004) // // Part 2, section 5.9: TPM_AUTH_DATA_USAGE values // #define TPM_AUTH_NEVER ((TPM_AUTH_DATA_USAGE) 0x00) #define TPM_AUTH_ALWAYS ((TPM_AUTH_DATA_USAGE) 0x01) #define TPM_AUTH_PRIV_USE_ONLY ((TPM_AUTH_DATA_USAGE) 0x03) /// /// Part 2, section 5.10: TPM_KEY_FLAGS /// typedef enum tdTPM_KEY_FLAGS { redirection = 0x00000001, migratable = 0x00000002, isVolatile = 0x00000004, pcrIgnoredOnRead = 0x00000008, migrateAuthority = 0x00000010 } TPM_KEY_FLAGS_BITS; /// /// Part 2, section 5.11: TPM_CHANGEAUTH_VALIDATE /// typedef struct tdTPM_CHANGEAUTH_VALIDATE { TPM_SECRET newAuthSecret; TPM_NONCE n1; } TPM_CHANGEAUTH_VALIDATE; /// /// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH /// declared after section 10 to catch declaration of TPM_PUBKEY /// /// Part 2 section 10.1: TPM_KEY_PARMS /// [size_is(parmSize)] BYTE* parms; /// typedef struct tdTPM_KEY_PARMS { TPM_ALGORITHM_ID algorithmID; TPM_ENC_SCHEME encScheme; TPM_SIG_SCHEME sigScheme; UINT32 parmSize; UINT8 *parms; } TPM_KEY_PARMS; /// /// Part 2, section 10.4: TPM_STORE_PUBKEY /// typedef struct tdTPM_STORE_PUBKEY { UINT32 keyLength; UINT8 key[1]; } TPM_STORE_PUBKEY; /// /// Part 2, section 10.5: TPM_PUBKEY /// typedef struct tdTPM_PUBKEY { TPM_KEY_PARMS algorithmParms; TPM_STORE_PUBKEY pubKey; } TPM_PUBKEY; /// /// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH /// typedef struct tdTPM_MIGRATIONKEYAUTH { TPM_PUBKEY migrationKey; TPM_MIGRATE_SCHEME migrationScheme; TPM_DIGEST digest; } TPM_MIGRATIONKEYAUTH; /// /// Part 2, section 5.13: TPM_COUNTER_VALUE /// typedef struct tdTPM_COUNTER_VALUE { TPM_STRUCTURE_TAG tag; UINT8 label[4]; TPM_ACTUAL_COUNT counter; } TPM_COUNTER_VALUE; /// /// Part 2, section 5.14: TPM_SIGN_INFO /// Size of data indicated by dataLen /// typedef struct tdTPM_SIGN_INFO { TPM_STRUCTURE_TAG tag; UINT8 fixed[4]; TPM_NONCE replay; UINT32 dataLen; UINT8 *data; } TPM_SIGN_INFO; /// /// Part 2, section 5.15: TPM_MSA_COMPOSITE /// Number of migAuthDigest indicated by MSAlist /// typedef struct tdTPM_MSA_COMPOSITE { UINT32 MSAlist; TPM_DIGEST migAuthDigest[1]; } TPM_MSA_COMPOSITE; /// /// Part 2, section 5.16: TPM_CMK_AUTH /// typedef struct tdTPM_CMK_AUTH { TPM_DIGEST migrationAuthorityDigest; TPM_DIGEST destinationKeyDigest; TPM_DIGEST sourceKeyDigest; } TPM_CMK_AUTH; // // Part 2, section 5.17: TPM_CMK_DELEGATE // #define TPM_CMK_DELEGATE_SIGNING ((TPM_CMK_DELEGATE) BIT31) #define TPM_CMK_DELEGATE_STORAGE ((TPM_CMK_DELEGATE) BIT30) #define TPM_CMK_DELEGATE_BIND ((TPM_CMK_DELEGATE) BIT29) #define TPM_CMK_DELEGATE_LEGACY ((TPM_CMK_DELEGATE) BIT28) #define TPM_CMK_DELEGATE_MIGRATE ((TPM_CMK_DELEGATE) BIT27) /// /// Part 2, section 5.18: TPM_SELECT_SIZE /// typedef struct tdTPM_SELECT_SIZE { UINT8 major; UINT8 minor; UINT16 reqSize; } TPM_SELECT_SIZE; /// /// Part 2, section 5,19: TPM_CMK_MIGAUTH /// typedef struct tdTPM_CMK_MIGAUTH { TPM_STRUCTURE_TAG tag; TPM_DIGEST msaDigest; TPM_DIGEST pubKeyDigest; } TPM_CMK_MIGAUTH; /// /// Part 2, section 5.20: TPM_CMK_SIGTICKET /// typedef struct tdTPM_CMK_SIGTICKET { TPM_STRUCTURE_TAG tag; TPM_DIGEST verKeyDigest; TPM_DIGEST signedData; } TPM_CMK_SIGTICKET; /// /// Part 2, section 5.21: TPM_CMK_MA_APPROVAL /// typedef struct tdTPM_CMK_MA_APPROVAL { TPM_STRUCTURE_TAG tag; TPM_DIGEST migrationAuthorityDigest; } TPM_CMK_MA_APPROVAL; // // Part 2, section 6: Command Tags // #define TPM_TAG_RQU_COMMAND ((TPM_STRUCTURE_TAG) 0x00C1) #define TPM_TAG_RQU_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C2) #define TPM_TAG_RQU_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C3) #define TPM_TAG_RSP_COMMAND ((TPM_STRUCTURE_TAG) 0x00C4) #define TPM_TAG_RSP_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C5) #define TPM_TAG_RSP_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C6) /// /// Part 2, section 7.1: TPM_PERMANENT_FLAGS /// typedef struct tdTPM_PERMANENT_FLAGS { TPM_STRUCTURE_TAG tag; BOOLEAN disable; BOOLEAN ownership; BOOLEAN deactivated; BOOLEAN readPubek; BOOLEAN disableOwnerClear; BOOLEAN allowMaintenance; BOOLEAN physicalPresenceLifetimeLock; BOOLEAN physicalPresenceHWEnable; BOOLEAN physicalPresenceCMDEnable; BOOLEAN CEKPUsed; BOOLEAN TPMpost; BOOLEAN TPMpostLock; BOOLEAN FIPS; BOOLEAN operator; BOOLEAN enableRevokeEK; BOOLEAN nvLocked; BOOLEAN readSRKPub; BOOLEAN tpmEstablished; BOOLEAN maintenanceDone; BOOLEAN disableFullDALogicInfo; } TPM_PERMANENT_FLAGS; // // Part 2, section 7.1.1: Flag Restrictions (of TPM_PERMANENT_FLAGS) // #define TPM_PF_DISABLE ((TPM_CAPABILITY_AREA) 1) #define TPM_PF_OWNERSHIP ((TPM_CAPABILITY_AREA) 2) #define TPM_PF_DEACTIVATED ((TPM_CAPABILITY_AREA) 3) #define TPM_PF_READPUBEK ((TPM_CAPABILITY_AREA) 4) #define TPM_PF_DISABLEOWNERCLEAR ((TPM_CAPABILITY_AREA) 5) #define TPM_PF_ALLOWMAINTENANCE ((TPM_CAPABILITY_AREA) 6) #define TPM_PF_PHYSICALPRESENCELIFETIMELOCK ((TPM_CAPABILITY_AREA) 7) #define TPM_PF_PHYSICALPRESENCEHWENABLE ((TPM_CAPABILITY_AREA) 8) #define TPM_PF_PHYSICALPRESENCECMDENABLE ((TPM_CAPABILITY_AREA) 9) #define TPM_PF_CEKPUSED ((TPM_CAPABILITY_AREA) 10) #define TPM_PF_TPMPOST ((TPM_CAPABILITY_AREA) 11) #define TPM_PF_TPMPOSTLOCK ((TPM_CAPABILITY_AREA) 12) #define TPM_PF_FIPS ((TPM_CAPABILITY_AREA) 13) #define TPM_PF_OPERATOR ((TPM_CAPABILITY_AREA) 14) #define TPM_PF_ENABLEREVOKEEK ((TPM_CAPABILITY_AREA) 15) #define TPM_PF_NV_LOCKED ((TPM_CAPABILITY_AREA) 16) #define TPM_PF_READSRKPUB ((TPM_CAPABILITY_AREA) 17) #define TPM_PF_TPMESTABLISHED ((TPM_CAPABILITY_AREA) 18) #define TPM_PF_MAINTENANCEDONE ((TPM_CAPABILITY_AREA) 19) #define TPM_PF_DISABLEFULLDALOGICINFO ((TPM_CAPABILITY_AREA) 20) /// /// Part 2, section 7.2: TPM_STCLEAR_FLAGS /// typedef struct tdTPM_STCLEAR_FLAGS { TPM_STRUCTURE_TAG tag; BOOLEAN deactivated; BOOLEAN disableForceClear; BOOLEAN physicalPresence; BOOLEAN physicalPresenceLock; BOOLEAN bGlobalLock; } TPM_STCLEAR_FLAGS; // // Part 2, section 7.2.1: Flag Restrictions (of TPM_STCLEAR_FLAGS) // #define TPM_SF_DEACTIVATED ((TPM_CAPABILITY_AREA) 1) #define TPM_SF_DISABLEFORCECLEAR ((TPM_CAPABILITY_AREA) 2) #define TPM_SF_PHYSICALPRESENCE ((TPM_CAPABILITY_AREA) 3) #define TPM_SF_PHYSICALPRESENCELOCK ((TPM_CAPABILITY_AREA) 4) #define TPM_SF_BGLOBALLOCK ((TPM_CAPABILITY_AREA) 5) /// /// Part 2, section 7.3: TPM_STANY_FLAGS /// typedef struct tdTPM_STANY_FLAGS { TPM_STRUCTURE_TAG tag; BOOLEAN postInitialise; TPM_MODIFIER_INDICATOR localityModifier; BOOLEAN transportExclusive; BOOLEAN TOSPresent; } TPM_STANY_FLAGS; // // Part 2, section 7.3.1: Flag Restrictions (of TPM_STANY_FLAGS) // #define TPM_AF_POSTINITIALISE ((TPM_CAPABILITY_AREA) 1) #define TPM_AF_LOCALITYMODIFIER ((TPM_CAPABILITY_AREA) 2) #define TPM_AF_TRANSPORTEXCLUSIVE ((TPM_CAPABILITY_AREA) 3) #define TPM_AF_TOSPRESENT ((TPM_CAPABILITY_AREA) 4) // // All those structures defined in section 7.4, 7.5, 7.6 are not normative and // thus no definitions here // // Part 2, section 7.4: TPM_PERMANENT_DATA // #define TPM_MIN_COUNTERS 4 ///< the minimum number of counters is 4 #define TPM_DELEGATE_KEY TPM_KEY #define TPM_NUM_PCR 16 #define TPM_MAX_NV_WRITE_NOOWNER 64 // // Part 2, section 7.4.1: PERMANENT_DATA Subcap for SetCapability // #define TPM_PD_REVMAJOR ((TPM_CAPABILITY_AREA) 1) #define TPM_PD_REVMINOR ((TPM_CAPABILITY_AREA) 2) #define TPM_PD_TPMPROOF ((TPM_CAPABILITY_AREA) 3) #define TPM_PD_OWNERAUTH ((TPM_CAPABILITY_AREA) 4) #define TPM_PD_OPERATORAUTH ((TPM_CAPABILITY_AREA) 5) #define TPM_PD_MANUMAINTPUB ((TPM_CAPABILITY_AREA) 6) #define TPM_PD_ENDORSEMENTKEY ((TPM_CAPABILITY_AREA) 7) #define TPM_PD_SRK ((TPM_CAPABILITY_AREA) 8) #define TPM_PD_DELEGATEKEY ((TPM_CAPABILITY_AREA) 9) #define TPM_PD_CONTEXTKEY ((TPM_CAPABILITY_AREA) 10) #define TPM_PD_AUDITMONOTONICCOUNTER ((TPM_CAPABILITY_AREA) 11) #define TPM_PD_MONOTONICCOUNTER ((TPM_CAPABILITY_AREA) 12) #define TPM_PD_PCRATTRIB ((TPM_CAPABILITY_AREA) 13) #define TPM_PD_ORDINALAUDITSTATUS ((TPM_CAPABILITY_AREA) 14) #define TPM_PD_AUTHDIR ((TPM_CAPABILITY_AREA) 15) #define TPM_PD_RNGSTATE ((TPM_CAPABILITY_AREA) 16) #define TPM_PD_FAMILYTABLE ((TPM_CAPABILITY_AREA) 17) #define TPM_DELEGATETABLE ((TPM_CAPABILITY_AREA) 18) #define TPM_PD_EKRESET ((TPM_CAPABILITY_AREA) 19) #define TPM_PD_MAXNVBUFSIZE ((TPM_CAPABILITY_AREA) 20) #define TPM_PD_LASTFAMILYID ((TPM_CAPABILITY_AREA) 21) #define TPM_PD_NOOWNERNVWRITE ((TPM_CAPABILITY_AREA) 22) #define TPM_PD_RESTRICTDELEGATE ((TPM_CAPABILITY_AREA) 23) #define TPM_PD_TPMDAASEED ((TPM_CAPABILITY_AREA) 24) #define TPM_PD_DAAPROOF ((TPM_CAPABILITY_AREA) 25) /// /// Part 2, section 7.5: TPM_STCLEAR_DATA /// available inside TPM only /// typedef struct tdTPM_STCLEAR_DATA { TPM_STRUCTURE_TAG tag; TPM_NONCE contextNonceKey; TPM_COUNT_ID countID; UINT32 ownerReference; BOOLEAN disableResetLock; TPM_PCRVALUE PCR[TPM_NUM_PCR]; UINT32 deferredPhysicalPresence; } TPM_STCLEAR_DATA; // // Part 2, section 7.5.1: STCLEAR_DATA Subcap for SetCapability // #define TPM_SD_CONTEXTNONCEKEY ((TPM_CAPABILITY_AREA)0x00000001) #define TPM_SD_COUNTID ((TPM_CAPABILITY_AREA)0x00000002) #define TPM_SD_OWNERREFERENCE ((TPM_CAPABILITY_AREA)0x00000003) #define TPM_SD_DISABLERESETLOCK ((TPM_CAPABILITY_AREA)0x00000004) #define TPM_SD_PCR ((TPM_CAPABILITY_AREA)0x00000005) #define TPM_SD_DEFERREDPHYSICALPRESENCE ((TPM_CAPABILITY_AREA)0x00000006) // // Part 2, section 7.6.1: STANY_DATA Subcap for SetCapability // #define TPM_AD_CONTEXTNONCESESSION ((TPM_CAPABILITY_AREA) 1) #define TPM_AD_AUDITDIGEST ((TPM_CAPABILITY_AREA) 2) #define TPM_AD_CURRENTTICKS ((TPM_CAPABILITY_AREA) 3) #define TPM_AD_CONTEXTCOUNT ((TPM_CAPABILITY_AREA) 4) #define TPM_AD_CONTEXTLIST ((TPM_CAPABILITY_AREA) 5) #define TPM_AD_SESSIONS ((TPM_CAPABILITY_AREA) 6) // // Part 2, section 8: PCR Structures // /// /// Part 2, section 8.1: TPM_PCR_SELECTION /// Size of pcrSelect[] indicated by sizeOfSelect /// typedef struct tdTPM_PCR_SELECTION { UINT16 sizeOfSelect; UINT8 pcrSelect[1]; } TPM_PCR_SELECTION; /// /// Part 2, section 8.2: TPM_PCR_COMPOSITE /// Size of pcrValue[] indicated by valueSize /// typedef struct tdTPM_PCR_COMPOSITE { TPM_PCR_SELECTION select; UINT32 valueSize; TPM_PCRVALUE pcrValue[1]; } TPM_PCR_COMPOSITE; /// /// Part 2, section 8.3: TPM_PCR_INFO /// typedef struct tdTPM_PCR_INFO { TPM_PCR_SELECTION pcrSelection; TPM_COMPOSITE_HASH digestAtRelease; TPM_COMPOSITE_HASH digestAtCreation; } TPM_PCR_INFO; /// /// Part 2, section 8.6: TPM_LOCALITY_SELECTION /// typedef UINT8 TPM_LOCALITY_SELECTION; #define TPM_LOC_FOUR ((UINT8) 0x10) #define TPM_LOC_THREE ((UINT8) 0x08) #define TPM_LOC_TWO ((UINT8) 0x04) #define TPM_LOC_ONE ((UINT8) 0x02) #define TPM_LOC_ZERO ((UINT8) 0x01) /// /// Part 2, section 8.4: TPM_PCR_INFO_LONG /// typedef struct tdTPM_PCR_INFO_LONG { TPM_STRUCTURE_TAG tag; TPM_LOCALITY_SELECTION localityAtCreation; TPM_LOCALITY_SELECTION localityAtRelease; TPM_PCR_SELECTION creationPCRSelection; TPM_PCR_SELECTION releasePCRSelection; TPM_COMPOSITE_HASH digestAtCreation; TPM_COMPOSITE_HASH digestAtRelease; } TPM_PCR_INFO_LONG; /// /// Part 2, section 8.5: TPM_PCR_INFO_SHORT /// typedef struct tdTPM_PCR_INFO_SHORT { TPM_PCR_SELECTION pcrSelection; TPM_LOCALITY_SELECTION localityAtRelease; TPM_COMPOSITE_HASH digestAtRelease; } TPM_PCR_INFO_SHORT; /// /// Part 2, section 8.8: TPM_PCR_ATTRIBUTES /// typedef struct tdTPM_PCR_ATTRIBUTES { BOOLEAN pcrReset; TPM_LOCALITY_SELECTION pcrExtendLocal; TPM_LOCALITY_SELECTION pcrResetLocal; } TPM_PCR_ATTRIBUTES; // // Part 2, section 9: Storage Structures // /// /// Part 2, section 9.1: TPM_STORED_DATA /// [size_is(sealInfoSize)] BYTE* sealInfo; /// [size_is(encDataSize)] BYTE* encData; /// typedef struct tdTPM_STORED_DATA { TPM_STRUCT_VER ver; UINT32 sealInfoSize; UINT8 *sealInfo; UINT32 encDataSize; UINT8 *encData; } TPM_STORED_DATA; /// /// Part 2, section 9.2: TPM_STORED_DATA12 /// [size_is(sealInfoSize)] BYTE* sealInfo; /// [size_is(encDataSize)] BYTE* encData; /// typedef struct tdTPM_STORED_DATA12 { TPM_STRUCTURE_TAG tag; TPM_ENTITY_TYPE et; UINT32 sealInfoSize; UINT8 *sealInfo; UINT32 encDataSize; UINT8 *encData; } TPM_STORED_DATA12; /// /// Part 2, section 9.3: TPM_SEALED_DATA /// [size_is(dataSize)] BYTE* data; /// typedef struct tdTPM_SEALED_DATA { TPM_PAYLOAD_TYPE payload; TPM_SECRET authData; TPM_NONCE tpmProof; TPM_DIGEST storedDigest; UINT32 dataSize; UINT8 *data; } TPM_SEALED_DATA; /// /// Part 2, section 9.4: TPM_SYMMETRIC_KEY /// [size_is(size)] BYTE* data; /// typedef struct tdTPM_SYMMETRIC_KEY { TPM_ALGORITHM_ID algId; TPM_ENC_SCHEME encScheme; UINT16 dataSize; UINT8 *data; } TPM_SYMMETRIC_KEY; /// /// Part 2, section 9.5: TPM_BOUND_DATA /// typedef struct tdTPM_BOUND_DATA { TPM_STRUCT_VER ver; TPM_PAYLOAD_TYPE payload; UINT8 payloadData[1]; } TPM_BOUND_DATA; // // Part 2 section 10: TPM_KEY complex // // // Section 10.1, 10.4, and 10.5 have been defined previously // /// /// Part 2, section 10.2: TPM_KEY /// [size_is(encDataSize)] BYTE* encData; /// typedef struct tdTPM_KEY { TPM_STRUCT_VER ver; TPM_KEY_USAGE keyUsage; TPM_KEY_FLAGS keyFlags; TPM_AUTH_DATA_USAGE authDataUsage; TPM_KEY_PARMS algorithmParms; UINT32 PCRInfoSize; UINT8 *PCRInfo; TPM_STORE_PUBKEY pubKey; UINT32 encDataSize; UINT8 *encData; } TPM_KEY; /// /// Part 2, section 10.3: TPM_KEY12 /// [size_is(encDataSize)] BYTE* encData; /// typedef struct tdTPM_KEY12 { TPM_STRUCTURE_TAG tag; UINT16 fill; TPM_KEY_USAGE keyUsage; TPM_KEY_FLAGS keyFlags; TPM_AUTH_DATA_USAGE authDataUsage; TPM_KEY_PARMS algorithmParms; UINT32 PCRInfoSize; UINT8 *PCRInfo; TPM_STORE_PUBKEY pubKey; UINT32 encDataSize; UINT8 *encData; } TPM_KEY12; /// /// Part 2, section 10.7: TPM_STORE_PRIVKEY /// [size_is(keyLength)] BYTE* key; /// typedef struct tdTPM_STORE_PRIVKEY { UINT32 keyLength; UINT8 *key; } TPM_STORE_PRIVKEY; /// /// Part 2, section 10.6: TPM_STORE_ASYMKEY /// typedef struct tdTPM_STORE_ASYMKEY { // pos len total TPM_PAYLOAD_TYPE payload; // 0 1 1 TPM_SECRET usageAuth; // 1 20 21 TPM_SECRET migrationAuth; // 21 20 41 TPM_DIGEST pubDataDigest; // 41 20 61 TPM_STORE_PRIVKEY privKey; // 61 132-151 193-214 } TPM_STORE_ASYMKEY; /// /// Part 2, section 10.8: TPM_MIGRATE_ASYMKEY /// [size_is(partPrivKeyLen)] BYTE* partPrivKey; /// typedef struct tdTPM_MIGRATE_ASYMKEY { // pos len total TPM_PAYLOAD_TYPE payload; // 0 1 1 TPM_SECRET usageAuth; // 1 20 21 TPM_DIGEST pubDataDigest; // 21 20 41 UINT32 partPrivKeyLen; // 41 4 45 UINT8 *partPrivKey; // 45 112-127 157-172 } TPM_MIGRATE_ASYMKEY; /// /// Part 2, section 10.9: TPM_KEY_CONTROL /// #define TPM_KEY_CONTROL_OWNER_EVICT ((UINT32) 0x00000001) // // Part 2, section 11: Signed Structures // /// /// Part 2, section 11.1: TPM_CERTIFY_INFO Structure /// typedef struct tdTPM_CERTIFY_INFO { TPM_STRUCT_VER version; TPM_KEY_USAGE keyUsage; TPM_KEY_FLAGS keyFlags; TPM_AUTH_DATA_USAGE authDataUsage; TPM_KEY_PARMS algorithmParms; TPM_DIGEST pubkeyDigest; TPM_NONCE data; BOOLEAN parentPCRStatus; UINT32 PCRInfoSize; UINT8 *PCRInfo; } TPM_CERTIFY_INFO; /// /// Part 2, section 11.2: TPM_CERTIFY_INFO2 Structure /// typedef struct tdTPM_CERTIFY_INFO2 { TPM_STRUCTURE_TAG tag; UINT8 fill; TPM_PAYLOAD_TYPE payloadType; TPM_KEY_USAGE keyUsage; TPM_KEY_FLAGS keyFlags; TPM_AUTH_DATA_USAGE authDataUsage; TPM_KEY_PARMS algorithmParms; TPM_DIGEST pubkeyDigest; TPM_NONCE data; BOOLEAN parentPCRStatus; UINT32 PCRInfoSize; UINT8 *PCRInfo; UINT32 migrationAuthoritySize; UINT8 *migrationAuthority; } TPM_CERTIFY_INFO2; /// /// Part 2, section 11.3 TPM_QUOTE_INFO Structure /// typedef struct tdTPM_QUOTE_INFO { TPM_STRUCT_VER version; UINT8 fixed[4]; TPM_COMPOSITE_HASH digestValue; TPM_NONCE externalData; } TPM_QUOTE_INFO; /// /// Part 2, section 11.4 TPM_QUOTE_INFO2 Structure /// typedef struct tdTPM_QUOTE_INFO2 { TPM_STRUCTURE_TAG tag; UINT8 fixed[4]; TPM_NONCE externalData; TPM_PCR_INFO_SHORT infoShort; } TPM_QUOTE_INFO2; // // Part 2, section 12: Identity Structures // /// /// Part 2, section 12.1 TPM_EK_BLOB /// typedef struct tdTPM_EK_BLOB { TPM_STRUCTURE_TAG tag; TPM_EK_TYPE ekType; UINT32 blobSize; UINT8 *blob; } TPM_EK_BLOB; /// /// Part 2, section 12.2 TPM_EK_BLOB_ACTIVATE /// typedef struct tdTPM_EK_BLOB_ACTIVATE { TPM_STRUCTURE_TAG tag; TPM_SYMMETRIC_KEY sessionKey; TPM_DIGEST idDigest; TPM_PCR_INFO_SHORT pcrInfo; } TPM_EK_BLOB_ACTIVATE; /// /// Part 2, section 12.3 TPM_EK_BLOB_AUTH /// typedef struct tdTPM_EK_BLOB_AUTH { TPM_STRUCTURE_TAG tag; TPM_SECRET authValue; } TPM_EK_BLOB_AUTH; /// /// Part 2, section 12.5 TPM_IDENTITY_CONTENTS /// typedef struct tdTPM_IDENTITY_CONTENTS { TPM_STRUCT_VER ver; UINT32 ordinal; TPM_CHOSENID_HASH labelPrivCADigest; TPM_PUBKEY identityPubKey; } TPM_IDENTITY_CONTENTS; /// /// Part 2, section 12.6 TPM_IDENTITY_REQ /// typedef struct tdTPM_IDENTITY_REQ { UINT32 asymSize; UINT32 symSize; TPM_KEY_PARMS asymAlgorithm; TPM_KEY_PARMS symAlgorithm; UINT8 *asymBlob; UINT8 *symBlob; } TPM_IDENTITY_REQ; /// /// Part 2, section 12.7 TPM_IDENTITY_PROOF /// typedef struct tdTPM_IDENTITY_PROOF { TPM_STRUCT_VER ver; UINT32 labelSize; UINT32 identityBindingSize; UINT32 endorsementSize; UINT32 platformSize; UINT32 conformanceSize; TPM_PUBKEY identityKey; UINT8 *labelArea; UINT8 *identityBinding; UINT8 *endorsementCredential; UINT8 *platformCredential; UINT8 *conformanceCredential; } TPM_IDENTITY_PROOF; /// /// Part 2, section 12.8 TPM_ASYM_CA_CONTENTS /// typedef struct tdTPM_ASYM_CA_CONTENTS { TPM_SYMMETRIC_KEY sessionKey; TPM_DIGEST idDigest; } TPM_ASYM_CA_CONTENTS; /// /// Part 2, section 12.9 TPM_SYM_CA_ATTESTATION /// typedef struct tdTPM_SYM_CA_ATTESTATION { UINT32 credSize; TPM_KEY_PARMS algorithm; UINT8 *credential; } TPM_SYM_CA_ATTESTATION; /// /// Part 2, section 15: Tick Structures /// Placed here out of order because definitions are used in section 13. /// typedef struct tdTPM_CURRENT_TICKS { TPM_STRUCTURE_TAG tag; UINT64 currentTicks; UINT16 tickRate; TPM_NONCE tickNonce; } TPM_CURRENT_TICKS; /// /// Part 2, section 13: Transport structures /// /// /// Part 2, section 13.1: TPM _TRANSPORT_PUBLIC /// typedef struct tdTPM_TRANSPORT_PUBLIC { TPM_STRUCTURE_TAG tag; TPM_TRANSPORT_ATTRIBUTES transAttributes; TPM_ALGORITHM_ID algId; TPM_ENC_SCHEME encScheme; } TPM_TRANSPORT_PUBLIC; // // Part 2, section 13.1.1 TPM_TRANSPORT_ATTRIBUTES Definitions // #define TPM_TRANSPORT_ENCRYPT ((UINT32)BIT0) #define TPM_TRANSPORT_LOG ((UINT32)BIT1) #define TPM_TRANSPORT_EXCLUSIVE ((UINT32)BIT2) /// /// Part 2, section 13.2 TPM_TRANSPORT_INTERNAL /// typedef struct tdTPM_TRANSPORT_INTERNAL { TPM_STRUCTURE_TAG tag; TPM_AUTHDATA authData; TPM_TRANSPORT_PUBLIC transPublic; TPM_TRANSHANDLE transHandle; TPM_NONCE transNonceEven; TPM_DIGEST transDigest; } TPM_TRANSPORT_INTERNAL; /// /// Part 2, section 13.3 TPM_TRANSPORT_LOG_IN structure /// typedef struct tdTPM_TRANSPORT_LOG_IN { TPM_STRUCTURE_TAG tag; TPM_DIGEST parameters; TPM_DIGEST pubKeyHash; } TPM_TRANSPORT_LOG_IN; /// /// Part 2, section 13.4 TPM_TRANSPORT_LOG_OUT structure /// typedef struct tdTPM_TRANSPORT_LOG_OUT { TPM_STRUCTURE_TAG tag; TPM_CURRENT_TICKS currentTicks; TPM_DIGEST parameters; TPM_MODIFIER_INDICATOR locality; } TPM_TRANSPORT_LOG_OUT; /// /// Part 2, section 13.5 TPM_TRANSPORT_AUTH structure /// typedef struct tdTPM_TRANSPORT_AUTH { TPM_STRUCTURE_TAG tag; TPM_AUTHDATA authData; } TPM_TRANSPORT_AUTH; // // Part 2, section 14: Audit Structures // /// /// Part 2, section 14.1 TPM_AUDIT_EVENT_IN structure /// typedef struct tdTPM_AUDIT_EVENT_IN { TPM_STRUCTURE_TAG tag; TPM_DIGEST inputParms; TPM_COUNTER_VALUE auditCount; } TPM_AUDIT_EVENT_IN; /// /// Part 2, section 14.2 TPM_AUDIT_EVENT_OUT structure /// typedef struct tdTPM_AUDIT_EVENT_OUT { TPM_STRUCTURE_TAG tag; TPM_COMMAND_CODE ordinal; TPM_DIGEST outputParms; TPM_COUNTER_VALUE auditCount; TPM_RESULT returnCode; } TPM_AUDIT_EVENT_OUT; // // Part 2, section 16: Return Codes // #define TPM_VENDOR_ERROR TPM_Vendor_Specific32 #define TPM_NON_FATAL 0x00000800 #define TPM_SUCCESS ((TPM_RESULT) TPM_BASE) #define TPM_AUTHFAIL ((TPM_RESULT) (TPM_BASE + 1)) #define TPM_BADINDEX ((TPM_RESULT) (TPM_BASE + 2)) #define TPM_BAD_PARAMETER ((TPM_RESULT) (TPM_BASE + 3)) #define TPM_AUDITFAILURE ((TPM_RESULT) (TPM_BASE + 4)) #define TPM_CLEAR_DISABLED ((TPM_RESULT) (TPM_BASE + 5)) #define TPM_DEACTIVATED ((TPM_RESULT) (TPM_BASE + 6)) #define TPM_DISABLED ((TPM_RESULT) (TPM_BASE + 7)) #define TPM_DISABLED_CMD ((TPM_RESULT) (TPM_BASE + 8)) #define TPM_FAIL ((TPM_RESULT) (TPM_BASE + 9)) #define TPM_BAD_ORDINAL ((TPM_RESULT) (TPM_BASE + 10)) #define TPM_INSTALL_DISABLED ((TPM_RESULT) (TPM_BASE + 11)) #define TPM_INVALID_KEYHANDLE ((TPM_RESULT) (TPM_BASE + 12)) #define TPM_KEYNOTFOUND ((TPM_RESULT) (TPM_BASE + 13)) #define TPM_INAPPROPRIATE_ENC ((TPM_RESULT) (TPM_BASE + 14)) #define TPM_MIGRATEFAIL ((TPM_RESULT) (TPM_BASE + 15)) #define TPM_INVALID_PCR_INFO ((TPM_RESULT) (TPM_BASE + 16)) #define TPM_NOSPACE ((TPM_RESULT) (TPM_BASE + 17)) #define TPM_NOSRK ((TPM_RESULT) (TPM_BASE + 18)) #define TPM_NOTSEALED_BLOB ((TPM_RESULT) (TPM_BASE + 19)) #define TPM_OWNER_SET ((TPM_RESULT) (TPM_BASE + 20)) #define TPM_RESOURCES ((TPM_RESULT) (TPM_BASE + 21)) #define TPM_SHORTRANDOM ((TPM_RESULT) (TPM_BASE + 22)) #define TPM_SIZE ((TPM_RESULT) (TPM_BASE + 23)) #define TPM_WRONGPCRVAL ((TPM_RESULT) (TPM_BASE + 24)) #define TPM_BAD_PARAM_SIZE ((TPM_RESULT) (TPM_BASE + 25)) #define TPM_SHA_THREAD ((TPM_RESULT) (TPM_BASE + 26)) #define TPM_SHA_ERROR ((TPM_RESULT) (TPM_BASE + 27)) #define TPM_FAILEDSELFTEST ((TPM_RESULT) (TPM_BASE + 28)) #define TPM_AUTH2FAIL ((TPM_RESULT) (TPM_BASE + 29)) #define TPM_BADTAG ((TPM_RESULT) (TPM_BASE + 30)) #define TPM_IOERROR ((TPM_RESULT) (TPM_BASE + 31)) #define TPM_ENCRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 32)) #define TPM_DECRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 33)) #define TPM_INVALID_AUTHHANDLE ((TPM_RESULT) (TPM_BASE + 34)) #define TPM_NO_ENDORSEMENT ((TPM_RESULT) (TPM_BASE + 35)) #define TPM_INVALID_KEYUSAGE ((TPM_RESULT) (TPM_BASE + 36)) #define TPM_WRONG_ENTITYTYPE ((TPM_RESULT) (TPM_BASE + 37)) #define TPM_INVALID_POSTINIT ((TPM_RESULT) (TPM_BASE + 38)) #define TPM_INAPPROPRIATE_SIG ((TPM_RESULT) (TPM_BASE + 39)) #define TPM_BAD_KEY_PROPERTY ((TPM_RESULT) (TPM_BASE + 40)) #define TPM_BAD_MIGRATION ((TPM_RESULT) (TPM_BASE + 41)) #define TPM_BAD_SCHEME ((TPM_RESULT) (TPM_BASE + 42)) #define TPM_BAD_DATASIZE ((TPM_RESULT) (TPM_BASE + 43)) #define TPM_BAD_MODE ((TPM_RESULT) (TPM_BASE + 44)) #define TPM_BAD_PRESENCE ((TPM_RESULT) (TPM_BASE + 45)) #define TPM_BAD_VERSION ((TPM_RESULT) (TPM_BASE + 46)) #define TPM_NO_WRAP_TRANSPORT ((TPM_RESULT) (TPM_BASE + 47)) #define TPM_AUDITFAIL_UNSUCCESSFUL ((TPM_RESULT) (TPM_BASE + 48)) #define TPM_AUDITFAIL_SUCCESSFUL ((TPM_RESULT) (TPM_BASE + 49)) #define TPM_NOTRESETABLE ((TPM_RESULT) (TPM_BASE + 50)) #define TPM_NOTLOCAL ((TPM_RESULT) (TPM_BASE + 51)) #define TPM_BAD_TYPE ((TPM_RESULT) (TPM_BASE + 52)) #define TPM_INVALID_RESOURCE ((TPM_RESULT) (TPM_BASE + 53)) #define TPM_NOTFIPS ((TPM_RESULT) (TPM_BASE + 54)) #define TPM_INVALID_FAMILY ((TPM_RESULT) (TPM_BASE + 55)) #define TPM_NO_NV_PERMISSION ((TPM_RESULT) (TPM_BASE + 56)) #define TPM_REQUIRES_SIGN ((TPM_RESULT) (TPM_BASE + 57)) #define TPM_KEY_NOTSUPPORTED ((TPM_RESULT) (TPM_BASE + 58)) #define TPM_AUTH_CONFLICT ((TPM_RESULT) (TPM_BASE + 59)) #define TPM_AREA_LOCKED ((TPM_RESULT) (TPM_BASE + 60)) #define TPM_BAD_LOCALITY ((TPM_RESULT) (TPM_BASE + 61)) #define TPM_READ_ONLY ((TPM_RESULT) (TPM_BASE + 62)) #define TPM_PER_NOWRITE ((TPM_RESULT) (TPM_BASE + 63)) #define TPM_FAMILYCOUNT ((TPM_RESULT) (TPM_BASE + 64)) #define TPM_WRITE_LOCKED ((TPM_RESULT) (TPM_BASE + 65)) #define TPM_BAD_ATTRIBUTES ((TPM_RESULT) (TPM_BASE + 66)) #define TPM_INVALID_STRUCTURE ((TPM_RESULT) (TPM_BASE + 67)) #define TPM_KEY_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 68)) #define TPM_BAD_COUNTER ((TPM_RESULT) (TPM_BASE + 69)) #define TPM_NOT_FULLWRITE ((TPM_RESULT) (TPM_BASE + 70)) #define TPM_CONTEXT_GAP ((TPM_RESULT) (TPM_BASE + 71)) #define TPM_MAXNVWRITES ((TPM_RESULT) (TPM_BASE + 72)) #define TPM_NOOPERATOR ((TPM_RESULT) (TPM_BASE + 73)) #define TPM_RESOURCEMISSING ((TPM_RESULT) (TPM_BASE + 74)) #define TPM_DELEGATE_LOCK ((TPM_RESULT) (TPM_BASE + 75)) #define TPM_DELEGATE_FAMILY ((TPM_RESULT) (TPM_BASE + 76)) #define TPM_DELEGATE_ADMIN ((TPM_RESULT) (TPM_BASE + 77)) #define TPM_TRANSPORT_NOTEXCLUSIVE ((TPM_RESULT) (TPM_BASE + 78)) #define TPM_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 79)) #define TPM_DAA_RESOURCES ((TPM_RESULT) (TPM_BASE + 80)) #define TPM_DAA_INPUT_DATA0 ((TPM_RESULT) (TPM_BASE + 81)) #define TPM_DAA_INPUT_DATA1 ((TPM_RESULT) (TPM_BASE + 82)) #define TPM_DAA_ISSUER_SETTINGS ((TPM_RESULT) (TPM_BASE + 83)) #define TPM_DAA_TPM_SETTINGS ((TPM_RESULT) (TPM_BASE + 84)) #define TPM_DAA_STAGE ((TPM_RESULT) (TPM_BASE + 85)) #define TPM_DAA_ISSUER_VALIDITY ((TPM_RESULT) (TPM_BASE + 86)) #define TPM_DAA_WRONG_W ((TPM_RESULT) (TPM_BASE + 87)) #define TPM_BAD_HANDLE ((TPM_RESULT) (TPM_BASE + 88)) #define TPM_BAD_DELEGATE ((TPM_RESULT) (TPM_BASE + 89)) #define TPM_BADCONTEXT ((TPM_RESULT) (TPM_BASE + 90)) #define TPM_TOOMANYCONTEXTS ((TPM_RESULT) (TPM_BASE + 91)) #define TPM_MA_TICKET_SIGNATURE ((TPM_RESULT) (TPM_BASE + 92)) #define TPM_MA_DESTINATION ((TPM_RESULT) (TPM_BASE + 93)) #define TPM_MA_SOURCE ((TPM_RESULT) (TPM_BASE + 94)) #define TPM_MA_AUTHORITY ((TPM_RESULT) (TPM_BASE + 95)) #define TPM_PERMANENTEK ((TPM_RESULT) (TPM_BASE + 97)) #define TPM_BAD_SIGNATURE ((TPM_RESULT) (TPM_BASE + 98)) #define TPM_NOCONTEXTSPACE ((TPM_RESULT) (TPM_BASE + 99)) #define TPM_RETRY ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL)) #define TPM_NEEDS_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 1)) #define TPM_DOING_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 2)) #define TPM_DEFEND_LOCK_RUNNING ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 3)) // // Part 2, section 17: Ordinals // // Ordinals are 32 bit values. The upper byte contains values that serve as // flag indicators, the next byte contains values indicating what committee // designated the ordinal, and the final two bytes contain the Command // Ordinal Index. // 3 2 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // |P|C|V| Reserved| Purview | Command Ordinal Index | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // Where: // // * P is Protected/Unprotected command. When 0 the command is a Protected // command, when 1 the command is an Unprotected command. // // * C is Non-Connection/Connection related command. When 0 this command // passes through to either the protected (TPM) or unprotected (TSS) // components. // // * V is TPM/Vendor command. When 0 the command is TPM defined, when 1 the // command is vendor defined. // // * All reserved area bits are set to 0. // #define TPM_ORD_ActivateIdentity ((TPM_COMMAND_CODE) 0x0000007A) #define TPM_ORD_AuthorizeMigrationKey ((TPM_COMMAND_CODE) 0x0000002B) #define TPM_ORD_CertifyKey ((TPM_COMMAND_CODE) 0x00000032) #define TPM_ORD_CertifyKey2 ((TPM_COMMAND_CODE) 0x00000033) #define TPM_ORD_CertifySelfTest ((TPM_COMMAND_CODE) 0x00000052) #define TPM_ORD_ChangeAuth ((TPM_COMMAND_CODE) 0x0000000C) #define TPM_ORD_ChangeAuthAsymFinish ((TPM_COMMAND_CODE) 0x0000000F) #define TPM_ORD_ChangeAuthAsymStart ((TPM_COMMAND_CODE) 0x0000000E) #define TPM_ORD_ChangeAuthOwner ((TPM_COMMAND_CODE) 0x00000010) #define TPM_ORD_CMK_ApproveMA ((TPM_COMMAND_CODE) 0x0000001D) #define TPM_ORD_CMK_ConvertMigration ((TPM_COMMAND_CODE) 0x00000024) #define TPM_ORD_CMK_CreateBlob ((TPM_COMMAND_CODE) 0x0000001B) #define TPM_ORD_CMK_CreateKey ((TPM_COMMAND_CODE) 0x00000013) #define TPM_ORD_CMK_CreateTicket ((TPM_COMMAND_CODE) 0x00000012) #define TPM_ORD_CMK_SetRestrictions ((TPM_COMMAND_CODE) 0x0000001C) #define TPM_ORD_ContinueSelfTest ((TPM_COMMAND_CODE) 0x00000053) #define TPM_ORD_ConvertMigrationBlob ((TPM_COMMAND_CODE) 0x0000002A) #define TPM_ORD_CreateCounter ((TPM_COMMAND_CODE) 0x000000DC) #define TPM_ORD_CreateEndorsementKeyPair ((TPM_COMMAND_CODE) 0x00000078) #define TPM_ORD_CreateMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002C) #define TPM_ORD_CreateMigrationBlob ((TPM_COMMAND_CODE) 0x00000028) #define TPM_ORD_CreateRevocableEK ((TPM_COMMAND_CODE) 0x0000007F) #define TPM_ORD_CreateWrapKey ((TPM_COMMAND_CODE) 0x0000001F) #define TPM_ORD_DAA_JOIN ((TPM_COMMAND_CODE) 0x00000029) #define TPM_ORD_DAA_SIGN ((TPM_COMMAND_CODE) 0x00000031) #define TPM_ORD_Delegate_CreateKeyDelegation ((TPM_COMMAND_CODE) 0x000000D4) #define TPM_ORD_Delegate_CreateOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D5) #define TPM_ORD_Delegate_LoadOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D8) #define TPM_ORD_Delegate_Manage ((TPM_COMMAND_CODE) 0x000000D2) #define TPM_ORD_Delegate_ReadTable ((TPM_COMMAND_CODE) 0x000000DB) #define TPM_ORD_Delegate_UpdateVerification ((TPM_COMMAND_CODE) 0x000000D1) #define TPM_ORD_Delegate_VerifyDelegation ((TPM_COMMAND_CODE) 0x000000D6) #define TPM_ORD_DirRead ((TPM_COMMAND_CODE) 0x0000001A) #define TPM_ORD_DirWriteAuth ((TPM_COMMAND_CODE) 0x00000019) #define TPM_ORD_DisableForceClear ((TPM_COMMAND_CODE) 0x0000005E) #define TPM_ORD_DisableOwnerClear ((TPM_COMMAND_CODE) 0x0000005C) #define TPM_ORD_DisablePubekRead ((TPM_COMMAND_CODE) 0x0000007E) #define TPM_ORD_DSAP ((TPM_COMMAND_CODE) 0x00000011) #define TPM_ORD_EstablishTransport ((TPM_COMMAND_CODE) 0x000000E6) #define TPM_ORD_EvictKey ((TPM_COMMAND_CODE) 0x00000022) #define TPM_ORD_ExecuteTransport ((TPM_COMMAND_CODE) 0x000000E7) #define TPM_ORD_Extend ((TPM_COMMAND_CODE) 0x00000014) #define TPM_ORD_FieldUpgrade ((TPM_COMMAND_CODE) 0x000000AA) #define TPM_ORD_FlushSpecific ((TPM_COMMAND_CODE) 0x000000BA) #define TPM_ORD_ForceClear ((TPM_COMMAND_CODE) 0x0000005D) #define TPM_ORD_GetAuditDigest ((TPM_COMMAND_CODE) 0x00000085) #define TPM_ORD_GetAuditDigestSigned ((TPM_COMMAND_CODE) 0x00000086) #define TPM_ORD_GetAuditEvent ((TPM_COMMAND_CODE) 0x00000082) #define TPM_ORD_GetAuditEventSigned ((TPM_COMMAND_CODE) 0x00000083) #define TPM_ORD_GetCapability ((TPM_COMMAND_CODE) 0x00000065) #define TPM_ORD_GetCapabilityOwner ((TPM_COMMAND_CODE) 0x00000066) #define TPM_ORD_GetCapabilitySigned ((TPM_COMMAND_CODE) 0x00000064) #define TPM_ORD_GetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008C) #define TPM_ORD_GetPubKey ((TPM_COMMAND_CODE) 0x00000021) #define TPM_ORD_GetRandom ((TPM_COMMAND_CODE) 0x00000046) #define TPM_ORD_GetTestResult ((TPM_COMMAND_CODE) 0x00000054) #define TPM_ORD_GetTicks ((TPM_COMMAND_CODE) 0x000000F1) #define TPM_ORD_IncrementCounter ((TPM_COMMAND_CODE) 0x000000DD) #define TPM_ORD_Init ((TPM_COMMAND_CODE) 0x00000097) #define TPM_ORD_KeyControlOwner ((TPM_COMMAND_CODE) 0x00000023) #define TPM_ORD_KillMaintenanceFeature ((TPM_COMMAND_CODE) 0x0000002E) #define TPM_ORD_LoadAuthContext ((TPM_COMMAND_CODE) 0x000000B7) #define TPM_ORD_LoadContext ((TPM_COMMAND_CODE) 0x000000B9) #define TPM_ORD_LoadKey ((TPM_COMMAND_CODE) 0x00000020) #define TPM_ORD_LoadKey2 ((TPM_COMMAND_CODE) 0x00000041) #define TPM_ORD_LoadKeyContext ((TPM_COMMAND_CODE) 0x000000B5) #define TPM_ORD_LoadMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002D) #define TPM_ORD_LoadManuMaintPub ((TPM_COMMAND_CODE) 0x0000002F) #define TPM_ORD_MakeIdentity ((TPM_COMMAND_CODE) 0x00000079) #define TPM_ORD_MigrateKey ((TPM_COMMAND_CODE) 0x00000025) #define TPM_ORD_NV_DefineSpace ((TPM_COMMAND_CODE) 0x000000CC) #define TPM_ORD_NV_ReadValue ((TPM_COMMAND_CODE) 0x000000CF) #define TPM_ORD_NV_ReadValueAuth ((TPM_COMMAND_CODE) 0x000000D0) #define TPM_ORD_NV_WriteValue ((TPM_COMMAND_CODE) 0x000000CD) #define TPM_ORD_NV_WriteValueAuth ((TPM_COMMAND_CODE) 0x000000CE) #define TPM_ORD_OIAP ((TPM_COMMAND_CODE) 0x0000000A) #define TPM_ORD_OSAP ((TPM_COMMAND_CODE) 0x0000000B) #define TPM_ORD_OwnerClear ((TPM_COMMAND_CODE) 0x0000005B) #define TPM_ORD_OwnerReadInternalPub ((TPM_COMMAND_CODE) 0x00000081) #define TPM_ORD_OwnerReadPubek ((TPM_COMMAND_CODE) 0x0000007D) #define TPM_ORD_OwnerSetDisable ((TPM_COMMAND_CODE) 0x0000006E) #define TPM_ORD_PCR_Reset ((TPM_COMMAND_CODE) 0x000000C8) #define TPM_ORD_PcrRead ((TPM_COMMAND_CODE) 0x00000015) #define TPM_ORD_PhysicalDisable ((TPM_COMMAND_CODE) 0x00000070) #define TPM_ORD_PhysicalEnable ((TPM_COMMAND_CODE) 0x0000006F) #define TPM_ORD_PhysicalSetDeactivated ((TPM_COMMAND_CODE) 0x00000072) #define TPM_ORD_Quote ((TPM_COMMAND_CODE) 0x00000016) #define TPM_ORD_Quote2 ((TPM_COMMAND_CODE) 0x0000003E) #define TPM_ORD_ReadCounter ((TPM_COMMAND_CODE) 0x000000DE) #define TPM_ORD_ReadManuMaintPub ((TPM_COMMAND_CODE) 0x00000030) #define TPM_ORD_ReadPubek ((TPM_COMMAND_CODE) 0x0000007C) #define TPM_ORD_ReleaseCounter ((TPM_COMMAND_CODE) 0x000000DF) #define TPM_ORD_ReleaseCounterOwner ((TPM_COMMAND_CODE) 0x000000E0) #define TPM_ORD_ReleaseTransportSigned ((TPM_COMMAND_CODE) 0x000000E8) #define TPM_ORD_Reset ((TPM_COMMAND_CODE) 0x0000005A) #define TPM_ORD_ResetLockValue ((TPM_COMMAND_CODE) 0x00000040) #define TPM_ORD_RevokeTrust ((TPM_COMMAND_CODE) 0x00000080) #define TPM_ORD_SaveAuthContext ((TPM_COMMAND_CODE) 0x000000B6) #define TPM_ORD_SaveContext ((TPM_COMMAND_CODE) 0x000000B8) #define TPM_ORD_SaveKeyContext ((TPM_COMMAND_CODE) 0x000000B4) #define TPM_ORD_SaveState ((TPM_COMMAND_CODE) 0x00000098) #define TPM_ORD_Seal ((TPM_COMMAND_CODE) 0x00000017) #define TPM_ORD_Sealx ((TPM_COMMAND_CODE) 0x0000003D) #define TPM_ORD_SelfTestFull ((TPM_COMMAND_CODE) 0x00000050) #define TPM_ORD_SetCapability ((TPM_COMMAND_CODE) 0x0000003F) #define TPM_ORD_SetOperatorAuth ((TPM_COMMAND_CODE) 0x00000074) #define TPM_ORD_SetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008D) #define TPM_ORD_SetOwnerInstall ((TPM_COMMAND_CODE) 0x00000071) #define TPM_ORD_SetOwnerPointer ((TPM_COMMAND_CODE) 0x00000075) #define TPM_ORD_SetRedirection ((TPM_COMMAND_CODE) 0x0000009A) #define TPM_ORD_SetTempDeactivated ((TPM_COMMAND_CODE) 0x00000073) #define TPM_ORD_SHA1Complete ((TPM_COMMAND_CODE) 0x000000A2) #define TPM_ORD_SHA1CompleteExtend ((TPM_COMMAND_CODE) 0x000000A3) #define TPM_ORD_SHA1Start ((TPM_COMMAND_CODE) 0x000000A0) #define TPM_ORD_SHA1Update ((TPM_COMMAND_CODE) 0x000000A1) #define TPM_ORD_Sign ((TPM_COMMAND_CODE) 0x0000003C) #define TPM_ORD_Startup ((TPM_COMMAND_CODE) 0x00000099) #define TPM_ORD_StirRandom ((TPM_COMMAND_CODE) 0x00000047) #define TPM_ORD_TakeOwnership ((TPM_COMMAND_CODE) 0x0000000D) #define TPM_ORD_Terminate_Handle ((TPM_COMMAND_CODE) 0x00000096) #define TPM_ORD_TickStampBlob ((TPM_COMMAND_CODE) 0x000000F2) #define TPM_ORD_UnBind ((TPM_COMMAND_CODE) 0x0000001E) #define TPM_ORD_Unseal ((TPM_COMMAND_CODE) 0x00000018) #define TSC_ORD_PhysicalPresence ((TPM_COMMAND_CODE) 0x4000000A) #define TSC_ORD_ResetEstablishmentBit ((TPM_COMMAND_CODE) 0x4000000B) // // Part 2, section 18: Context structures // /// /// Part 2, section 18.1: TPM_CONTEXT_BLOB /// typedef struct tdTPM_CONTEXT_BLOB { TPM_STRUCTURE_TAG tag; TPM_RESOURCE_TYPE resourceType; TPM_HANDLE handle; UINT8 label[16]; UINT32 contextCount; TPM_DIGEST integrityDigest; UINT32 additionalSize; UINT8 *additionalData; UINT32 sensitiveSize; UINT8 *sensitiveData; } TPM_CONTEXT_BLOB; /// /// Part 2, section 18.2 TPM_CONTEXT_SENSITIVE /// typedef struct tdTPM_CONTEXT_SENSITIVE { TPM_STRUCTURE_TAG tag; TPM_NONCE contextNonce; UINT32 internalSize; UINT8 *internalData; } TPM_CONTEXT_SENSITIVE; // // Part 2, section 19: NV Structures // // // Part 2, section 19.1.1: Required TPM_NV_INDEX values // #define TPM_NV_INDEX_LOCK ((UINT32)0xffffffff) #define TPM_NV_INDEX0 ((UINT32)0x00000000) #define TPM_NV_INDEX_DIR ((UINT32)0x10000001) #define TPM_NV_INDEX_EKCert ((UINT32)0x0000f000) #define TPM_NV_INDEX_TPM_CC ((UINT32)0x0000f001) #define TPM_NV_INDEX_PlatformCert ((UINT32)0x0000f002) #define TPM_NV_INDEX_Platform_CC ((UINT32)0x0000f003) // // Part 2, section 19.1.2: Reserved Index values // #define TPM_NV_INDEX_TSS_BASE ((UINT32)0x00011100) #define TPM_NV_INDEX_PC_BASE ((UINT32)0x00011200) #define TPM_NV_INDEX_SERVER_BASE ((UINT32)0x00011300) #define TPM_NV_INDEX_MOBILE_BASE ((UINT32)0x00011400) #define TPM_NV_INDEX_PERIPHERAL_BASE ((UINT32)0x00011500) #define TPM_NV_INDEX_GROUP_RESV_BASE ((UINT32)0x00010000) /// /// Part 2, section 19.2: TPM_NV_ATTRIBUTES /// typedef struct tdTPM_NV_ATTRIBUTES { TPM_STRUCTURE_TAG tag; UINT32 attributes; } TPM_NV_ATTRIBUTES; #define TPM_NV_PER_READ_STCLEAR (BIT31) #define TPM_NV_PER_AUTHREAD (BIT18) #define TPM_NV_PER_OWNERREAD (BIT17) #define TPM_NV_PER_PPREAD (BIT16) #define TPM_NV_PER_GLOBALLOCK (BIT15) #define TPM_NV_PER_WRITE_STCLEAR (BIT14) #define TPM_NV_PER_WRITEDEFINE (BIT13) #define TPM_NV_PER_WRITEALL (BIT12) #define TPM_NV_PER_AUTHWRITE (BIT2) #define TPM_NV_PER_OWNERWRITE (BIT1) #define TPM_NV_PER_PPWRITE (BIT0) /// /// Part 2, section 19.3: TPM_NV_DATA_PUBLIC /// typedef struct tdTPM_NV_DATA_PUBLIC { TPM_STRUCTURE_TAG tag; TPM_NV_INDEX nvIndex; TPM_PCR_INFO_SHORT pcrInfoRead; TPM_PCR_INFO_SHORT pcrInfoWrite; TPM_NV_ATTRIBUTES permission; BOOLEAN bReadSTClear; BOOLEAN bWriteSTClear; BOOLEAN bWriteDefine; UINT32 dataSize; } TPM_NV_DATA_PUBLIC; // // Part 2, section 20: Delegate Structures // #define TPM_DEL_OWNER_BITS ((UINT32)0x00000001) #define TPM_DEL_KEY_BITS ((UINT32)0x00000002) /// /// Part 2, section 20.2: Delegate Definitions /// typedef struct tdTPM_DELEGATIONS { TPM_STRUCTURE_TAG tag; UINT32 delegateType; UINT32 per1; UINT32 per2; } TPM_DELEGATIONS; // // Part 2, section 20.2.1: Owner Permission Settings // #define TPM_DELEGATE_SetOrdinalAuditStatus (BIT30) #define TPM_DELEGATE_DirWriteAuth (BIT29) #define TPM_DELEGATE_CMK_ApproveMA (BIT28) #define TPM_DELEGATE_NV_WriteValue (BIT27) #define TPM_DELEGATE_CMK_CreateTicket (BIT26) #define TPM_DELEGATE_NV_ReadValue (BIT25) #define TPM_DELEGATE_Delegate_LoadOwnerDelegation (BIT24) #define TPM_DELEGATE_DAA_Join (BIT23) #define TPM_DELEGATE_AuthorizeMigrationKey (BIT22) #define TPM_DELEGATE_CreateMaintenanceArchive (BIT21) #define TPM_DELEGATE_LoadMaintenanceArchive (BIT20) #define TPM_DELEGATE_KillMaintenanceFeature (BIT19) #define TPM_DELEGATE_OwnerReadInteralPub (BIT18) #define TPM_DELEGATE_ResetLockValue (BIT17) #define TPM_DELEGATE_OwnerClear (BIT16) #define TPM_DELEGATE_DisableOwnerClear (BIT15) #define TPM_DELEGATE_NV_DefineSpace (BIT14) #define TPM_DELEGATE_OwnerSetDisable (BIT13) #define TPM_DELEGATE_SetCapability (BIT12) #define TPM_DELEGATE_MakeIdentity (BIT11) #define TPM_DELEGATE_ActivateIdentity (BIT10) #define TPM_DELEGATE_OwnerReadPubek (BIT9) #define TPM_DELEGATE_DisablePubekRead (BIT8) #define TPM_DELEGATE_SetRedirection (BIT7) #define TPM_DELEGATE_FieldUpgrade (BIT6) #define TPM_DELEGATE_Delegate_UpdateVerification (BIT5) #define TPM_DELEGATE_CreateCounter (BIT4) #define TPM_DELEGATE_ReleaseCounterOwner (BIT3) #define TPM_DELEGATE_DelegateManage (BIT2) #define TPM_DELEGATE_Delegate_CreateOwnerDelegation (BIT1) #define TPM_DELEGATE_DAA_Sign (BIT0) // // Part 2, section 20.2.3: Key Permission settings // #define TPM_KEY_DELEGATE_CMK_ConvertMigration (BIT28) #define TPM_KEY_DELEGATE_TickStampBlob (BIT27) #define TPM_KEY_DELEGATE_ChangeAuthAsymStart (BIT26) #define TPM_KEY_DELEGATE_ChangeAuthAsymFinish (BIT25) #define TPM_KEY_DELEGATE_CMK_CreateKey (BIT24) #define TPM_KEY_DELEGATE_MigrateKey (BIT23) #define TPM_KEY_DELEGATE_LoadKey2 (BIT22) #define TPM_KEY_DELEGATE_EstablishTransport (BIT21) #define TPM_KEY_DELEGATE_ReleaseTransportSigned (BIT20) #define TPM_KEY_DELEGATE_Quote2 (BIT19) #define TPM_KEY_DELEGATE_Sealx (BIT18) #define TPM_KEY_DELEGATE_MakeIdentity (BIT17) #define TPM_KEY_DELEGATE_ActivateIdentity (BIT16) #define TPM_KEY_DELEGATE_GetAuditDigestSigned (BIT15) #define TPM_KEY_DELEGATE_Sign (BIT14) #define TPM_KEY_DELEGATE_CertifyKey2 (BIT13) #define TPM_KEY_DELEGATE_CertifyKey (BIT12) #define TPM_KEY_DELEGATE_CreateWrapKey (BIT11) #define TPM_KEY_DELEGATE_CMK_CreateBlob (BIT10) #define TPM_KEY_DELEGATE_CreateMigrationBlob (BIT9) #define TPM_KEY_DELEGATE_ConvertMigrationBlob (BIT8) #define TPM_KEY_DELEGATE_CreateKeyDelegation (BIT7) #define TPM_KEY_DELEGATE_ChangeAuth (BIT6) #define TPM_KEY_DELEGATE_GetPubKey (BIT5) #define TPM_KEY_DELEGATE_UnBind (BIT4) #define TPM_KEY_DELEGATE_Quote (BIT3) #define TPM_KEY_DELEGATE_Unseal (BIT2) #define TPM_KEY_DELEGATE_Seal (BIT1) #define TPM_KEY_DELEGATE_LoadKey (BIT0) // // Part 2, section 20.3: TPM_FAMILY_FLAGS // #define TPM_DELEGATE_ADMIN_LOCK (BIT1) #define TPM_FAMFLAG_ENABLE (BIT0) /// /// Part 2, section 20.4: TPM_FAMILY_LABEL /// typedef struct tdTPM_FAMILY_LABEL { UINT8 label; } TPM_FAMILY_LABEL; /// /// Part 2, section 20.5: TPM_FAMILY_TABLE_ENTRY /// typedef struct tdTPM_FAMILY_TABLE_ENTRY { TPM_STRUCTURE_TAG tag; TPM_FAMILY_LABEL label; TPM_FAMILY_ID familyID; TPM_FAMILY_VERIFICATION verificationCount; TPM_FAMILY_FLAGS flags; } TPM_FAMILY_TABLE_ENTRY; // // Part 2, section 20.6: TPM_FAMILY_TABLE // #define TPM_NUM_FAMILY_TABLE_ENTRY_MIN 8 typedef struct tdTPM_FAMILY_TABLE { TPM_FAMILY_TABLE_ENTRY famTableRow[TPM_NUM_FAMILY_TABLE_ENTRY_MIN]; } TPM_FAMILY_TABLE; /// /// Part 2, section 20.7: TPM_DELEGATE_LABEL /// typedef struct tdTPM_DELEGATE_LABEL { UINT8 label; } TPM_DELEGATE_LABEL; /// /// Part 2, section 20.8: TPM_DELEGATE_PUBLIC /// typedef struct tdTPM_DELEGATE_PUBLIC { TPM_STRUCTURE_TAG tag; TPM_DELEGATE_LABEL label; TPM_PCR_INFO_SHORT pcrInfo; TPM_DELEGATIONS permissions; TPM_FAMILY_ID familyID; TPM_FAMILY_VERIFICATION verificationCount; } TPM_DELEGATE_PUBLIC; /// /// Part 2, section 20.9: TPM_DELEGATE_TABLE_ROW /// typedef struct tdTPM_DELEGATE_TABLE_ROW { TPM_STRUCTURE_TAG tag; TPM_DELEGATE_PUBLIC pub; TPM_SECRET authValue; } TPM_DELEGATE_TABLE_ROW; // // Part 2, section 20.10: TPM_DELEGATE_TABLE // #define TPM_NUM_DELEGATE_TABLE_ENTRY_MIN 2 typedef struct tdTPM_DELEGATE_TABLE { TPM_DELEGATE_TABLE_ROW delRow[TPM_NUM_DELEGATE_TABLE_ENTRY_MIN]; } TPM_DELEGATE_TABLE; /// /// Part 2, section 20.11: TPM_DELEGATE_SENSITIVE /// typedef struct tdTPM_DELEGATE_SENSITIVE { TPM_STRUCTURE_TAG tag; TPM_SECRET authValue; } TPM_DELEGATE_SENSITIVE; /// /// Part 2, section 20.12: TPM_DELEGATE_OWNER_BLOB /// typedef struct tdTPM_DELEGATE_OWNER_BLOB { TPM_STRUCTURE_TAG tag; TPM_DELEGATE_PUBLIC pub; TPM_DIGEST integrityDigest; UINT32 additionalSize; UINT8 *additionalArea; UINT32 sensitiveSize; UINT8 *sensitiveArea; } TPM_DELEGATE_OWNER_BLOB; /// /// Part 2, section 20.13: TTPM_DELEGATE_KEY_BLOB /// typedef struct tdTPM_DELEGATE_KEY_BLOB { TPM_STRUCTURE_TAG tag; TPM_DELEGATE_PUBLIC pub; TPM_DIGEST integrityDigest; TPM_DIGEST pubKeyDigest; UINT32 additionalSize; UINT8 *additionalArea; UINT32 sensitiveSize; UINT8 *sensitiveArea; } TPM_DELEGATE_KEY_BLOB; // // Part 2, section 20.14: TPM_FAMILY_OPERATION Values // #define TPM_FAMILY_CREATE ((UINT32)0x00000001) #define TPM_FAMILY_ENABLE ((UINT32)0x00000002) #define TPM_FAMILY_ADMIN ((UINT32)0x00000003) #define TPM_FAMILY_INVALIDATE ((UINT32)0x00000004) // // Part 2, section 21.1: TPM_CAPABILITY_AREA for GetCapability // #define TPM_CAP_ORD ((TPM_CAPABILITY_AREA) 0x00000001) #define TPM_CAP_ALG ((TPM_CAPABILITY_AREA) 0x00000002) #define TPM_CAP_PID ((TPM_CAPABILITY_AREA) 0x00000003) #define TPM_CAP_FLAG ((TPM_CAPABILITY_AREA) 0x00000004) #define TPM_CAP_PROPERTY ((TPM_CAPABILITY_AREA) 0x00000005) #define TPM_CAP_VERSION ((TPM_CAPABILITY_AREA) 0x00000006) #define TPM_CAP_KEY_HANDLE ((TPM_CAPABILITY_AREA) 0x00000007) #define TPM_CAP_CHECK_LOADED ((TPM_CAPABILITY_AREA) 0x00000008) #define TPM_CAP_SYM_MODE ((TPM_CAPABILITY_AREA) 0x00000009) #define TPM_CAP_KEY_STATUS ((TPM_CAPABILITY_AREA) 0x0000000C) #define TPM_CAP_NV_LIST ((TPM_CAPABILITY_AREA) 0x0000000D) #define TPM_CAP_MFR ((TPM_CAPABILITY_AREA) 0x00000010) #define TPM_CAP_NV_INDEX ((TPM_CAPABILITY_AREA) 0x00000011) #define TPM_CAP_TRANS_ALG ((TPM_CAPABILITY_AREA) 0x00000012) #define TPM_CAP_HANDLE ((TPM_CAPABILITY_AREA) 0x00000014) #define TPM_CAP_TRANS_ES ((TPM_CAPABILITY_AREA) 0x00000015) #define TPM_CAP_AUTH_ENCRYPT ((TPM_CAPABILITY_AREA) 0x00000017) #define TPM_CAP_SELECT_SIZE ((TPM_CAPABILITY_AREA) 0x00000018) #define TPM_CAP_VERSION_VAL ((TPM_CAPABILITY_AREA) 0x0000001A) #define TPM_CAP_FLAG_PERMANENT ((TPM_CAPABILITY_AREA) 0x00000108) #define TPM_CAP_FLAG_VOLATILE ((TPM_CAPABILITY_AREA) 0x00000109) // // Part 2, section 21.2: CAP_PROPERTY Subcap values for GetCapability // #define TPM_CAP_PROP_PCR ((TPM_CAPABILITY_AREA) 0x00000101) #define TPM_CAP_PROP_DIR ((TPM_CAPABILITY_AREA) 0x00000102) #define TPM_CAP_PROP_MANUFACTURER ((TPM_CAPABILITY_AREA) 0x00000103) #define TPM_CAP_PROP_KEYS ((TPM_CAPABILITY_AREA) 0x00000104) #define TPM_CAP_PROP_MIN_COUNTER ((TPM_CAPABILITY_AREA) 0x00000107) #define TPM_CAP_PROP_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010A) #define TPM_CAP_PROP_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010B) #define TPM_CAP_PROP_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010C) #define TPM_CAP_PROP_MAX_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010D) #define TPM_CAP_PROP_MAX_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010E) #define TPM_CAP_PROP_MAX_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010F) #define TPM_CAP_PROP_MAX_KEYS ((TPM_CAPABILITY_AREA) 0x00000110) #define TPM_CAP_PROP_OWNER ((TPM_CAPABILITY_AREA) 0x00000111) #define TPM_CAP_PROP_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000112) #define TPM_CAP_PROP_MAX_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000113) #define TPM_CAP_PROP_FAMILYROWS ((TPM_CAPABILITY_AREA) 0x00000114) #define TPM_CAP_PROP_TIS_TIMEOUT ((TPM_CAPABILITY_AREA) 0x00000115) #define TPM_CAP_PROP_STARTUP_EFFECT ((TPM_CAPABILITY_AREA) 0x00000116) #define TPM_CAP_PROP_DELEGATE_ROW ((TPM_CAPABILITY_AREA) 0x00000117) #define TPM_CAP_PROP_DAA_MAX ((TPM_CAPABILITY_AREA) 0x00000119) #define CAP_PROP_SESSION_DAA ((TPM_CAPABILITY_AREA) 0x0000011A) #define TPM_CAP_PROP_CONTEXT_DIST ((TPM_CAPABILITY_AREA) 0x0000011B) #define TPM_CAP_PROP_DAA_INTERRUPT ((TPM_CAPABILITY_AREA) 0x0000011C) #define TPM_CAP_PROP_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011D) #define TPM_CAP_PROP_MAX_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011E) #define TPM_CAP_PROP_CMK_RESTRICTION ((TPM_CAPABILITY_AREA) 0x0000011F) #define TPM_CAP_PROP_DURATION ((TPM_CAPABILITY_AREA) 0x00000120) #define TPM_CAP_PROP_ACTIVE_COUNTER ((TPM_CAPABILITY_AREA) 0x00000122) #define TPM_CAP_PROP_MAX_NV_AVAILABLE ((TPM_CAPABILITY_AREA) 0x00000123) #define TPM_CAP_PROP_INPUT_BUFFER ((TPM_CAPABILITY_AREA) 0x00000124) // // Part 2, section 21.4: TPM_CAPABILITY_AREA for SetCapability // #define TPM_SET_PERM_FLAGS ((TPM_CAPABILITY_AREA) 0x00000001) #define TPM_SET_PERM_DATA ((TPM_CAPABILITY_AREA) 0x00000002) #define TPM_SET_STCLEAR_FLAGS ((TPM_CAPABILITY_AREA) 0x00000003) #define TPM_SET_STCLEAR_DATA ((TPM_CAPABILITY_AREA) 0x00000004) #define TPM_SET_STANY_FLAGS ((TPM_CAPABILITY_AREA) 0x00000005) #define TPM_SET_STANY_DATA ((TPM_CAPABILITY_AREA) 0x00000006) /// /// Part 2, section 21.6: TPM_CAP_VERSION_INFO /// [size_is(vendorSpecificSize)] BYTE* vendorSpecific; /// typedef struct tdTPM_CAP_VERSION_INFO { TPM_STRUCTURE_TAG tag; TPM_VERSION version; UINT16 specLevel; UINT8 errataRev; UINT8 tpmVendorID[4]; UINT16 vendorSpecificSize; UINT8 *vendorSpecific; } TPM_CAP_VERSION_INFO; /// /// Part 2, section 21.10: TPM_DA_ACTION_TYPE /// typedef struct tdTPM_DA_ACTION_TYPE { TPM_STRUCTURE_TAG tag; UINT32 actions; } TPM_DA_ACTION_TYPE; #define TPM_DA_ACTION_FAILURE_MODE (((UINT32)1)<<3) #define TPM_DA_ACTION_DEACTIVATE (((UINT32)1)<<2) #define TPM_DA_ACTION_DISABLE (((UINT32)1)<<1) #define TPM_DA_ACTION_TIMEOUT (((UINT32)1)<<0) /// /// Part 2, section 21.7: TPM_DA_INFO /// typedef struct tdTPM_DA_INFO { TPM_STRUCTURE_TAG tag; TPM_DA_STATE state; UINT16 currentCount; UINT16 thresholdCount; TPM_DA_ACTION_TYPE actionAtThreshold; UINT32 actionDependValue; UINT32 vendorDataSize; UINT8 *vendorData; } TPM_DA_INFO; /// /// Part 2, section 21.8: TPM_DA_INFO_LIMITED /// typedef struct tdTPM_DA_INFO_LIMITED { TPM_STRUCTURE_TAG tag; TPM_DA_STATE state; TPM_DA_ACTION_TYPE actionAtThreshold; UINT32 vendorDataSize; UINT8 *vendorData; } TPM_DA_INFO_LIMITED; // // Part 2, section 21.9: CAP_PROPERTY Subcap values for GetCapability // #define TPM_DA_STATE_INACTIVE ((UINT8)0x00) #define TPM_DA_STATE_ACTIVE ((UINT8)0x01) // // Part 2, section 22: DAA Structures // // // Part 2, section 22.1: Size definitions // #define TPM_DAA_SIZE_r0 (43) #define TPM_DAA_SIZE_r1 (43) #define TPM_DAA_SIZE_r2 (128) #define TPM_DAA_SIZE_r3 (168) #define TPM_DAA_SIZE_r4 (219) #define TPM_DAA_SIZE_NT (20) #define TPM_DAA_SIZE_v0 (128) #define TPM_DAA_SIZE_v1 (192) #define TPM_DAA_SIZE_NE (256) #define TPM_DAA_SIZE_w (256) #define TPM_DAA_SIZE_issuerModulus (256) // // Part 2, section 22.2: Constant definitions // #define TPM_DAA_power0 (104) #define TPM_DAA_power1 (1024) /// /// Part 2, section 22.3: TPM_DAA_ISSUER /// typedef struct tdTPM_DAA_ISSUER { TPM_STRUCTURE_TAG tag; TPM_DIGEST DAA_digest_R0; TPM_DIGEST DAA_digest_R1; TPM_DIGEST DAA_digest_S0; TPM_DIGEST DAA_digest_S1; TPM_DIGEST DAA_digest_n; TPM_DIGEST DAA_digest_gamma; UINT8 DAA_generic_q[26]; } TPM_DAA_ISSUER; /// /// Part 2, section 22.4: TPM_DAA_TPM /// typedef struct tdTPM_DAA_TPM { TPM_STRUCTURE_TAG tag; TPM_DIGEST DAA_digestIssuer; TPM_DIGEST DAA_digest_v0; TPM_DIGEST DAA_digest_v1; TPM_DIGEST DAA_rekey; UINT32 DAA_count; } TPM_DAA_TPM; /// /// Part 2, section 22.5: TPM_DAA_CONTEXT /// typedef struct tdTPM_DAA_CONTEXT { TPM_STRUCTURE_TAG tag; TPM_DIGEST DAA_digestContext; TPM_DIGEST DAA_digest; TPM_DAA_CONTEXT_SEED DAA_contextSeed; UINT8 DAA_scratch[256]; UINT8 DAA_stage; } TPM_DAA_CONTEXT; /// /// Part 2, section 22.6: TPM_DAA_JOINDATA /// typedef struct tdTPM_DAA_JOINDATA { UINT8 DAA_join_u0[128]; UINT8 DAA_join_u1[138]; TPM_DIGEST DAA_digest_n0; } TPM_DAA_JOINDATA; /// /// Part 2, section 22.8: TPM_DAA_BLOB /// typedef struct tdTPM_DAA_BLOB { TPM_STRUCTURE_TAG tag; TPM_RESOURCE_TYPE resourceType; UINT8 label[16]; TPM_DIGEST blobIntegrity; UINT32 additionalSize; UINT8 *additionalData; UINT32 sensitiveSize; UINT8 *sensitiveData; } TPM_DAA_BLOB; /// /// Part 2, section 22.9: TPM_DAA_SENSITIVE /// typedef struct tdTPM_DAA_SENSITIVE { TPM_STRUCTURE_TAG tag; UINT32 internalSize; UINT8 *internalData; } TPM_DAA_SENSITIVE; // // Part 2, section 23: Redirection // /// /// Part 2 section 23.1: TPM_REDIR_COMMAND /// This section defines exactly one value but does not /// give it a name. The definition of TPM_SetRedirection in Part3 /// refers to exactly one name but does not give its value. We join /// them here. /// #define TPM_REDIR_GPIO (0x00000001) /// /// TPM Command Headers defined in Part 3 /// typedef struct tdTPM_RQU_COMMAND_HDR { TPM_STRUCTURE_TAG tag; UINT32 paramSize; TPM_COMMAND_CODE ordinal; } TPM_RQU_COMMAND_HDR; /// /// TPM Response Headers defined in Part 3 /// typedef struct tdTPM_RSP_COMMAND_HDR { TPM_STRUCTURE_TAG tag; UINT32 paramSize; TPM_RESULT returnCode; } TPM_RSP_COMMAND_HDR; #pragma pack () #endif /** @file TPM2.0 Specification data structures (Trusted Platform Module Library Specification, Family "2.0", Level 00, Revision 00.96, @http://www.trustedcomputinggroup.org/resources/tpm_library_specification) Check http://trustedcomputinggroup.org for latest specification updates. Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _TPM20_H_ #define _TPM20_H_ #include #pragma pack (1) // Annex A Algorithm Constants // Table 205 - Defines for SHA1 Hash Values #define SHA1_DIGEST_SIZE 20 #define SHA1_BLOCK_SIZE 64 // Table 206 - Defines for SHA256 Hash Values #define SHA256_DIGEST_SIZE 32 #define SHA256_BLOCK_SIZE 64 // Table 207 - Defines for SHA384 Hash Values #define SHA384_DIGEST_SIZE 48 #define SHA384_BLOCK_SIZE 128 // Table 208 - Defines for SHA512 Hash Values #define SHA512_DIGEST_SIZE 64 #define SHA512_BLOCK_SIZE 128 // Table 209 - Defines for SM3_256 Hash Values #define SM3_256_DIGEST_SIZE 32 #define SM3_256_BLOCK_SIZE 64 // Table 210 - Defines for Architectural Limits Values #define MAX_SESSION_NUMBER 3 // Annex B Implementation Definitions // Table 211 - Defines for Logic Values #define YES 1 #define NO 0 #define SET 1 #define CLEAR 0 // Table 215 - Defines for RSA Algorithm Constants #define MAX_RSA_KEY_BITS 2048 #define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS + 7) / 8) // Table 216 - Defines for ECC Algorithm Constants #define MAX_ECC_KEY_BITS 256 #define MAX_ECC_KEY_BYTES ((MAX_ECC_KEY_BITS + 7) / 8) // Table 217 - Defines for AES Algorithm Constants #define MAX_AES_KEY_BITS 128 #define MAX_AES_BLOCK_SIZE_BYTES 16 #define MAX_AES_KEY_BYTES ((MAX_AES_KEY_BITS + 7) / 8) // Table 218 - Defines for SM4 Algorithm Constants #define MAX_SM4_KEY_BITS 128 #define MAX_SM4_BLOCK_SIZE_BYTES 16 #define MAX_SM4_KEY_BYTES ((MAX_SM4_KEY_BITS + 7) / 8) // Table 219 - Defines for Symmetric Algorithm Constants #define MAX_SYM_KEY_BITS MAX_AES_KEY_BITS #define MAX_SYM_KEY_BYTES MAX_AES_KEY_BYTES #define MAX_SYM_BLOCK_SIZE MAX_AES_BLOCK_SIZE_BYTES // Table 220 - Defines for Implementation Values typedef UINT16 BSIZE; #define BUFFER_ALIGNMENT 4 #define IMPLEMENTATION_PCR 24 #define PLATFORM_PCR 24 #define DRTM_PCR 17 #define NUM_LOCALITIES 5 #define MAX_HANDLE_NUM 3 #define MAX_ACTIVE_SESSIONS 64 typedef UINT16 CONTEXT_SLOT; typedef UINT64 CONTEXT_COUNTER; #define MAX_LOADED_SESSIONS 3 #define MAX_SESSION_NUM 3 #define MAX_LOADED_OBJECTS 3 #define MIN_EVICT_OBJECTS 2 #define PCR_SELECT_MIN ((PLATFORM_PCR + 7) / 8) #define PCR_SELECT_MAX ((IMPLEMENTATION_PCR + 7) / 8) #define NUM_POLICY_PCR_GROUP 1 #define NUM_AUTHVALUE_PCR_GROUP 1 #define MAX_CONTEXT_SIZE 4000 #define MAX_DIGEST_BUFFER 1024 #define MAX_NV_INDEX_SIZE 1024 #define MAX_CAP_BUFFER 1024 #define NV_MEMORY_SIZE 16384 #define NUM_STATIC_PCR 16 #define MAX_ALG_LIST_SIZE 64 #define TIMER_PRESCALE 100000 #define PRIMARY_SEED_SIZE 32 #define CONTEXT_ENCRYPT_ALG TPM_ALG_AES #define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS #define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS + 7) / 8) #define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256 #define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE #define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE #define NV_CLOCK_UPDATE_INTERVAL 12 #define NUM_POLICY_PCR 1 #define MAX_COMMAND_SIZE 4096 #define MAX_RESPONSE_SIZE 4096 #define ORDERLY_BITS 8 #define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1) #define ALG_ID_FIRST TPM_ALG_FIRST #define ALG_ID_LAST TPM_ALG_LAST #define MAX_SYM_DATA 128 #define MAX_RNG_ENTROPY_SIZE 64 #define RAM_INDEX_SPACE 512 #define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001 #define CRT_FORMAT_RSA YES #define PRIVATE_VENDOR_SPECIFIC_BYTES ((MAX_RSA_KEY_BYTES / 2) * ( 3 + CRT_FORMAT_RSA * 2)) // Capability related MAX_ value #define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP) - sizeof(UINT32)) #define MAX_CAP_ALGS (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY)) #define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE)) #define MAX_CAP_CC (MAX_CAP_DATA / sizeof(TPM_CC)) #define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY)) #define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT)) #define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE)) // // Always set 5 here, because we want to support all hash algo in BIOS. // #define HASH_COUNT 5 // 5 Base Types // Table 3 - Definition of Base Types typedef UINT8 BYTE; // Table 4 - Definition of Types for Documentation Clarity // // NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue) // // typedef UINT32 TPM_ALGORITHM_ID; // typedef UINT32 TPM_MODIFIER_INDICATOR; typedef UINT32 TPM_AUTHORIZATION_SIZE; typedef UINT32 TPM_PARAMETER_SIZE; typedef UINT16 TPM_KEY_SIZE; typedef UINT16 TPM_KEY_BITS; // 6 Constants // Table 6 - TPM_GENERATED Constants typedef UINT32 TPM_GENERATED; #define TPM_GENERATED_VALUE (TPM_GENERATED)(0xff544347) // Table 7 - TPM_ALG_ID Constants typedef UINT16 TPM_ALG_ID; // // NOTE: Comment some algo which has same name as TPM1.2 (value is same, so not runtime issue) // #define TPM_ALG_ERROR (TPM_ALG_ID)(0x0000) #define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001) // #define TPM_ALG_RSA (TPM_ALG_ID)(0x0001) // #define TPM_ALG_SHA (TPM_ALG_ID)(0x0004) #define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004) // #define TPM_ALG_HMAC (TPM_ALG_ID)(0x0005) #define TPM_ALG_AES (TPM_ALG_ID)(0x0006) // #define TPM_ALG_MGF1 (TPM_ALG_ID)(0x0007) #define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(0x0008) // #define TPM_ALG_XOR (TPM_ALG_ID)(0x000A) #define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B) #define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C) #define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D) #define TPM_ALG_NULL (TPM_ALG_ID)(0x0010) #define TPM_ALG_SM3_256 (TPM_ALG_ID)(0x0012) #define TPM_ALG_SM4 (TPM_ALG_ID)(0x0013) #define TPM_ALG_RSASSA (TPM_ALG_ID)(0x0014) #define TPM_ALG_RSAES (TPM_ALG_ID)(0x0015) #define TPM_ALG_RSAPSS (TPM_ALG_ID)(0x0016) #define TPM_ALG_OAEP (TPM_ALG_ID)(0x0017) #define TPM_ALG_ECDSA (TPM_ALG_ID)(0x0018) #define TPM_ALG_ECDH (TPM_ALG_ID)(0x0019) #define TPM_ALG_ECDAA (TPM_ALG_ID)(0x001A) #define TPM_ALG_SM2 (TPM_ALG_ID)(0x001B) #define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(0x001C) #define TPM_ALG_ECMQV (TPM_ALG_ID)(0x001D) #define TPM_ALG_KDF1_SP800_56a (TPM_ALG_ID)(0x0020) #define TPM_ALG_KDF2 (TPM_ALG_ID)(0x0021) #define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022) #define TPM_ALG_ECC (TPM_ALG_ID)(0x0023) #define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(0x0025) #define TPM_ALG_CTR (TPM_ALG_ID)(0x0040) #define TPM_ALG_OFB (TPM_ALG_ID)(0x0041) #define TPM_ALG_CBC (TPM_ALG_ID)(0x0042) #define TPM_ALG_CFB (TPM_ALG_ID)(0x0043) #define TPM_ALG_ECB (TPM_ALG_ID)(0x0044) #define TPM_ALG_LAST (TPM_ALG_ID)(0x0044) // Table 8 - TPM_ECC_CURVE Constants typedef UINT16 TPM_ECC_CURVE; #define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000) #define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001) #define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002) #define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003) #define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004) #define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005) #define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010) #define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011) #define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020) // Table 11 - TPM_CC Constants (Numeric Order) typedef UINT32 TPM_CC; #define TPM_CC_FIRST (TPM_CC)(0x0000011F) #define TPM_CC_PP_FIRST (TPM_CC)(0x0000011F) #define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F) #define TPM_CC_EvictControl (TPM_CC)(0x00000120) #define TPM_CC_HierarchyControl (TPM_CC)(0x00000121) #define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122) #define TPM_CC_ChangeEPS (TPM_CC)(0x00000124) #define TPM_CC_ChangePPS (TPM_CC)(0x00000125) #define TPM_CC_Clear (TPM_CC)(0x00000126) #define TPM_CC_ClearControl (TPM_CC)(0x00000127) #define TPM_CC_ClockSet (TPM_CC)(0x00000128) #define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129) #define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A) #define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B) #define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C) #define TPM_CC_PP_Commands (TPM_CC)(0x0000012D) #define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E) #define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F) #define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130) #define TPM_CC_CreatePrimary (TPM_CC)(0x00000131) #define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132) #define TPM_CC_PP_LAST (TPM_CC)(0x00000132) #define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133) #define TPM_CC_NV_Increment (TPM_CC)(0x00000134) #define TPM_CC_NV_SetBits (TPM_CC)(0x00000135) #define TPM_CC_NV_Extend (TPM_CC)(0x00000136) #define TPM_CC_NV_Write (TPM_CC)(0x00000137) #define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138) #define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139) #define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A) #define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B) #define TPM_CC_PCR_Event (TPM_CC)(0x0000013C) #define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D) #define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E) #define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F) #define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140) #define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141) #define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142) #define TPM_CC_SelfTest (TPM_CC)(0x00000143) #define TPM_CC_Startup (TPM_CC)(0x00000144) #define TPM_CC_Shutdown (TPM_CC)(0x00000145) #define TPM_CC_StirRandom (TPM_CC)(0x00000146) #define TPM_CC_ActivateCredential (TPM_CC)(0x00000147) #define TPM_CC_Certify (TPM_CC)(0x00000148) #define TPM_CC_PolicyNV (TPM_CC)(0x00000149) #define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A) #define TPM_CC_Duplicate (TPM_CC)(0x0000014B) #define TPM_CC_GetTime (TPM_CC)(0x0000014C) #define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D) #define TPM_CC_NV_Read (TPM_CC)(0x0000014E) #define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F) #define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150) #define TPM_CC_PolicySecret (TPM_CC)(0x00000151) #define TPM_CC_Rewrap (TPM_CC)(0x00000152) #define TPM_CC_Create (TPM_CC)(0x00000153) #define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154) #define TPM_CC_HMAC (TPM_CC)(0x00000155) #define TPM_CC_Import (TPM_CC)(0x00000156) #define TPM_CC_Load (TPM_CC)(0x00000157) #define TPM_CC_Quote (TPM_CC)(0x00000158) #define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159) #define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B) #define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C) #define TPM_CC_Sign (TPM_CC)(0x0000015D) #define TPM_CC_Unseal (TPM_CC)(0x0000015E) #define TPM_CC_PolicySigned (TPM_CC)(0x00000160) #define TPM_CC_ContextLoad (TPM_CC)(0x00000161) #define TPM_CC_ContextSave (TPM_CC)(0x00000162) #define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163) #define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164) #define TPM_CC_FlushContext (TPM_CC)(0x00000165) #define TPM_CC_LoadExternal (TPM_CC)(0x00000167) #define TPM_CC_MakeCredential (TPM_CC)(0x00000168) #define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169) #define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A) #define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B) #define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C) #define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D) #define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E) #define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F) #define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170) #define TPM_CC_PolicyOR (TPM_CC)(0x00000171) #define TPM_CC_PolicyTicket (TPM_CC)(0x00000172) #define TPM_CC_ReadPublic (TPM_CC)(0x00000173) #define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174) #define TPM_CC_StartAuthSession (TPM_CC)(0x00000176) #define TPM_CC_VerifySignature (TPM_CC)(0x00000177) #define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178) #define TPM_CC_FirmwareRead (TPM_CC)(0x00000179) #define TPM_CC_GetCapability (TPM_CC)(0x0000017A) #define TPM_CC_GetRandom (TPM_CC)(0x0000017B) #define TPM_CC_GetTestResult (TPM_CC)(0x0000017C) #define TPM_CC_Hash (TPM_CC)(0x0000017D) #define TPM_CC_PCR_Read (TPM_CC)(0x0000017E) #define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F) #define TPM_CC_PolicyRestart (TPM_CC)(0x00000180) #define TPM_CC_ReadClock (TPM_CC)(0x00000181) #define TPM_CC_PCR_Extend (TPM_CC)(0x00000182) #define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183) #define TPM_CC_NV_Certify (TPM_CC)(0x00000184) #define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185) #define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186) #define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187) #define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188) #define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189) #define TPM_CC_TestParms (TPM_CC)(0x0000018A) #define TPM_CC_Commit (TPM_CC)(0x0000018B) #define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C) #define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018D) #define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018E) #define TPM_CC_LAST (TPM_CC)(0x0000018E) // Table 15 - TPM_RC Constants (Actions) typedef UINT32 TPM_RC; #define TPM_RC_SUCCESS (TPM_RC)(0x000) #define TPM_RC_BAD_TAG (TPM_RC)(0x030) #define RC_VER1 (TPM_RC)(0x100) #define TPM_RC_INITIALIZE (TPM_RC)(RC_VER1 + 0x000) #define TPM_RC_FAILURE (TPM_RC)(RC_VER1 + 0x001) #define TPM_RC_SEQUENCE (TPM_RC)(RC_VER1 + 0x003) #define TPM_RC_PRIVATE (TPM_RC)(RC_VER1 + 0x00B) #define TPM_RC_HMAC (TPM_RC)(RC_VER1 + 0x019) #define TPM_RC_DISABLED (TPM_RC)(RC_VER1 + 0x020) #define TPM_RC_EXCLUSIVE (TPM_RC)(RC_VER1 + 0x021) #define TPM_RC_AUTH_TYPE (TPM_RC)(RC_VER1 + 0x024) #define TPM_RC_AUTH_MISSING (TPM_RC)(RC_VER1 + 0x025) #define TPM_RC_POLICY (TPM_RC)(RC_VER1 + 0x026) #define TPM_RC_PCR (TPM_RC)(RC_VER1 + 0x027) #define TPM_RC_PCR_CHANGED (TPM_RC)(RC_VER1 + 0x028) #define TPM_RC_UPGRADE (TPM_RC)(RC_VER1 + 0x02D) #define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1 + 0x02E) #define TPM_RC_AUTH_UNAVAILABLE (TPM_RC)(RC_VER1 + 0x02F) #define TPM_RC_REBOOT (TPM_RC)(RC_VER1 + 0x030) #define TPM_RC_UNBALANCED (TPM_RC)(RC_VER1 + 0x031) #define TPM_RC_COMMAND_SIZE (TPM_RC)(RC_VER1 + 0x042) #define TPM_RC_COMMAND_CODE (TPM_RC)(RC_VER1 + 0x043) #define TPM_RC_AUTHSIZE (TPM_RC)(RC_VER1 + 0x044) #define TPM_RC_AUTH_CONTEXT (TPM_RC)(RC_VER1 + 0x045) #define TPM_RC_NV_RANGE (TPM_RC)(RC_VER1 + 0x046) #define TPM_RC_NV_SIZE (TPM_RC)(RC_VER1 + 0x047) #define TPM_RC_NV_LOCKED (TPM_RC)(RC_VER1 + 0x048) #define TPM_RC_NV_AUTHORIZATION (TPM_RC)(RC_VER1 + 0x049) #define TPM_RC_NV_UNINITIALIZED (TPM_RC)(RC_VER1 + 0x04A) #define TPM_RC_NV_SPACE (TPM_RC)(RC_VER1 + 0x04B) #define TPM_RC_NV_DEFINED (TPM_RC)(RC_VER1 + 0x04C) #define TPM_RC_BAD_CONTEXT (TPM_RC)(RC_VER1 + 0x050) #define TPM_RC_CPHASH (TPM_RC)(RC_VER1 + 0x051) #define TPM_RC_PARENT (TPM_RC)(RC_VER1 + 0x052) #define TPM_RC_NEEDS_TEST (TPM_RC)(RC_VER1 + 0x053) #define TPM_RC_NO_RESULT (TPM_RC)(RC_VER1 + 0x054) #define TPM_RC_SENSITIVE (TPM_RC)(RC_VER1 + 0x055) #define RC_MAX_FM0 (TPM_RC)(RC_VER1 + 0x07F) #define RC_FMT1 (TPM_RC)(0x080) #define TPM_RC_ASYMMETRIC (TPM_RC)(RC_FMT1 + 0x001) #define TPM_RC_ATTRIBUTES (TPM_RC)(RC_FMT1 + 0x002) #define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003) #define TPM_RC_VALUE (TPM_RC)(RC_FMT1 + 0x004) #define TPM_RC_HIERARCHY (TPM_RC)(RC_FMT1 + 0x005) #define TPM_RC_KEY_SIZE (TPM_RC)(RC_FMT1 + 0x007) #define TPM_RC_MGF (TPM_RC)(RC_FMT1 + 0x008) #define TPM_RC_MODE (TPM_RC)(RC_FMT1 + 0x009) #define TPM_RC_TYPE (TPM_RC)(RC_FMT1 + 0x00A) #define TPM_RC_HANDLE (TPM_RC)(RC_FMT1 + 0x00B) #define TPM_RC_KDF (TPM_RC)(RC_FMT1 + 0x00C) #define TPM_RC_RANGE (TPM_RC)(RC_FMT1 + 0x00D) #define TPM_RC_AUTH_FAIL (TPM_RC)(RC_FMT1 + 0x00E) #define TPM_RC_NONCE (TPM_RC)(RC_FMT1 + 0x00F) #define TPM_RC_PP (TPM_RC)(RC_FMT1 + 0x010) #define TPM_RC_SCHEME (TPM_RC)(RC_FMT1 + 0x012) #define TPM_RC_SIZE (TPM_RC)(RC_FMT1 + 0x015) #define TPM_RC_SYMMETRIC (TPM_RC)(RC_FMT1 + 0x016) #define TPM_RC_TAG (TPM_RC)(RC_FMT1 + 0x017) #define TPM_RC_SELECTOR (TPM_RC)(RC_FMT1 + 0x018) #define TPM_RC_INSUFFICIENT (TPM_RC)(RC_FMT1 + 0x01A) #define TPM_RC_SIGNATURE (TPM_RC)(RC_FMT1 + 0x01B) #define TPM_RC_KEY (TPM_RC)(RC_FMT1 + 0x01C) #define TPM_RC_POLICY_FAIL (TPM_RC)(RC_FMT1 + 0x01D) #define TPM_RC_INTEGRITY (TPM_RC)(RC_FMT1 + 0x01F) #define TPM_RC_TICKET (TPM_RC)(RC_FMT1 + 0x020) #define TPM_RC_RESERVED_BITS (TPM_RC)(RC_FMT1 + 0x021) #define TPM_RC_BAD_AUTH (TPM_RC)(RC_FMT1 + 0x022) #define TPM_RC_EXPIRED (TPM_RC)(RC_FMT1 + 0x023) #define TPM_RC_POLICY_CC (TPM_RC)(RC_FMT1 + 0x024 ) #define TPM_RC_BINDING (TPM_RC)(RC_FMT1 + 0x025) #define TPM_RC_CURVE (TPM_RC)(RC_FMT1 + 0x026) #define TPM_RC_ECC_POINT (TPM_RC)(RC_FMT1 + 0x027) #define RC_WARN (TPM_RC)(0x900) #define TPM_RC_CONTEXT_GAP (TPM_RC)(RC_WARN + 0x001) #define TPM_RC_OBJECT_MEMORY (TPM_RC)(RC_WARN + 0x002) #define TPM_RC_SESSION_MEMORY (TPM_RC)(RC_WARN + 0x003) #define TPM_RC_MEMORY (TPM_RC)(RC_WARN + 0x004) #define TPM_RC_SESSION_HANDLES (TPM_RC)(RC_WARN + 0x005) #define TPM_RC_OBJECT_HANDLES (TPM_RC)(RC_WARN + 0x006) #define TPM_RC_LOCALITY (TPM_RC)(RC_WARN + 0x007) #define TPM_RC_YIELDED (TPM_RC)(RC_WARN + 0x008) #define TPM_RC_CANCELED (TPM_RC)(RC_WARN + 0x009) #define TPM_RC_TESTING (TPM_RC)(RC_WARN + 0x00A) #define TPM_RC_REFERENCE_H0 (TPM_RC)(RC_WARN + 0x010) #define TPM_RC_REFERENCE_H1 (TPM_RC)(RC_WARN + 0x011) #define TPM_RC_REFERENCE_H2 (TPM_RC)(RC_WARN + 0x012) #define TPM_RC_REFERENCE_H3 (TPM_RC)(RC_WARN + 0x013) #define TPM_RC_REFERENCE_H4 (TPM_RC)(RC_WARN + 0x014) #define TPM_RC_REFERENCE_H5 (TPM_RC)(RC_WARN + 0x015) #define TPM_RC_REFERENCE_H6 (TPM_RC)(RC_WARN + 0x016) #define TPM_RC_REFERENCE_S0 (TPM_RC)(RC_WARN + 0x018) #define TPM_RC_REFERENCE_S1 (TPM_RC)(RC_WARN + 0x019) #define TPM_RC_REFERENCE_S2 (TPM_RC)(RC_WARN + 0x01A) #define TPM_RC_REFERENCE_S3 (TPM_RC)(RC_WARN + 0x01B) #define TPM_RC_REFERENCE_S4 (TPM_RC)(RC_WARN + 0x01C) #define TPM_RC_REFERENCE_S5 (TPM_RC)(RC_WARN + 0x01D) #define TPM_RC_REFERENCE_S6 (TPM_RC)(RC_WARN + 0x01E) #define TPM_RC_NV_RATE (TPM_RC)(RC_WARN + 0x020) #define TPM_RC_LOCKOUT (TPM_RC)(RC_WARN + 0x021) #define TPM_RC_RETRY (TPM_RC)(RC_WARN + 0x022) #define TPM_RC_NV_UNAVAILABLE (TPM_RC)(RC_WARN + 0x023) #define TPM_RC_NOT_USED (TPM_RC)(RC_WARN + 0x7F) #define TPM_RC_H (TPM_RC)(0x000) #define TPM_RC_P (TPM_RC)(0x040) #define TPM_RC_S (TPM_RC)(0x800) #define TPM_RC_1 (TPM_RC)(0x100) #define TPM_RC_2 (TPM_RC)(0x200) #define TPM_RC_3 (TPM_RC)(0x300) #define TPM_RC_4 (TPM_RC)(0x400) #define TPM_RC_5 (TPM_RC)(0x500) #define TPM_RC_6 (TPM_RC)(0x600) #define TPM_RC_7 (TPM_RC)(0x700) #define TPM_RC_8 (TPM_RC)(0x800) #define TPM_RC_9 (TPM_RC)(0x900) #define TPM_RC_A (TPM_RC)(0xA00) #define TPM_RC_B (TPM_RC)(0xB00) #define TPM_RC_C (TPM_RC)(0xC00) #define TPM_RC_D (TPM_RC)(0xD00) #define TPM_RC_E (TPM_RC)(0xE00) #define TPM_RC_F (TPM_RC)(0xF00) #define TPM_RC_N_MASK (TPM_RC)(0xF00) // Table 16 - TPM_CLOCK_ADJUST Constants typedef INT8 TPM_CLOCK_ADJUST; #define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3) #define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2) #define TPM_CLOCK_FINE_SLOWER (TPM_CLOCK_ADJUST)(-1) #define TPM_CLOCK_NO_CHANGE (TPM_CLOCK_ADJUST)(0) #define TPM_CLOCK_FINE_FASTER (TPM_CLOCK_ADJUST)(1) #define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2) #define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3) // Table 17 - TPM_EO Constants typedef UINT16 TPM_EO; #define TPM_EO_EQ (TPM_EO)(0x0000) #define TPM_EO_NEQ (TPM_EO)(0x0001) #define TPM_EO_SIGNED_GT (TPM_EO)(0x0002) #define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003) #define TPM_EO_SIGNED_LT (TPM_EO)(0x0004) #define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005) #define TPM_EO_SIGNED_GE (TPM_EO)(0x0006) #define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007) #define TPM_EO_SIGNED_LE (TPM_EO)(0x0008) #define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009) #define TPM_EO_BITSET (TPM_EO)(0x000A) #define TPM_EO_BITCLEAR (TPM_EO)(0x000B) // Table 18 - TPM_ST Constants typedef UINT16 TPM_ST; #define TPM_ST_RSP_COMMAND (TPM_ST)(0x00C4) #define TPM_ST_NULL (TPM_ST)(0X8000) #define TPM_ST_NO_SESSIONS (TPM_ST)(0x8001) #define TPM_ST_SESSIONS (TPM_ST)(0x8002) #define TPM_ST_ATTEST_NV (TPM_ST)(0x8014) #define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015) #define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016) #define TPM_ST_ATTEST_CERTIFY (TPM_ST)(0x8017) #define TPM_ST_ATTEST_QUOTE (TPM_ST)(0x8018) #define TPM_ST_ATTEST_TIME (TPM_ST)(0x8019) #define TPM_ST_ATTEST_CREATION (TPM_ST)(0x801A) #define TPM_ST_CREATION (TPM_ST)(0x8021) #define TPM_ST_VERIFIED (TPM_ST)(0x8022) #define TPM_ST_AUTH_SECRET (TPM_ST)(0x8023) #define TPM_ST_HASHCHECK (TPM_ST)(0x8024) #define TPM_ST_AUTH_SIGNED (TPM_ST)(0x8025) #define TPM_ST_FU_MANIFEST (TPM_ST)(0x8029) // Table 19 - TPM_SU Constants typedef UINT16 TPM_SU; #define TPM_SU_CLEAR (TPM_SU)(0x0000) #define TPM_SU_STATE (TPM_SU)(0x0001) // Table 20 - TPM_SE Constants typedef UINT8 TPM_SE; #define TPM_SE_HMAC (TPM_SE)(0x00) #define TPM_SE_POLICY (TPM_SE)(0x01) #define TPM_SE_TRIAL (TPM_SE)(0x03) // Table 21 - TPM_CAP Constants typedef UINT32 TPM_CAP; #define TPM_CAP_FIRST (TPM_CAP)(0x00000000) #define TPM_CAP_ALGS (TPM_CAP)(0x00000000) #define TPM_CAP_HANDLES (TPM_CAP)(0x00000001) #define TPM_CAP_COMMANDS (TPM_CAP)(0x00000002) #define TPM_CAP_PP_COMMANDS (TPM_CAP)(0x00000003) #define TPM_CAP_AUDIT_COMMANDS (TPM_CAP)(0x00000004) #define TPM_CAP_PCRS (TPM_CAP)(0x00000005) #define TPM_CAP_TPM_PROPERTIES (TPM_CAP)(0x00000006) #define TPM_CAP_PCR_PROPERTIES (TPM_CAP)(0x00000007) #define TPM_CAP_ECC_CURVES (TPM_CAP)(0x00000008) #define TPM_CAP_LAST (TPM_CAP)(0x00000008) #define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100) // Table 22 - TPM_PT Constants typedef UINT32 TPM_PT; #define TPM_PT_NONE (TPM_PT)(0x00000000) #define PT_GROUP (TPM_PT)(0x00000100) #define PT_FIXED (TPM_PT)(PT_GROUP * 1) #define TPM_PT_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 0) #define TPM_PT_LEVEL (TPM_PT)(PT_FIXED + 1) #define TPM_PT_REVISION (TPM_PT)(PT_FIXED + 2) #define TPM_PT_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 3) #define TPM_PT_YEAR (TPM_PT)(PT_FIXED + 4) #define TPM_PT_MANUFACTURER (TPM_PT)(PT_FIXED + 5) #define TPM_PT_VENDOR_STRING_1 (TPM_PT)(PT_FIXED + 6) #define TPM_PT_VENDOR_STRING_2 (TPM_PT)(PT_FIXED + 7) #define TPM_PT_VENDOR_STRING_3 (TPM_PT)(PT_FIXED + 8) #define TPM_PT_VENDOR_STRING_4 (TPM_PT)(PT_FIXED + 9) #define TPM_PT_VENDOR_TPM_TYPE (TPM_PT)(PT_FIXED + 10) #define TPM_PT_FIRMWARE_VERSION_1 (TPM_PT)(PT_FIXED + 11) #define TPM_PT_FIRMWARE_VERSION_2 (TPM_PT)(PT_FIXED + 12) #define TPM_PT_INPUT_BUFFER (TPM_PT)(PT_FIXED + 13) #define TPM_PT_HR_TRANSIENT_MIN (TPM_PT)(PT_FIXED + 14) #define TPM_PT_HR_PERSISTENT_MIN (TPM_PT)(PT_FIXED + 15) #define TPM_PT_HR_LOADED_MIN (TPM_PT)(PT_FIXED + 16) #define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED + 17) #define TPM_PT_PCR_COUNT (TPM_PT)(PT_FIXED + 18) #define TPM_PT_PCR_SELECT_MIN (TPM_PT)(PT_FIXED + 19) #define TPM_PT_CONTEXT_GAP_MAX (TPM_PT)(PT_FIXED + 20) #define TPM_PT_NV_COUNTERS_MAX (TPM_PT)(PT_FIXED + 22) #define TPM_PT_NV_INDEX_MAX (TPM_PT)(PT_FIXED + 23) #define TPM_PT_MEMORY (TPM_PT)(PT_FIXED + 24) #define TPM_PT_CLOCK_UPDATE (TPM_PT)(PT_FIXED + 25) #define TPM_PT_CONTEXT_HASH (TPM_PT)(PT_FIXED + 26) #define TPM_PT_CONTEXT_SYM (TPM_PT)(PT_FIXED + 27) #define TPM_PT_CONTEXT_SYM_SIZE (TPM_PT)(PT_FIXED + 28) #define TPM_PT_ORDERLY_COUNT (TPM_PT)(PT_FIXED + 29) #define TPM_PT_MAX_COMMAND_SIZE (TPM_PT)(PT_FIXED + 30) #define TPM_PT_MAX_RESPONSE_SIZE (TPM_PT)(PT_FIXED + 31) #define TPM_PT_MAX_DIGEST (TPM_PT)(PT_FIXED + 32) #define TPM_PT_MAX_OBJECT_CONTEXT (TPM_PT)(PT_FIXED + 33) #define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED + 34) #define TPM_PT_PS_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 35) #define TPM_PT_PS_LEVEL (TPM_PT)(PT_FIXED + 36) #define TPM_PT_PS_REVISION (TPM_PT)(PT_FIXED + 37) #define TPM_PT_PS_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 38) #define TPM_PT_PS_YEAR (TPM_PT)(PT_FIXED + 39) #define TPM_PT_SPLIT_MAX (TPM_PT)(PT_FIXED + 40) #define TPM_PT_TOTAL_COMMANDS (TPM_PT)(PT_FIXED + 41) #define TPM_PT_LIBRARY_COMMANDS (TPM_PT)(PT_FIXED + 42) #define TPM_PT_VENDOR_COMMANDS (TPM_PT)(PT_FIXED + 43) #define PT_VAR (TPM_PT)(PT_GROUP * 2) #define TPM_PT_PERMANENT (TPM_PT)(PT_VAR + 0) #define TPM_PT_STARTUP_CLEAR (TPM_PT)(PT_VAR + 1) #define TPM_PT_HR_NV_INDEX (TPM_PT)(PT_VAR + 2) #define TPM_PT_HR_LOADED (TPM_PT)(PT_VAR + 3) #define TPM_PT_HR_LOADED_AVAIL (TPM_PT)(PT_VAR + 4) #define TPM_PT_HR_ACTIVE (TPM_PT)(PT_VAR + 5) #define TPM_PT_HR_ACTIVE_AVAIL (TPM_PT)(PT_VAR + 6) #define TPM_PT_HR_TRANSIENT_AVAIL (TPM_PT)(PT_VAR + 7) #define TPM_PT_HR_PERSISTENT (TPM_PT)(PT_VAR + 8) #define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR + 9) #define TPM_PT_NV_COUNTERS (TPM_PT)(PT_VAR + 10) #define TPM_PT_NV_COUNTERS_AVAIL (TPM_PT)(PT_VAR + 11) #define TPM_PT_ALGORITHM_SET (TPM_PT)(PT_VAR + 12) #define TPM_PT_LOADED_CURVES (TPM_PT)(PT_VAR + 13) #define TPM_PT_LOCKOUT_COUNTER (TPM_PT)(PT_VAR + 14) #define TPM_PT_MAX_AUTH_FAIL (TPM_PT)(PT_VAR + 15) #define TPM_PT_LOCKOUT_INTERVAL (TPM_PT)(PT_VAR + 16) #define TPM_PT_LOCKOUT_RECOVERY (TPM_PT)(PT_VAR + 17) #define TPM_PT_NV_WRITE_RECOVERY (TPM_PT)(PT_VAR + 18) #define TPM_PT_AUDIT_COUNTER_0 (TPM_PT)(PT_VAR + 19) #define TPM_PT_AUDIT_COUNTER_1 (TPM_PT)(PT_VAR + 20) // Table 23 - TPM_PT_PCR Constants typedef UINT32 TPM_PT_PCR; #define TPM_PT_PCR_FIRST (TPM_PT_PCR)(0x00000000) #define TPM_PT_PCR_SAVE (TPM_PT_PCR)(0x00000000) #define TPM_PT_PCR_EXTEND_L0 (TPM_PT_PCR)(0x00000001) #define TPM_PT_PCR_RESET_L0 (TPM_PT_PCR)(0x00000002) #define TPM_PT_PCR_EXTEND_L1 (TPM_PT_PCR)(0x00000003) #define TPM_PT_PCR_RESET_L1 (TPM_PT_PCR)(0x00000004) #define TPM_PT_PCR_EXTEND_L2 (TPM_PT_PCR)(0x00000005) #define TPM_PT_PCR_RESET_L2 (TPM_PT_PCR)(0x00000006) #define TPM_PT_PCR_EXTEND_L3 (TPM_PT_PCR)(0x00000007) #define TPM_PT_PCR_RESET_L3 (TPM_PT_PCR)(0x00000008) #define TPM_PT_PCR_EXTEND_L4 (TPM_PT_PCR)(0x00000009) #define TPM_PT_PCR_RESET_L4 (TPM_PT_PCR)(0x0000000A) #define TPM_PT_PCR_NO_INCREMENT (TPM_PT_PCR)(0x00000011) #define TPM_PT_PCR_DRTM_RESET (TPM_PT_PCR)(0x00000012) #define TPM_PT_PCR_POLICY (TPM_PT_PCR)(0x00000013) #define TPM_PT_PCR_AUTH (TPM_PT_PCR)(0x00000014) #define TPM_PT_PCR_LAST (TPM_PT_PCR)(0x00000014) // Table 24 - TPM_PS Constants typedef UINT32 TPM_PS; #define TPM_PS_MAIN (TPM_PS)(0x00000000) #define TPM_PS_PC (TPM_PS)(0x00000001) #define TPM_PS_PDA (TPM_PS)(0x00000002) #define TPM_PS_CELL_PHONE (TPM_PS)(0x00000003) #define TPM_PS_SERVER (TPM_PS)(0x00000004) #define TPM_PS_PERIPHERAL (TPM_PS)(0x00000005) #define TPM_PS_TSS (TPM_PS)(0x00000006) #define TPM_PS_STORAGE (TPM_PS)(0x00000007) #define TPM_PS_AUTHENTICATION (TPM_PS)(0x00000008) #define TPM_PS_EMBEDDED (TPM_PS)(0x00000009) #define TPM_PS_HARDCOPY (TPM_PS)(0x0000000A) #define TPM_PS_INFRASTRUCTURE (TPM_PS)(0x0000000B) #define TPM_PS_VIRTUALIZATION (TPM_PS)(0x0000000C) #define TPM_PS_TNC (TPM_PS)(0x0000000D) #define TPM_PS_MULTI_TENANT (TPM_PS)(0x0000000E) #define TPM_PS_TC (TPM_PS)(0x0000000F) // 7 Handles // Table 25 - Handles Types // // NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue) // // typedef UINT32 TPM_HANDLE; // Table 26 - TPM_HT Constants typedef UINT8 TPM_HT; #define TPM_HT_PCR (TPM_HT)(0x00) #define TPM_HT_NV_INDEX (TPM_HT)(0x01) #define TPM_HT_HMAC_SESSION (TPM_HT)(0x02) #define TPM_HT_LOADED_SESSION (TPM_HT)(0x02) #define TPM_HT_POLICY_SESSION (TPM_HT)(0x03) #define TPM_HT_ACTIVE_SESSION (TPM_HT)(0x03) #define TPM_HT_PERMANENT (TPM_HT)(0x40) #define TPM_HT_TRANSIENT (TPM_HT)(0x80) #define TPM_HT_PERSISTENT (TPM_HT)(0x81) // Table 27 - TPM_RH Constants typedef UINT32 TPM_RH; #define TPM_RH_FIRST (TPM_RH)(0x40000000) #define TPM_RH_SRK (TPM_RH)(0x40000000) #define TPM_RH_OWNER (TPM_RH)(0x40000001) #define TPM_RH_REVOKE (TPM_RH)(0x40000002) #define TPM_RH_TRANSPORT (TPM_RH)(0x40000003) #define TPM_RH_OPERATOR (TPM_RH)(0x40000004) #define TPM_RH_ADMIN (TPM_RH)(0x40000005) #define TPM_RH_EK (TPM_RH)(0x40000006) #define TPM_RH_NULL (TPM_RH)(0x40000007) #define TPM_RH_UNASSIGNED (TPM_RH)(0x40000008) #define TPM_RS_PW (TPM_RH)(0x40000009) #define TPM_RH_LOCKOUT (TPM_RH)(0x4000000A) #define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B) #define TPM_RH_PLATFORM (TPM_RH)(0x4000000C) #define TPM_RH_PLATFORM_NV (TPM_RH)(0x4000000D) #define TPM_RH_AUTH_00 (TPM_RH)(0x40000010) #define TPM_RH_AUTH_FF (TPM_RH)(0x4000010F) #define TPM_RH_LAST (TPM_RH)(0x4000010F) // Table 28 - TPM_HC Constants typedef TPM_HANDLE TPM_HC; #define HR_HANDLE_MASK (TPM_HC)(0x00FFFFFF) #define HR_RANGE_MASK (TPM_HC)(0xFF000000) #define HR_SHIFT (TPM_HC)(24) #define HR_PCR (TPM_HC)((TPM_HC)TPM_HT_PCR << HR_SHIFT) #define HR_HMAC_SESSION (TPM_HC)((TPM_HC)TPM_HT_HMAC_SESSION << HR_SHIFT) #define HR_POLICY_SESSION (TPM_HC)((TPM_HC)TPM_HT_POLICY_SESSION << HR_SHIFT) #define HR_TRANSIENT (TPM_HC)((TPM_HC)TPM_HT_TRANSIENT << HR_SHIFT) #define HR_PERSISTENT (TPM_HC)((TPM_HC)TPM_HT_PERSISTENT << HR_SHIFT) #define HR_NV_INDEX (TPM_HC)((TPM_HC)TPM_HT_NV_INDEX << HR_SHIFT) #define HR_PERMANENT (TPM_HC)((TPM_HC)TPM_HT_PERMANENT << HR_SHIFT) #define PCR_FIRST (TPM_HC)(HR_PCR + 0) #define PCR_LAST (TPM_HC)(PCR_FIRST + IMPLEMENTATION_PCR - 1) #define HMAC_SESSION_FIRST (TPM_HC)(HR_HMAC_SESSION + 0) #define HMAC_SESSION_LAST (TPM_HC)(HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1) #define LOADED_SESSION_FIRST (TPM_HC)(HMAC_SESSION_FIRST) #define LOADED_SESSION_LAST (TPM_HC)(HMAC_SESSION_LAST) #define POLICY_SESSION_FIRST (TPM_HC)(HR_POLICY_SESSION + 0) #define POLICY_SESSION_LAST (TPM_HC)(POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1) #define TRANSIENT_FIRST (TPM_HC)(HR_TRANSIENT + 0) #define ACTIVE_SESSION_FIRST (TPM_HC)(POLICY_SESSION_FIRST) #define ACTIVE_SESSION_LAST (TPM_HC)(POLICY_SESSION_LAST) #define TRANSIENT_LAST (TPM_HC)(TRANSIENT_FIRST+MAX_LOADED_OBJECTS - 1) #define PERSISTENT_FIRST (TPM_HC)(HR_PERSISTENT + 0) #define PERSISTENT_LAST (TPM_HC)(PERSISTENT_FIRST + 0x00FFFFFF) #define PLATFORM_PERSISTENT (TPM_HC)(PERSISTENT_FIRST + 0x00800000) #define NV_INDEX_FIRST (TPM_HC)(HR_NV_INDEX + 0) #define NV_INDEX_LAST (TPM_HC)(NV_INDEX_FIRST + 0x00FFFFFF) #define PERMANENT_FIRST (TPM_HC)(TPM_RH_FIRST) #define PERMANENT_LAST (TPM_HC)(TPM_RH_LAST) // 8 Attribute Structures // Table 29 - TPMA_ALGORITHM Bits typedef struct { UINT32 asymmetric : 1; UINT32 symmetric : 1; UINT32 hash : 1; UINT32 object : 1; UINT32 reserved4_7 : 4; UINT32 signing : 1; UINT32 encrypting : 1; UINT32 method : 1; UINT32 reserved11_31 : 21; } TPMA_ALGORITHM; // Table 30 - TPMA_OBJECT Bits typedef struct { UINT32 reserved1 : 1; UINT32 fixedTPM : 1; UINT32 stClear : 1; UINT32 reserved4 : 1; UINT32 fixedParent : 1; UINT32 sensitiveDataOrigin : 1; UINT32 userWithAuth : 1; UINT32 adminWithPolicy : 1; UINT32 reserved8_9 : 2; UINT32 noDA : 1; UINT32 encryptedDuplication : 1; UINT32 reserved12_15 : 4; UINT32 restricted : 1; UINT32 decrypt : 1; UINT32 sign : 1; UINT32 reserved19_31 : 13; } TPMA_OBJECT; // Table 31 - TPMA_SESSION Bits typedef struct { UINT8 continueSession : 1; UINT8 auditExclusive : 1; UINT8 auditReset : 1; UINT8 reserved3_4 : 2; UINT8 decrypt : 1; UINT8 encrypt : 1; UINT8 audit : 1; } TPMA_SESSION; // Table 32 - TPMA_LOCALITY Bits // // NOTE: Use low case here to resolve conflict // typedef struct { UINT8 locZero : 1; UINT8 locOne : 1; UINT8 locTwo : 1; UINT8 locThree : 1; UINT8 locFour : 1; UINT8 Extended : 3; } TPMA_LOCALITY; // Table 33 - TPMA_PERMANENT Bits typedef struct { UINT32 ownerAuthSet : 1; UINT32 endorsementAuthSet : 1; UINT32 lockoutAuthSet : 1; UINT32 reserved3_7 : 5; UINT32 disableClear : 1; UINT32 inLockout : 1; UINT32 tpmGeneratedEPS : 1; UINT32 reserved11_31 : 21; } TPMA_PERMANENT; // Table 34 - TPMA_STARTUP_CLEAR Bits typedef struct { UINT32 phEnable : 1; UINT32 shEnable : 1; UINT32 ehEnable : 1; UINT32 reserved3_30 : 28; UINT32 orderly : 1; } TPMA_STARTUP_CLEAR; // Table 35 - TPMA_MEMORY Bits typedef struct { UINT32 sharedRAM : 1; UINT32 sharedNV : 1; UINT32 objectCopiedToRam : 1; UINT32 reserved3_31 : 29; } TPMA_MEMORY; // Table 36 - TPMA_CC Bits typedef struct { UINT32 commandIndex : 16; UINT32 reserved16_21 : 6; UINT32 nv : 1; UINT32 extensive : 1; UINT32 flushed : 1; UINT32 cHandles : 3; UINT32 rHandle : 1; UINT32 V : 1; UINT32 Res : 2; } TPMA_CC; // 9 Interface Types // Table 37 - TPMI_YES_NO Type typedef BYTE TPMI_YES_NO; // Table 38 - TPMI_DH_OBJECT Type typedef TPM_HANDLE TPMI_DH_OBJECT; // Table 39 - TPMI_DH_PERSISTENT Type typedef TPM_HANDLE TPMI_DH_PERSISTENT; // Table 40 - TPMI_DH_ENTITY Type typedef TPM_HANDLE TPMI_DH_ENTITY; // Table 41 - TPMI_DH_PCR Type typedef TPM_HANDLE TPMI_DH_PCR; // Table 42 - TPMI_SH_AUTH_SESSION Type typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; // Table 43 - TPMI_SH_HMAC Type typedef TPM_HANDLE TPMI_SH_HMAC; // Table 44 - TPMI_SH_POLICY Type typedef TPM_HANDLE TPMI_SH_POLICY; // Table 45 - TPMI_DH_CONTEXT Type typedef TPM_HANDLE TPMI_DH_CONTEXT; // Table 46 - TPMI_RH_HIERARCHY Type typedef TPM_HANDLE TPMI_RH_HIERARCHY; // Table 47 - TPMI_RH_HIERARCHY_AUTH Type typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH; // Table 48 - TPMI_RH_PLATFORM Type typedef TPM_HANDLE TPMI_RH_PLATFORM; // Table 49 - TPMI_RH_OWNER Type typedef TPM_HANDLE TPMI_RH_OWNER; // Table 50 - TPMI_RH_ENDORSEMENT Type typedef TPM_HANDLE TPMI_RH_ENDORSEMENT; // Table 51 - TPMI_RH_PROVISION Type typedef TPM_HANDLE TPMI_RH_PROVISION; // Table 52 - TPMI_RH_CLEAR Type typedef TPM_HANDLE TPMI_RH_CLEAR; // Table 53 - TPMI_RH_NV_AUTH Type typedef TPM_HANDLE TPMI_RH_NV_AUTH; // Table 54 - TPMI_RH_LOCKOUT Type typedef TPM_HANDLE TPMI_RH_LOCKOUT; // Table 55 - TPMI_RH_NV_INDEX Type typedef TPM_HANDLE TPMI_RH_NV_INDEX; // Table 56 - TPMI_ALG_HASH Type typedef TPM_ALG_ID TPMI_ALG_HASH; // Table 57 - TPMI_ALG_ASYM Type typedef TPM_ALG_ID TPMI_ALG_ASYM; // Table 58 - TPMI_ALG_SYM Type typedef TPM_ALG_ID TPMI_ALG_SYM; // Table 59 - TPMI_ALG_SYM_OBJECT Type typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT; // Table 60 - TPMI_ALG_SYM_MODE Type typedef TPM_ALG_ID TPMI_ALG_SYM_MODE; // Table 61 - TPMI_ALG_KDF Type typedef TPM_ALG_ID TPMI_ALG_KDF; // Table 62 - TPMI_ALG_SIG_SCHEME Type typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; // Table 63 - TPMI_ECC_KEY_EXCHANGE Type typedef TPM_ALG_ID TPMI_ECC_KEY_EXCHANGE; // Table 64 - TPMI_ST_COMMAND_TAG Type typedef TPM_ST TPMI_ST_COMMAND_TAG; // 10 Structure Definitions // Table 65 - TPMS_ALGORITHM_DESCRIPTION Structure typedef struct { TPM_ALG_ID alg; TPMA_ALGORITHM attributes; } TPMS_ALGORITHM_DESCRIPTION; // Table 66 - TPMU_HA Union typedef union { BYTE sha1[SHA1_DIGEST_SIZE]; BYTE sha256[SHA256_DIGEST_SIZE]; BYTE sm3_256[SM3_256_DIGEST_SIZE]; BYTE sha384[SHA384_DIGEST_SIZE]; BYTE sha512[SHA512_DIGEST_SIZE]; } TPMU_HA; // Table 67 - TPMT_HA Structure typedef struct { TPMI_ALG_HASH hashAlg; TPMU_HA digest; } TPMT_HA; // Table 68 - TPM2B_DIGEST Structure typedef struct { UINT16 size; BYTE buffer[sizeof (TPMU_HA)]; } TPM2B_DIGEST; // Table 69 - TPM2B_DATA Structure typedef struct { UINT16 size; BYTE buffer[sizeof (TPMT_HA)]; } TPM2B_DATA; // Table 70 - TPM2B_NONCE Types typedef TPM2B_DIGEST TPM2B_NONCE; // Table 71 - TPM2B_AUTH Types typedef TPM2B_DIGEST TPM2B_AUTH; // Table 72 - TPM2B_OPERAND Types typedef TPM2B_DIGEST TPM2B_OPERAND; // Table 73 - TPM2B_EVENT Structure typedef struct { UINT16 size; BYTE buffer[1024]; } TPM2B_EVENT; // Table 74 - TPM2B_MAX_BUFFER Structure typedef struct { UINT16 size; BYTE buffer[MAX_DIGEST_BUFFER]; } TPM2B_MAX_BUFFER; // Table 75 - TPM2B_MAX_NV_BUFFER Structure typedef struct { UINT16 size; BYTE buffer[MAX_NV_INDEX_SIZE]; } TPM2B_MAX_NV_BUFFER; // Table 76 - TPM2B_TIMEOUT Structure typedef struct { UINT16 size; BYTE buffer[sizeof (UINT64)]; } TPM2B_TIMEOUT; // Table 77 -- TPM2B_IV Structure typedef struct { UINT16 size; BYTE buffer[MAX_SYM_BLOCK_SIZE]; } TPM2B_IV; // Table 78 - TPMU_NAME Union typedef union { TPMT_HA digest; TPM_HANDLE handle; } TPMU_NAME; // Table 79 - TPM2B_NAME Structure typedef struct { UINT16 size; BYTE name[sizeof (TPMU_NAME)]; } TPM2B_NAME; // Table 80 - TPMS_PCR_SELECT Structure typedef struct { UINT8 sizeofSelect; BYTE pcrSelect[PCR_SELECT_MAX]; } TPMS_PCR_SELECT; // Table 81 - TPMS_PCR_SELECTION Structure typedef struct { TPMI_ALG_HASH hash; UINT8 sizeofSelect; BYTE pcrSelect[PCR_SELECT_MAX]; } TPMS_PCR_SELECTION; // Table 84 - TPMT_TK_CREATION Structure typedef struct { TPM_ST tag; TPMI_RH_HIERARCHY hierarchy; TPM2B_DIGEST digest; } TPMT_TK_CREATION; // Table 85 - TPMT_TK_VERIFIED Structure typedef struct { TPM_ST tag; TPMI_RH_HIERARCHY hierarchy; TPM2B_DIGEST digest; } TPMT_TK_VERIFIED; // Table 86 - TPMT_TK_AUTH Structure typedef struct { TPM_ST tag; TPMI_RH_HIERARCHY hierarchy; TPM2B_DIGEST digest; } TPMT_TK_AUTH; // Table 87 - TPMT_TK_HASHCHECK Structure typedef struct { TPM_ST tag; TPMI_RH_HIERARCHY hierarchy; TPM2B_DIGEST digest; } TPMT_TK_HASHCHECK; // Table 88 - TPMS_ALG_PROPERTY Structure typedef struct { TPM_ALG_ID alg; TPMA_ALGORITHM algProperties; } TPMS_ALG_PROPERTY; // Table 89 - TPMS_TAGGED_PROPERTY Structure typedef struct { TPM_PT property; UINT32 value; } TPMS_TAGGED_PROPERTY; // Table 90 - TPMS_TAGGED_PCR_SELECT Structure typedef struct { TPM_PT tag; UINT8 sizeofSelect; BYTE pcrSelect[PCR_SELECT_MAX]; } TPMS_TAGGED_PCR_SELECT; // Table 91 - TPML_CC Structure typedef struct { UINT32 count; TPM_CC commandCodes[MAX_CAP_CC]; } TPML_CC; // Table 92 - TPML_CCA Structure typedef struct { UINT32 count; TPMA_CC commandAttributes[MAX_CAP_CC]; } TPML_CCA; // Table 93 - TPML_ALG Structure typedef struct { UINT32 count; TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE]; } TPML_ALG; // Table 94 - TPML_HANDLE Structure typedef struct { UINT32 count; TPM_HANDLE handle[MAX_CAP_HANDLES]; } TPML_HANDLE; // Table 95 - TPML_DIGEST Structure typedef struct { UINT32 count; TPM2B_DIGEST digests[8]; } TPML_DIGEST; // Table 96 -- TPML_DIGEST_VALUES Structure typedef struct { UINT32 count; TPMT_HA digests[HASH_COUNT]; } TPML_DIGEST_VALUES; // Table 97 - TPM2B_DIGEST_VALUES Structure typedef struct { UINT16 size; BYTE buffer[sizeof (TPML_DIGEST_VALUES)]; } TPM2B_DIGEST_VALUES; // Table 98 - TPML_PCR_SELECTION Structure typedef struct { UINT32 count; TPMS_PCR_SELECTION pcrSelections[HASH_COUNT]; } TPML_PCR_SELECTION; // Table 99 - TPML_ALG_PROPERTY Structure typedef struct { UINT32 count; TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS]; } TPML_ALG_PROPERTY; // Table 100 - TPML_TAGGED_TPM_PROPERTY Structure typedef struct { UINT32 count; TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES]; } TPML_TAGGED_TPM_PROPERTY; // Table 101 - TPML_TAGGED_PCR_PROPERTY Structure typedef struct { UINT32 count; TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES]; } TPML_TAGGED_PCR_PROPERTY; // Table 102 - TPML_ECC_CURVE Structure typedef struct { UINT32 count; TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES]; } TPML_ECC_CURVE; // Table 103 - TPMU_CAPABILITIES Union typedef union { TPML_ALG_PROPERTY algorithms; TPML_HANDLE handles; TPML_CCA command; TPML_CC ppCommands; TPML_CC auditCommands; TPML_PCR_SELECTION assignedPCR; TPML_TAGGED_TPM_PROPERTY tpmProperties; TPML_TAGGED_PCR_PROPERTY pcrProperties; TPML_ECC_CURVE eccCurves; } TPMU_CAPABILITIES; // Table 104 - TPMS_CAPABILITY_DATA Structure typedef struct { TPM_CAP capability; TPMU_CAPABILITIES data; } TPMS_CAPABILITY_DATA; // Table 105 - TPMS_CLOCK_INFO Structure typedef struct { UINT64 clock; UINT32 resetCount; UINT32 restartCount; TPMI_YES_NO safe; } TPMS_CLOCK_INFO; // Table 106 - TPMS_TIME_INFO Structure typedef struct { UINT64 time; TPMS_CLOCK_INFO clockInfo; } TPMS_TIME_INFO; // Table 107 - TPMS_TIME_ATTEST_INFO Structure typedef struct { TPMS_TIME_INFO time; UINT64 firmwareVersion; } TPMS_TIME_ATTEST_INFO; // Table 108 - TPMS_CERTIFY_INFO Structure typedef struct { TPM2B_NAME name; TPM2B_NAME qualifiedName; } TPMS_CERTIFY_INFO; // Table 109 - TPMS_QUOTE_INFO Structure typedef struct { TPML_PCR_SELECTION pcrSelect; TPM2B_DIGEST pcrDigest; } TPMS_QUOTE_INFO; // Table 110 - TPMS_COMMAND_AUDIT_INFO Structure typedef struct { UINT64 auditCounter; TPM_ALG_ID digestAlg; TPM2B_DIGEST auditDigest; TPM2B_DIGEST commandDigest; } TPMS_COMMAND_AUDIT_INFO; // Table 111 - TPMS_SESSION_AUDIT_INFO Structure typedef struct { TPMI_YES_NO exclusiveSession; TPM2B_DIGEST sessionDigest; } TPMS_SESSION_AUDIT_INFO; // Table 112 - TPMS_CREATION_INFO Structure typedef struct { TPM2B_NAME objectName; TPM2B_DIGEST creationHash; } TPMS_CREATION_INFO; // Table 113 - TPMS_NV_CERTIFY_INFO Structure typedef struct { TPM2B_NAME indexName; UINT16 offset; TPM2B_MAX_NV_BUFFER nvContents; } TPMS_NV_CERTIFY_INFO; // Table 114 - TPMI_ST_ATTEST Type typedef TPM_ST TPMI_ST_ATTEST; // Table 115 - TPMU_ATTEST Union typedef union { TPMS_CERTIFY_INFO certify; TPMS_CREATION_INFO creation; TPMS_QUOTE_INFO quote; TPMS_COMMAND_AUDIT_INFO commandAudit; TPMS_SESSION_AUDIT_INFO sessionAudit; TPMS_TIME_ATTEST_INFO time; TPMS_NV_CERTIFY_INFO nv; } TPMU_ATTEST; // Table 116 - TPMS_ATTEST Structure typedef struct { TPM_GENERATED magic; TPMI_ST_ATTEST type; TPM2B_NAME qualifiedSigner; TPM2B_DATA extraData; TPMS_CLOCK_INFO clockInfo; UINT64 firmwareVersion; TPMU_ATTEST attested; } TPMS_ATTEST; // Table 117 - TPM2B_ATTEST Structure typedef struct { UINT16 size; BYTE attestationData[sizeof (TPMS_ATTEST)]; } TPM2B_ATTEST; // Table 118 - TPMS_AUTH_COMMAND Structure typedef struct { TPMI_SH_AUTH_SESSION sessionHandle; TPM2B_NONCE nonce; TPMA_SESSION sessionAttributes; TPM2B_AUTH hmac; } TPMS_AUTH_COMMAND; // Table 119 - TPMS_AUTH_RESPONSE Structure typedef struct { TPM2B_NONCE nonce; TPMA_SESSION sessionAttributes; TPM2B_AUTH hmac; } TPMS_AUTH_RESPONSE; // 11 Algorithm Parameters and Structures // Table 120 - TPMI_AES_KEY_BITS Type typedef TPM_KEY_BITS TPMI_AES_KEY_BITS; // Table 121 - TPMI_SM4_KEY_BITS Type typedef TPM_KEY_BITS TPMI_SM4_KEY_BITS; // Table 122 - TPMU_SYM_KEY_BITS Union typedef union { TPMI_AES_KEY_BITS aes; TPMI_SM4_KEY_BITS SM4; TPM_KEY_BITS sym; TPMI_ALG_HASH xor; } TPMU_SYM_KEY_BITS; // Table 123 - TPMU_SYM_MODE Union typedef union { TPMI_ALG_SYM_MODE aes; TPMI_ALG_SYM_MODE SM4; TPMI_ALG_SYM_MODE sym; } TPMU_SYM_MODE; // Table 125 - TPMT_SYM_DEF Structure typedef struct { TPMI_ALG_SYM algorithm; TPMU_SYM_KEY_BITS keyBits; TPMU_SYM_MODE mode; } TPMT_SYM_DEF; // Table 126 - TPMT_SYM_DEF_OBJECT Structure typedef struct { TPMI_ALG_SYM_OBJECT algorithm; TPMU_SYM_KEY_BITS keyBits; TPMU_SYM_MODE mode; } TPMT_SYM_DEF_OBJECT; // Table 127 - TPM2B_SYM_KEY Structure typedef struct { UINT16 size; BYTE buffer[MAX_SYM_KEY_BYTES]; } TPM2B_SYM_KEY; // Table 128 - TPMS_SYMCIPHER_PARMS Structure typedef struct { TPMT_SYM_DEF_OBJECT sym; } TPMS_SYMCIPHER_PARMS; // Table 129 - TPM2B_SENSITIVE_DATA Structure typedef struct { UINT16 size; BYTE buffer[MAX_SYM_DATA]; } TPM2B_SENSITIVE_DATA; // Table 130 - TPMS_SENSITIVE_CREATE Structure typedef struct { TPM2B_AUTH userAuth; TPM2B_SENSITIVE_DATA data; } TPMS_SENSITIVE_CREATE; // Table 131 - TPM2B_SENSITIVE_CREATE Structure typedef struct { UINT16 size; TPMS_SENSITIVE_CREATE sensitive; } TPM2B_SENSITIVE_CREATE; // Table 132 - TPMS_SCHEME_SIGHASH Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_SIGHASH; // Table 133 - TPMI_ALG_KEYEDHASH_SCHEME Type typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME; // Table 134 - HMAC_SIG_SCHEME Types typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_HMAC; // Table 135 - TPMS_SCHEME_XOR Structure typedef struct { TPMI_ALG_HASH hashAlg; TPMI_ALG_KDF kdf; } TPMS_SCHEME_XOR; // Table 136 - TPMU_SCHEME_KEYEDHASH Union typedef union { TPMS_SCHEME_HMAC hmac; TPMS_SCHEME_XOR xor; } TPMU_SCHEME_KEYEDHASH; // Table 137 - TPMT_KEYEDHASH_SCHEME Structure typedef struct { TPMI_ALG_KEYEDHASH_SCHEME scheme; TPMU_SCHEME_KEYEDHASH details; } TPMT_KEYEDHASH_SCHEME; // Table 138 - RSA_SIG_SCHEMES Types typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSASSA; typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSAPSS; // Table 139 - ECC_SIG_SCHEMES Types typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECDSA; typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_SM2; typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECSCHNORR; // Table 140 - TPMS_SCHEME_ECDAA Structure typedef struct { TPMI_ALG_HASH hashAlg; UINT16 count; } TPMS_SCHEME_ECDAA; // Table 141 - TPMU_SIG_SCHEME Union typedef union { TPMS_SCHEME_RSASSA rsassa; TPMS_SCHEME_RSAPSS rsapss; TPMS_SCHEME_ECDSA ecdsa; TPMS_SCHEME_ECDAA ecdaa; TPMS_SCHEME_ECSCHNORR ecSchnorr; TPMS_SCHEME_HMAC hmac; TPMS_SCHEME_SIGHASH any; } TPMU_SIG_SCHEME; // Table 142 - TPMT_SIG_SCHEME Structure typedef struct { TPMI_ALG_SIG_SCHEME scheme; TPMU_SIG_SCHEME details; } TPMT_SIG_SCHEME; // Table 143 - TPMS_SCHEME_OAEP Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_OAEP; // Table 144 - TPMS_SCHEME_ECDH Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_ECDH; // Table 145 - TPMS_SCHEME_MGF1 Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_MGF1; // Table 146 - TPMS_SCHEME_KDF1_SP800_56a Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_KDF1_SP800_56a; // Table 147 - TPMS_SCHEME_KDF2 Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_KDF2; // Table 148 - TPMS_SCHEME_KDF1_SP800_108 Structure typedef struct { TPMI_ALG_HASH hashAlg; } TPMS_SCHEME_KDF1_SP800_108; // Table 149 - TPMU_KDF_SCHEME Union typedef union { TPMS_SCHEME_MGF1 mgf1; TPMS_SCHEME_KDF1_SP800_56a kdf1_SP800_56a; TPMS_SCHEME_KDF2 kdf2; TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108; } TPMU_KDF_SCHEME; // Table 150 - TPMT_KDF_SCHEME Structure typedef struct { TPMI_ALG_KDF scheme; TPMU_KDF_SCHEME details; } TPMT_KDF_SCHEME; // Table 151 - TPMI_ALG_ASYM_SCHEME Type typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; // Table 152 - TPMU_ASYM_SCHEME Union typedef union { TPMS_SCHEME_RSASSA rsassa; TPMS_SCHEME_RSAPSS rsapss; TPMS_SCHEME_OAEP oaep; TPMS_SCHEME_ECDSA ecdsa; TPMS_SCHEME_ECDAA ecdaa; TPMS_SCHEME_ECSCHNORR ecSchnorr; TPMS_SCHEME_SIGHASH anySig; } TPMU_ASYM_SCHEME; // Table 153 - TPMT_ASYM_SCHEME Structure typedef struct { TPMI_ALG_ASYM_SCHEME scheme; TPMU_ASYM_SCHEME details; } TPMT_ASYM_SCHEME; // Table 154 - TPMI_ALG_RSA_SCHEME Type typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; // Table 155 - TPMT_RSA_SCHEME Structure typedef struct { TPMI_ALG_RSA_SCHEME scheme; TPMU_ASYM_SCHEME details; } TPMT_RSA_SCHEME; // Table 156 - TPMI_ALG_RSA_DECRYPT Type typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT; // Table 157 - TPMT_RSA_DECRYPT Structure typedef struct { TPMI_ALG_RSA_DECRYPT scheme; TPMU_ASYM_SCHEME details; } TPMT_RSA_DECRYPT; // Table 158 - TPM2B_PUBLIC_KEY_RSA Structure typedef struct { UINT16 size; BYTE buffer[MAX_RSA_KEY_BYTES]; } TPM2B_PUBLIC_KEY_RSA; // Table 159 - TPMI_RSA_KEY_BITS Type typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS; // Table 160 - TPM2B_PRIVATE_KEY_RSA Structure typedef struct { UINT16 size; BYTE buffer[MAX_RSA_KEY_BYTES/2]; } TPM2B_PRIVATE_KEY_RSA; // Table 161 - TPM2B_ECC_PARAMETER Structure typedef struct { UINT16 size; BYTE buffer[MAX_ECC_KEY_BYTES]; } TPM2B_ECC_PARAMETER; // Table 162 - TPMS_ECC_POINT Structure typedef struct { TPM2B_ECC_PARAMETER x; TPM2B_ECC_PARAMETER y; } TPMS_ECC_POINT; // Table 163 -- TPM2B_ECC_POINT Structure typedef struct { UINT16 size; TPMS_ECC_POINT point; } TPM2B_ECC_POINT; // Table 164 - TPMI_ALG_ECC_SCHEME Type typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; // Table 165 - TPMI_ECC_CURVE Type typedef TPM_ECC_CURVE TPMI_ECC_CURVE; // Table 166 - TPMT_ECC_SCHEME Structure typedef struct { TPMI_ALG_ECC_SCHEME scheme; TPMU_SIG_SCHEME details; } TPMT_ECC_SCHEME; // Table 167 - TPMS_ALGORITHM_DETAIL_ECC Structure typedef struct { TPM_ECC_CURVE curveID; UINT16 keySize; TPMT_KDF_SCHEME kdf; TPMT_ECC_SCHEME sign; TPM2B_ECC_PARAMETER p; TPM2B_ECC_PARAMETER a; TPM2B_ECC_PARAMETER b; TPM2B_ECC_PARAMETER gX; TPM2B_ECC_PARAMETER gY; TPM2B_ECC_PARAMETER n; TPM2B_ECC_PARAMETER h; } TPMS_ALGORITHM_DETAIL_ECC; // Table 168 - TPMS_SIGNATURE_RSASSA Structure typedef struct { TPMI_ALG_HASH hash; TPM2B_PUBLIC_KEY_RSA sig; } TPMS_SIGNATURE_RSASSA; // Table 169 - TPMS_SIGNATURE_RSAPSS Structure typedef struct { TPMI_ALG_HASH hash; TPM2B_PUBLIC_KEY_RSA sig; } TPMS_SIGNATURE_RSAPSS; // Table 170 - TPMS_SIGNATURE_ECDSA Structure typedef struct { TPMI_ALG_HASH hash; TPM2B_ECC_PARAMETER signatureR; TPM2B_ECC_PARAMETER signatureS; } TPMS_SIGNATURE_ECDSA; // Table 171 - TPMU_SIGNATURE Union typedef union { TPMS_SIGNATURE_RSASSA rsassa; TPMS_SIGNATURE_RSAPSS rsapss; TPMS_SIGNATURE_ECDSA ecdsa; TPMS_SIGNATURE_ECDSA sm2; TPMS_SIGNATURE_ECDSA ecdaa; TPMS_SIGNATURE_ECDSA ecschnorr; TPMT_HA hmac; TPMS_SCHEME_SIGHASH any; } TPMU_SIGNATURE; // Table 172 - TPMT_SIGNATURE Structure typedef struct { TPMI_ALG_SIG_SCHEME sigAlg; TPMU_SIGNATURE signature; } TPMT_SIGNATURE; // Table 173 - TPMU_ENCRYPTED_SECRET Union typedef union { BYTE ecc[sizeof (TPMS_ECC_POINT)]; BYTE rsa[MAX_RSA_KEY_BYTES]; BYTE symmetric[sizeof (TPM2B_DIGEST)]; BYTE keyedHash[sizeof (TPM2B_DIGEST)]; } TPMU_ENCRYPTED_SECRET; // Table 174 - TPM2B_ENCRYPTED_SECRET Structure typedef struct { UINT16 size; BYTE secret[sizeof (TPMU_ENCRYPTED_SECRET)]; } TPM2B_ENCRYPTED_SECRET; // 12 Key/Object Complex // Table 175 - TPMI_ALG_PUBLIC Type typedef TPM_ALG_ID TPMI_ALG_PUBLIC; // Table 176 - TPMU_PUBLIC_ID Union typedef union { TPM2B_DIGEST keyedHash; TPM2B_DIGEST sym; TPM2B_PUBLIC_KEY_RSA rsa; TPMS_ECC_POINT ecc; } TPMU_PUBLIC_ID; // Table 177 - TPMS_KEYEDHASH_PARMS Structure typedef struct { TPMT_KEYEDHASH_SCHEME scheme; } TPMS_KEYEDHASH_PARMS; // Table 178 - TPMS_ASYM_PARMS Structure typedef struct { TPMT_SYM_DEF_OBJECT symmetric; TPMT_ASYM_SCHEME scheme; } TPMS_ASYM_PARMS; // Table 179 - TPMS_RSA_PARMS Structure typedef struct { TPMT_SYM_DEF_OBJECT symmetric; TPMT_RSA_SCHEME scheme; TPMI_RSA_KEY_BITS keyBits; UINT32 exponent; } TPMS_RSA_PARMS; // Table 180 - TPMS_ECC_PARMS Structure typedef struct { TPMT_SYM_DEF_OBJECT symmetric; TPMT_ECC_SCHEME scheme; TPMI_ECC_CURVE curveID; TPMT_KDF_SCHEME kdf; } TPMS_ECC_PARMS; // Table 181 - TPMU_PUBLIC_PARMS Union typedef union { TPMS_KEYEDHASH_PARMS keyedHashDetail; TPMT_SYM_DEF_OBJECT symDetail; TPMS_RSA_PARMS rsaDetail; TPMS_ECC_PARMS eccDetail; TPMS_ASYM_PARMS asymDetail; } TPMU_PUBLIC_PARMS; // Table 182 - TPMT_PUBLIC_PARMS Structure typedef struct { TPMI_ALG_PUBLIC type; TPMU_PUBLIC_PARMS parameters; } TPMT_PUBLIC_PARMS; // Table 183 - TPMT_PUBLIC Structure typedef struct { TPMI_ALG_PUBLIC type; TPMI_ALG_HASH nameAlg; TPMA_OBJECT objectAttributes; TPM2B_DIGEST authPolicy; TPMU_PUBLIC_PARMS parameters; TPMU_PUBLIC_ID unique; } TPMT_PUBLIC; // Table 184 - TPM2B_PUBLIC Structure typedef struct { UINT16 size; TPMT_PUBLIC publicArea; } TPM2B_PUBLIC; // Table 185 - TPM2B_PRIVATE_VENDOR_SPECIFIC Structure typedef struct { UINT16 size; BYTE buffer[PRIVATE_VENDOR_SPECIFIC_BYTES]; } TPM2B_PRIVATE_VENDOR_SPECIFIC; // Table 186 - TPMU_SENSITIVE_COMPOSITE Union typedef union { TPM2B_PRIVATE_KEY_RSA rsa; TPM2B_ECC_PARAMETER ecc; TPM2B_SENSITIVE_DATA bits; TPM2B_SYM_KEY sym; TPM2B_PRIVATE_VENDOR_SPECIFIC any; } TPMU_SENSITIVE_COMPOSITE; // Table 187 - TPMT_SENSITIVE Structure typedef struct { TPMI_ALG_PUBLIC sensitiveType; TPM2B_AUTH authValue; TPM2B_DIGEST seedValue; TPMU_SENSITIVE_COMPOSITE sensitive; } TPMT_SENSITIVE; // Table 188 - TPM2B_SENSITIVE Structure typedef struct { UINT16 size; TPMT_SENSITIVE sensitiveArea; } TPM2B_SENSITIVE; // Table 189 - _PRIVATE Structure typedef struct { TPM2B_DIGEST integrityOuter; TPM2B_DIGEST integrityInner; TPMT_SENSITIVE sensitive; } _PRIVATE; // Table 190 - TPM2B_PRIVATE Structure typedef struct { UINT16 size; BYTE buffer[sizeof (_PRIVATE)]; } TPM2B_PRIVATE; // Table 191 - _ID_OBJECT Structure typedef struct { TPM2B_DIGEST integrityHMAC; TPM2B_DIGEST encIdentity; } _ID_OBJECT; // Table 192 - TPM2B_ID_OBJECT Structure typedef struct { UINT16 size; BYTE credential[sizeof (_ID_OBJECT)]; } TPM2B_ID_OBJECT; // 13 NV Storage Structures // Table 193 - TPM_NV_INDEX Bits // // NOTE: Comment here to resolve conflict // // typedef struct { // UINT32 index : 22; // UINT32 space : 2; // UINT32 RH_NV : 8; // } TPM_NV_INDEX; // Table 195 - TPMA_NV Bits typedef struct { UINT32 TPMA_NV_PPWRITE : 1; UINT32 TPMA_NV_OWNERWRITE : 1; UINT32 TPMA_NV_AUTHWRITE : 1; UINT32 TPMA_NV_POLICYWRITE : 1; UINT32 TPMA_NV_COUNTER : 1; UINT32 TPMA_NV_BITS : 1; UINT32 TPMA_NV_EXTEND : 1; UINT32 reserved7_9 : 3; UINT32 TPMA_NV_POLICY_DELETE : 1; UINT32 TPMA_NV_WRITELOCKED : 1; UINT32 TPMA_NV_WRITEALL : 1; UINT32 TPMA_NV_WRITEDEFINE : 1; UINT32 TPMA_NV_WRITE_STCLEAR : 1; UINT32 TPMA_NV_GLOBALLOCK : 1; UINT32 TPMA_NV_PPREAD : 1; UINT32 TPMA_NV_OWNERREAD : 1; UINT32 TPMA_NV_AUTHREAD : 1; UINT32 TPMA_NV_POLICYREAD : 1; UINT32 reserved20_24 : 5; UINT32 TPMA_NV_NO_DA : 1; UINT32 TPMA_NV_ORDERLY : 1; UINT32 TPMA_NV_CLEAR_STCLEAR : 1; UINT32 TPMA_NV_READLOCKED : 1; UINT32 TPMA_NV_WRITTEN : 1; UINT32 TPMA_NV_PLATFORMCREATE : 1; UINT32 TPMA_NV_READ_STCLEAR : 1; } TPMA_NV; // Table 196 - TPMS_NV_PUBLIC Structure typedef struct { TPMI_RH_NV_INDEX nvIndex; TPMI_ALG_HASH nameAlg; TPMA_NV attributes; TPM2B_DIGEST authPolicy; UINT16 dataSize; } TPMS_NV_PUBLIC; // Table 197 - TPM2B_NV_PUBLIC Structure typedef struct { UINT16 size; TPMS_NV_PUBLIC nvPublic; } TPM2B_NV_PUBLIC; // 14 Context Data // Table 198 - TPM2B_CONTEXT_SENSITIVE Structure typedef struct { UINT16 size; BYTE buffer[MAX_CONTEXT_SIZE]; } TPM2B_CONTEXT_SENSITIVE; // Table 199 - TPMS_CONTEXT_DATA Structure typedef struct { TPM2B_DIGEST integrity; TPM2B_CONTEXT_SENSITIVE encrypted; } TPMS_CONTEXT_DATA; // Table 200 - TPM2B_CONTEXT_DATA Structure typedef struct { UINT16 size; BYTE buffer[sizeof (TPMS_CONTEXT_DATA)]; } TPM2B_CONTEXT_DATA; // Table 201 - TPMS_CONTEXT Structure typedef struct { UINT64 sequence; TPMI_DH_CONTEXT savedHandle; TPMI_RH_HIERARCHY hierarchy; TPM2B_CONTEXT_DATA contextBlob; } TPMS_CONTEXT; // 15 Creation Data // Table 203 - TPMS_CREATION_DATA Structure typedef struct { TPML_PCR_SELECTION pcrSelect; TPM2B_DIGEST pcrDigest; TPMA_LOCALITY locality; TPM_ALG_ID parentNameAlg; TPM2B_NAME parentName; TPM2B_NAME parentQualifiedName; TPM2B_DATA outsideInfo; } TPMS_CREATION_DATA; // Table 204 - TPM2B_CREATION_DATA Structure typedef struct { UINT16 size; TPMS_CREATION_DATA creationData; } TPM2B_CREATION_DATA; // // Command Header // typedef struct { TPM_ST tag; UINT32 paramSize; TPM_CC commandCode; } TPM2_COMMAND_HEADER; typedef struct { TPM_ST tag; UINT32 paramSize; TPM_RC responseCode; } TPM2_RESPONSE_HEADER; #pragma pack () // // TCG Algorithm Registry // #define HASH_ALG_SHA1 0x00000001 #define HASH_ALG_SHA256 0x00000002 #define HASH_ALG_SHA384 0x00000004 #define HASH_ALG_SHA512 0x00000008 #define HASH_ALG_SM3_256 0x00000010 #endif /** @file TCG EFI Platform Definition in TCG_EFI_Platform_1_20_Final and TCG PC Client Platform Firmware Profile Specification, Revision 1.05 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_TCG_PLATFORM_H__ #define __UEFI_TCG_PLATFORM_H__ #include #include #include // // Standard event types // #define EV_PREBOOT_CERT ((TCG_EVENTTYPE) 0x00000000) #define EV_POST_CODE ((TCG_EVENTTYPE) 0x00000001) #define EV_NO_ACTION ((TCG_EVENTTYPE) 0x00000003) #define EV_SEPARATOR ((TCG_EVENTTYPE) 0x00000004) #define EV_ACTION ((TCG_EVENTTYPE) 0x00000005) #define EV_EVENT_TAG ((TCG_EVENTTYPE) 0x00000006) #define EV_S_CRTM_CONTENTS ((TCG_EVENTTYPE) 0x00000007) #define EV_S_CRTM_VERSION ((TCG_EVENTTYPE) 0x00000008) #define EV_CPU_MICROCODE ((TCG_EVENTTYPE) 0x00000009) #define EV_PLATFORM_CONFIG_FLAGS ((TCG_EVENTTYPE) 0x0000000A) #define EV_TABLE_OF_DEVICES ((TCG_EVENTTYPE) 0x0000000B) #define EV_COMPACT_HASH ((TCG_EVENTTYPE) 0x0000000C) #define EV_NONHOST_CODE ((TCG_EVENTTYPE) 0x0000000F) #define EV_NONHOST_CONFIG ((TCG_EVENTTYPE) 0x00000010) #define EV_NONHOST_INFO ((TCG_EVENTTYPE) 0x00000011) #define EV_OMIT_BOOT_DEVICE_EVENTS ((TCG_EVENTTYPE) 0x00000012) // // EFI specific event types // #define EV_EFI_EVENT_BASE ((TCG_EVENTTYPE) 0x80000000) #define EV_EFI_VARIABLE_DRIVER_CONFIG (EV_EFI_EVENT_BASE + 1) #define EV_EFI_VARIABLE_BOOT (EV_EFI_EVENT_BASE + 2) #define EV_EFI_BOOT_SERVICES_APPLICATION (EV_EFI_EVENT_BASE + 3) #define EV_EFI_BOOT_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 4) #define EV_EFI_RUNTIME_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 5) #define EV_EFI_GPT_EVENT (EV_EFI_EVENT_BASE + 6) #define EV_EFI_ACTION (EV_EFI_EVENT_BASE + 7) #define EV_EFI_PLATFORM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 8) #define EV_EFI_HANDOFF_TABLES (EV_EFI_EVENT_BASE + 9) #define EV_EFI_PLATFORM_FIRMWARE_BLOB2 (EV_EFI_EVENT_BASE + 0xA) #define EV_EFI_HANDOFF_TABLES2 (EV_EFI_EVENT_BASE + 0xB) #define EV_EFI_HCRTM_EVENT (EV_EFI_EVENT_BASE + 0x10) #define EV_EFI_VARIABLE_AUTHORITY (EV_EFI_EVENT_BASE + 0xE0) #define EV_EFI_SPDM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 0xE1) #define EV_EFI_SPDM_FIRMWARE_CONFIG (EV_EFI_EVENT_BASE + 0xE2) #define EFI_CALLING_EFI_APPLICATION \ "Calling EFI Application from Boot Option" #define EFI_RETURNING_FROM_EFI_APPLICATION \ "Returning from EFI Application from Boot Option" #define EFI_EXIT_BOOT_SERVICES_INVOCATION \ "Exit Boot Services Invocation" #define EFI_EXIT_BOOT_SERVICES_FAILED \ "Exit Boot Services Returned with Failure" #define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \ "Exit Boot Services Returned with Success" #define EV_POSTCODE_INFO_POST_CODE "POST CODE" #define POST_CODE_STR_LEN (sizeof(EV_POSTCODE_INFO_POST_CODE) - 1) #define EV_POSTCODE_INFO_SMM_CODE "SMM CODE" #define SMM_CODE_STR_LEN (sizeof(EV_POSTCODE_INFO_SMM_CODE) - 1) #define EV_POSTCODE_INFO_ACPI_DATA "ACPI DATA" #define ACPI_DATA_LEN (sizeof(EV_POSTCODE_INFO_ACPI_DATA) - 1) #define EV_POSTCODE_INFO_BIS_CODE "BIS CODE" #define BIS_CODE_LEN (sizeof(EV_POSTCODE_INFO_BIS_CODE) - 1) #define EV_POSTCODE_INFO_UEFI_PI "UEFI PI" #define UEFI_PI_LEN (sizeof(EV_POSTCODE_INFO_UEFI_PI) - 1) #define EV_POSTCODE_INFO_OPROM "Embedded Option ROM" #define OPROM_LEN (sizeof(EV_POSTCODE_INFO_OPROM) - 1) #define EV_POSTCODE_INFO_EMBEDDED_UEFI_DRIVER "Embedded UEFI Driver" #define EMBEDDED_UEFI_DRIVER_LEN (sizeof(EV_POSTCODE_INFO_EMBEDDED_UEFI_DRIVER) - 1) #define FIRMWARE_DEBUGGER_EVENT_STRING "UEFI Debug Mode" #define FIRMWARE_DEBUGGER_EVENT_STRING_LEN (sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1) // // Set structure alignment to 1-byte // #pragma pack (1) typedef UINT32 TCG_EVENTTYPE; typedef TPM_PCRINDEX TCG_PCRINDEX; typedef TPM_DIGEST TCG_DIGEST; /// /// Event Log Entry Structure Definition /// typedef struct tdTCG_PCR_EVENT { TCG_PCRINDEX PCRIndex; ///< PCRIndex event extended to TCG_EVENTTYPE EventType; ///< TCG EFI event type TCG_DIGEST Digest; ///< Value extended into PCRIndex UINT32 EventSize; ///< Size of the event data UINT8 Event[1]; ///< The event data } TCG_PCR_EVENT; #define TSS_EVENT_DATA_MAX_SIZE 256 /// /// TCG_PCR_EVENT_HDR /// typedef struct tdTCG_PCR_EVENT_HDR { TCG_PCRINDEX PCRIndex; TCG_EVENTTYPE EventType; TCG_DIGEST Digest; UINT32 EventSize; } TCG_PCR_EVENT_HDR; /// /// EFI_PLATFORM_FIRMWARE_BLOB /// /// BlobLength should be of type UINTN but we use UINT64 here /// because PEI is 32-bit while DXE is 64-bit on x64 platforms /// typedef struct tdEFI_PLATFORM_FIRMWARE_BLOB { EFI_PHYSICAL_ADDRESS BlobBase; UINT64 BlobLength; } EFI_PLATFORM_FIRMWARE_BLOB; /// /// UEFI_PLATFORM_FIRMWARE_BLOB /// /// This structure is used in EV_EFI_PLATFORM_FIRMWARE_BLOB /// event to facilitate the measurement of firmware volume. /// typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB { EFI_PHYSICAL_ADDRESS BlobBase; UINT64 BlobLength; } UEFI_PLATFORM_FIRMWARE_BLOB; /// /// UEFI_PLATFORM_FIRMWARE_BLOB2 /// /// This structure is used in EV_EFI_PLATFORM_FIRMWARE_BLOB2 /// event to facilitate the measurement of firmware volume. /// typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB2 { UINT8 BlobDescriptionSize; // UINT8 BlobDescription[BlobDescriptionSize]; // EFI_PHYSICAL_ADDRESS BlobBase; // UINT64 BlobLength; } UEFI_PLATFORM_FIRMWARE_BLOB2; /// /// EFI_IMAGE_LOAD_EVENT /// /// This structure is used in EV_EFI_BOOT_SERVICES_APPLICATION, /// EV_EFI_BOOT_SERVICES_DRIVER and EV_EFI_RUNTIME_SERVICES_DRIVER /// typedef struct tdEFI_IMAGE_LOAD_EVENT { EFI_PHYSICAL_ADDRESS ImageLocationInMemory; UINTN ImageLengthInMemory; UINTN ImageLinkTimeAddress; UINTN LengthOfDevicePath; EFI_DEVICE_PATH_PROTOCOL DevicePath[1]; } EFI_IMAGE_LOAD_EVENT; /// /// UEFI_IMAGE_LOAD_EVENT /// /// This structure is used in EV_EFI_BOOT_SERVICES_APPLICATION, /// EV_EFI_BOOT_SERVICES_DRIVER and EV_EFI_RUNTIME_SERVICES_DRIVER /// typedef struct tdUEFI_IMAGE_LOAD_EVENT { EFI_PHYSICAL_ADDRESS ImageLocationInMemory; UINT64 ImageLengthInMemory; UINT64 ImageLinkTimeAddress; UINT64 LengthOfDevicePath; EFI_DEVICE_PATH_PROTOCOL DevicePath[1]; } UEFI_IMAGE_LOAD_EVENT; /// /// EFI_HANDOFF_TABLE_POINTERS /// /// This structure is used in EV_EFI_HANDOFF_TABLES event to facilitate /// the measurement of given configuration tables. /// typedef struct tdEFI_HANDOFF_TABLE_POINTERS { UINTN NumberOfTables; EFI_CONFIGURATION_TABLE TableEntry[1]; } EFI_HANDOFF_TABLE_POINTERS; /// /// UEFI_HANDOFF_TABLE_POINTERS /// /// This structure is used in EV_EFI_HANDOFF_TABLES event to facilitate /// the measurement of given configuration tables. /// typedef struct tdUEFI_HANDOFF_TABLE_POINTERS { UINT64 NumberOfTables; EFI_CONFIGURATION_TABLE TableEntry[1]; } UEFI_HANDOFF_TABLE_POINTERS; /// /// UEFI_HANDOFF_TABLE_POINTERS2 /// /// This structure is used in EV_EFI_HANDOFF_TABLES2 event to facilitate /// the measurement of given configuration tables. /// typedef struct tdUEFI_HANDOFF_TABLE_POINTERS2 { UINT8 TableDescriptionSize; // UINT8 TableDescription[TableDescriptionSize]; // UINT64 NumberOfTables; // EFI_CONFIGURATION_TABLE TableEntry[1]; } UEFI_HANDOFF_TABLE_POINTERS2; /// /// EFI_VARIABLE_DATA /// /// This structure serves as the header for measuring variables. The name of the /// variable (in Unicode format) should immediately follow, then the variable /// data. /// This is defined in TCG EFI Platform Spec for TPM1.1 or 1.2 V1.22 /// typedef struct tdEFI_VARIABLE_DATA { EFI_GUID VariableName; UINTN UnicodeNameLength; UINTN VariableDataLength; CHAR16 UnicodeName[1]; INT8 VariableData[1]; ///< Driver or platform-specific data } EFI_VARIABLE_DATA; /// /// UEFI_VARIABLE_DATA /// /// This structure serves as the header for measuring variables. The name of the /// variable (in Unicode format) should immediately follow, then the variable /// data. /// This is defined in TCG PC Client Firmware Profile Spec 00.21 /// typedef struct tdUEFI_VARIABLE_DATA { EFI_GUID VariableName; UINT64 UnicodeNameLength; UINT64 VariableDataLength; CHAR16 UnicodeName[1]; INT8 VariableData[1]; ///< Driver or platform-specific data } UEFI_VARIABLE_DATA; // // For TrEE1.0 compatibility // typedef struct { EFI_GUID VariableName; UINT64 UnicodeNameLength; // The TCG Definition used UINTN UINT64 VariableDataLength; // The TCG Definition used UINTN CHAR16 UnicodeName[1]; INT8 VariableData[1]; } EFI_VARIABLE_DATA_TREE; typedef struct tdEFI_GPT_DATA { EFI_PARTITION_TABLE_HEADER EfiPartitionHeader; UINTN NumberOfPartitions; EFI_PARTITION_ENTRY Partitions[1]; } EFI_GPT_DATA; typedef struct tdUEFI_GPT_DATA { EFI_PARTITION_TABLE_HEADER EfiPartitionHeader; UINT64 NumberOfPartitions; EFI_PARTITION_ENTRY Partitions[1]; } UEFI_GPT_DATA; #define TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE "SPDM Device Sec" #define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION 1 #define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL 0 #define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI 1 #define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB 2 /// /// TCG_DEVICE_SECURITY_EVENT_DATA_HEADER /// This is the header of TCG_DEVICE_SECURITY_EVENT_DATA, which is /// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG. /// typedef struct { UINT8 Signature[16]; UINT16 Version; UINT16 Length; UINT32 SpdmHashAlgo; UINT32 DeviceType; // SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; } TCG_DEVICE_SECURITY_EVENT_DATA_HEADER; #define TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION 0 /// /// TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT /// This is the PCI context data of TCG_DEVICE_SECURITY_EVENT_DATA, which is /// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG. /// typedef struct { UINT16 Version; UINT16 Length; UINT16 VendorId; UINT16 DeviceId; UINT8 RevisionID; UINT8 ClassCode[3]; UINT16 SubsystemVendorID; UINT16 SubsystemID; } TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT; #define TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT_VERSION 0 /// /// TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT /// This is the USB context data of TCG_DEVICE_SECURITY_EVENT_DATA, which is /// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG. /// typedef struct { UINT16 Version; UINT16 Length; // UINT8 DeviceDescriptor[DescLen]; // UINT8 BodDescriptor[DescLen]; // UINT8 ConfigurationDescriptor[DescLen][NumOfConfiguration]; } TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT; // // Crypto Agile Log Entry Format // typedef struct tdTCG_PCR_EVENT2 { TCG_PCRINDEX PCRIndex; TCG_EVENTTYPE EventType; TPML_DIGEST_VALUES Digest; UINT32 EventSize; UINT8 Event[1]; } TCG_PCR_EVENT2; // // TCG PCR Event2 Header // Follow TCG EFI Protocol Spec 5.2 Crypto Agile Log Entry Format // typedef struct tdTCG_PCR_EVENT2_HDR { TCG_PCRINDEX PCRIndex; TCG_EVENTTYPE EventType; TPML_DIGEST_VALUES Digests; UINT32 EventSize; } TCG_PCR_EVENT2_HDR; // // Log Header Entry Data // typedef struct { // // TCG defined hashing algorithm ID. // UINT16 algorithmId; // // The size of the digest for the respective hashing algorithm. // UINT16 digestSize; } TCG_EfiSpecIdEventAlgorithmSize; #define TCG_EfiSpecIDEventStruct_SIGNATURE_02 "Spec ID Event02" #define TCG_EfiSpecIDEventStruct_SIGNATURE_03 "Spec ID Event03" #define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM12 1 #define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM12 2 #define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM12 2 #define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2 2 #define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2 0 #define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2 0 #define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105 105 typedef struct { UINT8 signature[16]; // // The value for the Platform Class. // The enumeration is defined in the TCG ACPI Specification Client Common Header. // UINT32 platformClass; // // The TCG EFI Platform Specification minor version number this BIOS supports. // Any BIOS supporting version (1.22) MUST set this value to 02h. // Any BIOS supporting version (2.0) SHALL set this value to 0x00. // UINT8 specVersionMinor; // // The TCG EFI Platform Specification major version number this BIOS supports. // Any BIOS supporting version (1.22) MUST set this value to 01h. // Any BIOS supporting version (2.0) SHALL set this value to 0x02. // UINT8 specVersionMajor; // // The TCG EFI Platform Specification errata for this specification this BIOS supports. // Any BIOS supporting version and errata (1.22) MUST set this value to 02h. // Any BIOS supporting version and errata (2.0) SHALL set this value to 0x00. // UINT8 specErrata; // // Specifies the size of the UINTN fields used in various data structures used in this specification. // 0x01 indicates UINT32 and 0x02 indicates UINT64. // UINT8 uintnSize; // // This field is added in "Spec ID Event03". // The number of hashing algorithms used in this event log (except the first event). // All events in this event log use all hashing algorithms defined here. // // UINT32 numberOfAlgorithms; // // This field is added in "Spec ID Event03". // An array of size numberOfAlgorithms of value pairs. // // TCG_EfiSpecIdEventAlgorithmSize digestSize[numberOfAlgorithms]; // // Size in bytes of the VendorInfo field. // Maximum value SHALL be FFh bytes. // // UINT8 vendorInfoSize; // // Provided for use by the BIOS implementer. // The value might be used, for example, to provide more detailed information about the specific BIOS such as BIOS revision numbers, etc. // The values within this field are not standardized and are implementer-specific. // Platform-specific or -unique information SHALL NOT be provided in this field. // // UINT8 vendorInfo[vendorInfoSize]; } TCG_EfiSpecIDEventStruct; typedef struct tdTCG_PCClientTaggedEvent { UINT32 taggedEventID; UINT32 taggedEventDataSize; // UINT8 taggedEventData[taggedEventDataSize]; } TCG_PCClientTaggedEvent; #define TCG_Sp800_155_PlatformId_Event_SIGNATURE "SP800-155 Event" #define TCG_Sp800_155_PlatformId_Event2_SIGNATURE "SP800-155 Event2" typedef struct tdTCG_Sp800_155_PlatformId_Event2 { UINT8 Signature[16]; // // Where Vendor ID is an integer defined // at http://www.iana.org/assignments/enterprisenumbers // UINT32 VendorId; // // 16-byte identifier of a given platform's static configuration of code // EFI_GUID ReferenceManifestGuid; // // Below structure is newly added in TCG_Sp800_155_PlatformId_Event2. // // UINT8 PlatformManufacturerStrSize; // UINT8 PlatformManufacturerStr[PlatformManufacturerStrSize]; // UINT8 PlatformModelSize; // UINT8 PlatformModel[PlatformModelSize]; // UINT8 PlatformVersionSize; // UINT8 PlatformVersion[PlatformVersionSize]; // UINT8 PlatformModelSize; // UINT8 PlatformModel[PlatformModelSize]; // UINT8 FirmwareManufacturerStrSize; // UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize]; // UINT32 FirmwareManufacturerId; // UINT8 FirmwareVersion; // UINT8 FirmwareVersion[FirmwareVersionSize]]; } TCG_Sp800_155_PlatformId_Event2; #define TCG_EfiStartupLocalityEvent_SIGNATURE "StartupLocality" // // The Locality Indicator which sent the TPM2_Startup command // #define LOCALITY_0_INDICATOR 0x00 #define LOCALITY_3_INDICATOR 0x03 // // Startup Locality Event // typedef struct tdTCG_EfiStartupLocalityEvent { UINT8 Signature[16]; // // The Locality Indicator which sent the TPM2_Startup command // UINT8 StartupLocality; } TCG_EfiStartupLocalityEvent; // // Restore original structure alignment // #pragma pack () #endif /** @file Support for USB 2.0 standard. Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __USB_H__ #define __USB_H__ // // Subset of Class and Subclass definitions from USB Specs // // // Usb mass storage class code // #define USB_MASS_STORE_CLASS 0x08 // // Usb mass storage subclass code, specify the command set used. // #define USB_MASS_STORE_RBC 0x01 ///< Reduced Block Commands #define USB_MASS_STORE_8020I 0x02 ///< SFF-8020i, typically a CD/DVD device #define USB_MASS_STORE_QIC 0x03 ///< Typically a tape device #define USB_MASS_STORE_UFI 0x04 ///< Typically a floppy disk driver device #define USB_MASS_STORE_8070I 0x05 ///< SFF-8070i, typically a floppy disk driver device. #define USB_MASS_STORE_SCSI 0x06 ///< SCSI transparent command set // // Usb mass storage protocol code, specify the transport protocol // #define USB_MASS_STORE_CBI0 0x00 ///< CBI protocol with command completion interrupt #define USB_MASS_STORE_CBI1 0x01 ///< CBI protocol without command completion interrupt #define USB_MASS_STORE_BOT 0x50 ///< Bulk-Only Transport // // Standard device request and request type // USB 2.0 spec, Section 9.4 // #define USB_DEV_GET_STATUS 0x00 #define USB_DEV_GET_STATUS_REQ_TYPE_D 0x80 // Receiver : Device #define USB_DEV_GET_STATUS_REQ_TYPE_I 0x81 // Receiver : Interface #define USB_DEV_GET_STATUS_REQ_TYPE_E 0x82 // Receiver : Endpoint #define USB_DEV_CLEAR_FEATURE 0x01 #define USB_DEV_CLEAR_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device #define USB_DEV_CLEAR_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface #define USB_DEV_CLEAR_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint #define USB_DEV_SET_FEATURE 0x03 #define USB_DEV_SET_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device #define USB_DEV_SET_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface #define USB_DEV_SET_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint #define USB_DEV_SET_ADDRESS 0x05 #define USB_DEV_SET_ADDRESS_REQ_TYPE 0x00 #define USB_DEV_GET_DESCRIPTOR 0x06 #define USB_DEV_GET_DESCRIPTOR_REQ_TYPE 0x80 #define USB_DEV_SET_DESCRIPTOR 0x07 #define USB_DEV_SET_DESCRIPTOR_REQ_TYPE 0x00 #define USB_DEV_GET_CONFIGURATION 0x08 #define USB_DEV_GET_CONFIGURATION_REQ_TYPE 0x80 #define USB_DEV_SET_CONFIGURATION 0x09 #define USB_DEV_SET_CONFIGURATION_REQ_TYPE 0x00 #define USB_DEV_GET_INTERFACE 0x0A #define USB_DEV_GET_INTERFACE_REQ_TYPE 0x81 #define USB_DEV_SET_INTERFACE 0x0B #define USB_DEV_SET_INTERFACE_REQ_TYPE 0x01 #define USB_DEV_SYNCH_FRAME 0x0C #define USB_DEV_SYNCH_FRAME_REQ_TYPE 0x82 // // USB standard descriptors and reqeust // #pragma pack(1) /// /// Format of Setup Data for USB Device Requests /// USB 2.0 spec, Section 9.3 /// typedef struct { UINT8 RequestType; UINT8 Request; UINT16 Value; UINT16 Index; UINT16 Length; } USB_DEVICE_REQUEST; /// /// Standard Device Descriptor /// USB 2.0 spec, Section 9.6.1 /// typedef struct { UINT8 Length; UINT8 DescriptorType; UINT16 BcdUSB; UINT8 DeviceClass; UINT8 DeviceSubClass; UINT8 DeviceProtocol; UINT8 MaxPacketSize0; UINT16 IdVendor; UINT16 IdProduct; UINT16 BcdDevice; UINT8 StrManufacturer; UINT8 StrProduct; UINT8 StrSerialNumber; UINT8 NumConfigurations; } USB_DEVICE_DESCRIPTOR; /// /// Standard Configuration Descriptor /// USB 2.0 spec, Section 9.6.3 /// typedef struct { UINT8 Length; UINT8 DescriptorType; UINT16 TotalLength; UINT8 NumInterfaces; UINT8 ConfigurationValue; UINT8 Configuration; UINT8 Attributes; UINT8 MaxPower; } USB_CONFIG_DESCRIPTOR; /// /// Standard Interface Descriptor /// USB 2.0 spec, Section 9.6.5 /// typedef struct { UINT8 Length; UINT8 DescriptorType; UINT8 InterfaceNumber; UINT8 AlternateSetting; UINT8 NumEndpoints; UINT8 InterfaceClass; UINT8 InterfaceSubClass; UINT8 InterfaceProtocol; UINT8 Interface; } USB_INTERFACE_DESCRIPTOR; /// /// Standard Endpoint Descriptor /// USB 2.0 spec, Section 9.6.6 /// typedef struct { UINT8 Length; UINT8 DescriptorType; UINT8 EndpointAddress; UINT8 Attributes; UINT16 MaxPacketSize; UINT8 Interval; } USB_ENDPOINT_DESCRIPTOR; /// /// UNICODE String Descriptor /// USB 2.0 spec, Section 9.6.7 /// typedef struct { UINT8 Length; UINT8 DescriptorType; CHAR16 String[1]; } EFI_USB_STRING_DESCRIPTOR; #pragma pack() typedef enum { // // USB request type // USB_REQ_TYPE_STANDARD = (0x00 << 5), USB_REQ_TYPE_CLASS = (0x01 << 5), USB_REQ_TYPE_VENDOR = (0x02 << 5), // // Standard control transfer request type, or the value // to fill in EFI_USB_DEVICE_REQUEST.Request // USB_REQ_GET_STATUS = 0x00, USB_REQ_CLEAR_FEATURE = 0x01, USB_REQ_SET_FEATURE = 0x03, USB_REQ_SET_ADDRESS = 0x05, USB_REQ_GET_DESCRIPTOR = 0x06, USB_REQ_SET_DESCRIPTOR = 0x07, USB_REQ_GET_CONFIG = 0x08, USB_REQ_SET_CONFIG = 0x09, USB_REQ_GET_INTERFACE = 0x0A, USB_REQ_SET_INTERFACE = 0x0B, USB_REQ_SYNCH_FRAME = 0x0C, // // Usb control transfer target // USB_TARGET_DEVICE = 0, USB_TARGET_INTERFACE = 0x01, USB_TARGET_ENDPOINT = 0x02, USB_TARGET_OTHER = 0x03, // // USB Descriptor types // USB_DESC_TYPE_DEVICE = 0x01, USB_DESC_TYPE_CONFIG = 0x02, USB_DESC_TYPE_STRING = 0x03, USB_DESC_TYPE_INTERFACE = 0x04, USB_DESC_TYPE_ENDPOINT = 0x05, USB_DESC_TYPE_HID = 0x21, USB_DESC_TYPE_REPORT = 0x22, // // Features to be cleared by CLEAR_FEATURE requests // USB_FEATURE_ENDPOINT_HALT = 0, // // USB endpoint types: 00: control, 01: isochronous, 10: bulk, 11: interrupt // USB_ENDPOINT_CONTROL = 0x00, USB_ENDPOINT_ISO = 0x01, USB_ENDPOINT_BULK = 0x02, USB_ENDPOINT_INTERRUPT = 0x03, USB_ENDPOINT_TYPE_MASK = 0x03, USB_ENDPOINT_DIR_IN = 0x80, // // Use 200 ms to increase the error handling response time // EFI_USB_INTERRUPT_DELAY = 2000000 } USB_TYPES_DEFINITION; // // HID constants definition, see Device Class Definition // for Human Interface Devices (HID) rev1.11 // // // HID standard GET_DESCRIPTOR request. // #define USB_HID_GET_DESCRIPTOR_REQ_TYPE 0x81 // // HID specific requests. // #define USB_HID_CLASS_GET_REQ_TYPE 0xa1 #define USB_HID_CLASS_SET_REQ_TYPE 0x21 // // HID report item format // #define HID_ITEM_FORMAT_SHORT 0 #define HID_ITEM_FORMAT_LONG 1 // // Special tag indicating long items // #define HID_ITEM_TAG_LONG 15 // // HID report descriptor item type (prefix bit 2,3) // #define HID_ITEM_TYPE_MAIN 0 #define HID_ITEM_TYPE_GLOBAL 1 #define HID_ITEM_TYPE_LOCAL 2 #define HID_ITEM_TYPE_RESERVED 3 // // HID report descriptor main item tags // #define HID_MAIN_ITEM_TAG_INPUT 8 #define HID_MAIN_ITEM_TAG_OUTPUT 9 #define HID_MAIN_ITEM_TAG_FEATURE 11 #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 #define HID_MAIN_ITEM_TAG_END_COLLECTION 12 // // HID report descriptor main item contents // #define HID_MAIN_ITEM_CONSTANT 0x001 #define HID_MAIN_ITEM_VARIABLE 0x002 #define HID_MAIN_ITEM_RELATIVE 0x004 #define HID_MAIN_ITEM_WRAP 0x008 #define HID_MAIN_ITEM_NONLINEAR 0x010 #define HID_MAIN_ITEM_NO_PREFERRED 0x020 #define HID_MAIN_ITEM_NULL_STATE 0x040 #define HID_MAIN_ITEM_VOLATILE 0x080 #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 // // HID report descriptor collection item types // #define HID_COLLECTION_PHYSICAL 0 #define HID_COLLECTION_APPLICATION 1 #define HID_COLLECTION_LOGICAL 2 // // HID report descriptor global item tags // #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 #define HID_GLOBAL_ITEM_TAG_UNIT 6 #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 #define HID_GLOBAL_ITEM_TAG_PUSH 10 #define HID_GLOBAL_ITEM_TAG_POP 11 // // HID report descriptor local item tags // #define HID_LOCAL_ITEM_TAG_USAGE 0 #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 #define HID_LOCAL_ITEM_TAG_DELIMITER 10 // // HID report types // #define HID_INPUT_REPORT 1 #define HID_OUTPUT_REPORT 2 #define HID_FEATURE_REPORT 3 // // HID class protocol request // #define EFI_USB_GET_REPORT_REQUEST 0x01 #define EFI_USB_GET_IDLE_REQUEST 0x02 #define EFI_USB_GET_PROTOCOL_REQUEST 0x03 #define EFI_USB_SET_REPORT_REQUEST 0x09 #define EFI_USB_SET_IDLE_REQUEST 0x0a #define EFI_USB_SET_PROTOCOL_REQUEST 0x0b #pragma pack(1) /// /// Descriptor header for Report/Physical Descriptors /// HID 1.1, section 6.2.1 /// typedef struct hid_class_descriptor { UINT8 DescriptorType; UINT16 DescriptorLength; } EFI_USB_HID_CLASS_DESCRIPTOR; /// /// The HID descriptor identifies the length and type /// of subordinate descriptors for a device. /// HID 1.1, section 6.2.1 /// typedef struct hid_descriptor { UINT8 Length; UINT8 DescriptorType; UINT16 BcdHID; UINT8 CountryCode; UINT8 NumDescriptors; EFI_USB_HID_CLASS_DESCRIPTOR HidClassDesc[1]; } EFI_USB_HID_DESCRIPTOR; #pragma pack() #endif /** @file Present the boot mode values in PI. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.2.1A **/ #ifndef __PI_BOOT_MODE_H__ #define __PI_BOOT_MODE_H__ /// /// EFI boot mode /// typedef UINT32 EFI_BOOT_MODE; // // 0x21 - 0xf..f are reserved. // #define BOOT_WITH_FULL_CONFIGURATION 0x00 #define BOOT_WITH_MINIMAL_CONFIGURATION 0x01 #define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02 #define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03 #define BOOT_WITH_DEFAULT_SETTINGS 0x04 #define BOOT_ON_S4_RESUME 0x05 #define BOOT_ON_S5_RESUME 0x06 #define BOOT_WITH_MFG_MODE_SETTINGS 0x07 #define BOOT_ON_S2_RESUME 0x10 #define BOOT_ON_S3_RESUME 0x11 #define BOOT_ON_FLASH_UPDATE 0x12 #define BOOT_IN_RECOVERY_MODE 0x20 #endif /** @file Present the dependency expression values in PI. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.0 **/ #ifndef __PI_DEPENDENCY_H__ #define __PI_DEPENDENCY_H__ /// /// If present, this must be the first and only opcode, /// EFI_DEP_BEFORE may be used by DXE and SMM drivers. /// #define EFI_DEP_BEFORE 0x00 /// /// If present, this must be the first and only opcode, /// EFI_DEP_AFTER may be used by DXE and SMM drivers. /// #define EFI_DEP_AFTER 0x01 #define EFI_DEP_PUSH 0x02 #define EFI_DEP_AND 0x03 #define EFI_DEP_OR 0x04 #define EFI_DEP_NOT 0x05 #define EFI_DEP_TRUE 0x06 #define EFI_DEP_FALSE 0x07 #define EFI_DEP_END 0x08 /// /// If present, this must be the first opcode, /// EFI_DEP_SOR is only used by DXE driver. /// #define EFI_DEP_SOR 0x09 #endif /** @file The firmware file related definitions in PI. Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.6. **/ #ifndef __PI_FIRMWARE_FILE_H__ #define __PI_FIRMWARE_FILE_H__ #pragma pack(1) /// /// Used to verify the integrity of the file. /// typedef union { struct { /// /// The IntegrityCheck.Checksum.Header field is an 8-bit checksum of the file /// header. The State and IntegrityCheck.Checksum.File fields are assumed /// to be zero and the checksum is calculated such that the entire header sums to zero. /// UINT8 Header; /// /// If the FFS_ATTRIB_CHECKSUM (see definition below) bit of the Attributes /// field is set to one, the IntegrityCheck.Checksum.File field is an 8-bit /// checksum of the file data. /// If the FFS_ATTRIB_CHECKSUM bit of the Attributes field is cleared to zero, /// the IntegrityCheck.Checksum.File field must be initialized with a value of /// 0xAA. The IntegrityCheck.Checksum.File field is valid any time the /// EFI_FILE_DATA_VALID bit is set in the State field. /// UINT8 File; } Checksum; /// /// This is the full 16 bits of the IntegrityCheck field. /// UINT16 Checksum16; } EFI_FFS_INTEGRITY_CHECK; /// /// FFS_FIXED_CHECKSUM is the checksum value used when the /// FFS_ATTRIB_CHECKSUM attribute bit is clear. /// #define FFS_FIXED_CHECKSUM 0xAA typedef UINT8 EFI_FV_FILETYPE; typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; typedef UINT8 EFI_FFS_FILE_STATE; /// /// File Types Definitions /// #define EFI_FV_FILETYPE_ALL 0x00 #define EFI_FV_FILETYPE_RAW 0x01 #define EFI_FV_FILETYPE_FREEFORM 0x02 #define EFI_FV_FILETYPE_SECURITY_CORE 0x03 #define EFI_FV_FILETYPE_PEI_CORE 0x04 #define EFI_FV_FILETYPE_DXE_CORE 0x05 #define EFI_FV_FILETYPE_PEIM 0x06 #define EFI_FV_FILETYPE_DRIVER 0x07 #define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 #define EFI_FV_FILETYPE_APPLICATION 0x09 #define EFI_FV_FILETYPE_MM 0x0A #define EFI_FV_FILETYPE_SMM EFI_FV_FILETYPE_MM #define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B #define EFI_FV_FILETYPE_COMBINED_MM_DXE 0x0C #define EFI_FV_FILETYPE_COMBINED_SMM_DXE EFI_FV_FILETYPE_COMBINED_MM_DXE #define EFI_FV_FILETYPE_MM_CORE 0x0D #define EFI_FV_FILETYPE_SMM_CORE EFI_FV_FILETYPE_MM_CORE #define EFI_FV_FILETYPE_MM_STANDALONE 0x0E #define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F #define EFI_FV_FILETYPE_OEM_MIN 0xc0 #define EFI_FV_FILETYPE_OEM_MAX 0xdf #define EFI_FV_FILETYPE_DEBUG_MIN 0xe0 #define EFI_FV_FILETYPE_DEBUG_MAX 0xef #define EFI_FV_FILETYPE_FFS_MIN 0xf0 #define EFI_FV_FILETYPE_FFS_MAX 0xff #define EFI_FV_FILETYPE_FFS_PAD 0xf0 /// /// FFS File Attributes. /// #define FFS_ATTRIB_LARGE_FILE 0x01 #define FFS_ATTRIB_DATA_ALIGNMENT_2 0x02 #define FFS_ATTRIB_FIXED 0x04 #define FFS_ATTRIB_DATA_ALIGNMENT 0x38 #define FFS_ATTRIB_CHECKSUM 0x40 /// /// FFS File State Bits. /// #define EFI_FILE_HEADER_CONSTRUCTION 0x01 #define EFI_FILE_HEADER_VALID 0x02 #define EFI_FILE_DATA_VALID 0x04 #define EFI_FILE_MARKED_FOR_UPDATE 0x08 #define EFI_FILE_DELETED 0x10 #define EFI_FILE_HEADER_INVALID 0x20 /// /// Each file begins with the header that describe the /// contents and state of the files. /// typedef struct { /// /// This GUID is the file name. It is used to uniquely identify the file. /// EFI_GUID Name; /// /// Used to verify the integrity of the file. /// EFI_FFS_INTEGRITY_CHECK IntegrityCheck; /// /// Identifies the type of file. /// EFI_FV_FILETYPE Type; /// /// Declares various file attribute bits. /// EFI_FFS_FILE_ATTRIBUTES Attributes; /// /// The length of the file in bytes, including the FFS header. /// UINT8 Size[3]; /// /// Used to track the state of the file throughout the life of the file from creation to deletion. /// EFI_FFS_FILE_STATE State; } EFI_FFS_FILE_HEADER; typedef struct { /// /// This GUID is the file name. It is used to uniquely identify the file. There may be only /// one instance of a file with the file name GUID of Name in any given firmware /// volume, except if the file type is EFI_FV_FILETYPE_FFS_PAD. /// EFI_GUID Name; /// /// Used to verify the integrity of the file. /// EFI_FFS_INTEGRITY_CHECK IntegrityCheck; /// /// Identifies the type of file. /// EFI_FV_FILETYPE Type; /// /// Declares various file attribute bits. /// EFI_FFS_FILE_ATTRIBUTES Attributes; /// /// The length of the file in bytes, including the FFS header. /// The length of the file data is either (Size - sizeof(EFI_FFS_FILE_HEADER)). This calculation means a /// zero-length file has a Size of 24 bytes, which is sizeof(EFI_FFS_FILE_HEADER). /// Size is not required to be a multiple of 8 bytes. Given a file F, the next file header is /// located at the next 8-byte aligned firmware volume offset following the last byte of the file F. /// UINT8 Size[3]; /// /// Used to track the state of the file throughout the life of the file from creation to deletion. /// EFI_FFS_FILE_STATE State; /// /// If FFS_ATTRIB_LARGE_FILE is set in Attributes, then ExtendedSize exists and Size must be set to zero. /// If FFS_ATTRIB_LARGE_FILE is not set then EFI_FFS_FILE_HEADER is used. /// UINT64 ExtendedSize; } EFI_FFS_FILE_HEADER2; #define IS_FFS_FILE2(FfsFileHeaderPtr) \ (((((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Attributes) & FFS_ATTRIB_LARGE_FILE) == FFS_ATTRIB_LARGE_FILE) /// /// The argument passed as the FfsFileHeaderPtr parameter to the /// FFS_FILE_SIZE() function-like macro below must not have side effects: /// FfsFileHeaderPtr is evaluated multiple times. /// #define FFS_FILE_SIZE(FfsFileHeaderPtr) ((UINT32) (\ (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[0] ) | \ (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[1] << 8) | \ (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[2] << 16))) #define FFS_FILE2_SIZE(FfsFileHeaderPtr) \ ((UINT32) (((EFI_FFS_FILE_HEADER2 *) (UINTN) FfsFileHeaderPtr)->ExtendedSize)) typedef UINT8 EFI_SECTION_TYPE; /// /// Pseudo type. It is used as a wild card when retrieving sections. /// The section type EFI_SECTION_ALL matches all section types. /// #define EFI_SECTION_ALL 0x00 /// /// Encapsulation section Type values. /// #define EFI_SECTION_COMPRESSION 0x01 #define EFI_SECTION_GUID_DEFINED 0x02 #define EFI_SECTION_DISPOSABLE 0x03 /// /// Leaf section Type values. /// #define EFI_SECTION_PE32 0x10 #define EFI_SECTION_PIC 0x11 #define EFI_SECTION_TE 0x12 #define EFI_SECTION_DXE_DEPEX 0x13 #define EFI_SECTION_VERSION 0x14 #define EFI_SECTION_USER_INTERFACE 0x15 #define EFI_SECTION_COMPATIBILITY16 0x16 #define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 #define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 #define EFI_SECTION_RAW 0x19 #define EFI_SECTION_PEI_DEPEX 0x1B #define EFI_SECTION_MM_DEPEX 0x1C #define EFI_SECTION_SMM_DEPEX EFI_SECTION_MM_DEPEX /// /// Common section header. /// typedef struct { /// /// A 24-bit unsigned integer that contains the total size of the section in bytes, /// including the EFI_COMMON_SECTION_HEADER. /// UINT8 Size[3]; EFI_SECTION_TYPE Type; /// /// Declares the section type. /// } EFI_COMMON_SECTION_HEADER; typedef struct { /// /// A 24-bit unsigned integer that contains the total size of the section in bytes, /// including the EFI_COMMON_SECTION_HEADER. /// UINT8 Size[3]; EFI_SECTION_TYPE Type; /// /// If Size is 0xFFFFFF, then ExtendedSize contains the size of the section. If /// Size is not equal to 0xFFFFFF, then this field does not exist. /// UINT32 ExtendedSize; } EFI_COMMON_SECTION_HEADER2; /// /// Leaf section type that contains an /// IA-32 16-bit executable image. /// typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2; /// /// CompressionType of EFI_COMPRESSION_SECTION. /// #define EFI_NOT_COMPRESSED 0x00 #define EFI_STANDARD_COMPRESSION 0x01 /// /// An encapsulation section type in which the /// section data is compressed. /// typedef struct { /// /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. /// EFI_COMMON_SECTION_HEADER CommonHeader; /// /// The UINT32 that indicates the size of the section data after decompression. /// UINT32 UncompressedLength; /// /// Indicates which compression algorithm is used. /// UINT8 CompressionType; } EFI_COMPRESSION_SECTION; typedef struct { /// /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. /// EFI_COMMON_SECTION_HEADER2 CommonHeader; /// /// UINT32 that indicates the size of the section data after decompression. /// UINT32 UncompressedLength; /// /// Indicates which compression algorithm is used. /// UINT8 CompressionType; } EFI_COMPRESSION_SECTION2; /// /// An encapsulation section type in which the section data is disposable. /// A disposable section is an encapsulation section in which the section data may be disposed of during /// the process of creating or updating a firmware image without significant impact on the usefulness of /// the file. The Type field in the section header is set to EFI_SECTION_DISPOSABLE. This /// allows optional or descriptive data to be included with the firmware file which can be removed in /// order to conserve space. The contents of this section are implementation specific, but might contain /// debug data or detailed integration instructions. /// typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2; /// /// The leaf section which could be used to determine the dispatch order of DXEs. /// typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2; /// /// The leaf section which contains a PI FV. /// typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2; /// /// The leaf section which contains a single GUID. /// typedef struct { /// /// Common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. /// EFI_COMMON_SECTION_HEADER CommonHeader; /// /// This GUID is defined by the creator of the file. It is a vendor-defined file type. /// EFI_GUID SubTypeGuid; } EFI_FREEFORM_SUBTYPE_GUID_SECTION; typedef struct { /// /// The common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. /// EFI_COMMON_SECTION_HEADER2 CommonHeader; /// /// This GUID is defined by the creator of the file. It is a vendor-defined file type. /// EFI_GUID SubTypeGuid; } EFI_FREEFORM_SUBTYPE_GUID_SECTION2; /// /// Attributes of EFI_GUID_DEFINED_SECTION. /// #define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 #define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 /// /// The leaf section which is encapsulation defined by specific GUID. /// typedef struct { /// /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. /// EFI_COMMON_SECTION_HEADER CommonHeader; /// /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. /// EFI_GUID SectionDefinitionGuid; /// /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. /// UINT16 DataOffset; /// /// The bit field that declares some specific characteristics of the section contents. /// UINT16 Attributes; } EFI_GUID_DEFINED_SECTION; typedef struct { /// /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. /// EFI_COMMON_SECTION_HEADER2 CommonHeader; /// /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. /// EFI_GUID SectionDefinitionGuid; /// /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. /// UINT16 DataOffset; /// /// The bit field that declares some specific characteristics of the section contents. /// UINT16 Attributes; } EFI_GUID_DEFINED_SECTION2; /// /// The leaf section which contains PE32+ image. /// typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2; /// /// The leaf section used to determine the dispatch order of PEIMs. /// typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2; /// /// A leaf section type that contains a position-independent-code (PIC) image. /// A PIC image section is a leaf section that contains a position-independent-code (PIC) image. /// In addition to normal PE32+ images that contain relocation information, PEIM executables may be /// PIC and are referred to as PIC images. A PIC image is the same as a PE32+ image except that all /// relocation information has been stripped from the image and the image can be moved and will /// execute correctly without performing any relocation or other fix-ups. EFI_PIC_SECTION2 must /// be used if the section is 16MB or larger. /// typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2; /// /// The leaf section which constains the position-independent-code image. /// typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2; /// /// The leaf section which contains an array of zero or more bytes. /// typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2; /// /// The SMM dependency expression section is a leaf section that contains a dependency expression that /// is used to determine the dispatch order for SMM drivers. Before the SMRAM invocation of the /// SMM driver's entry point, this dependency expression must evaluate to TRUE. See the Platform /// Initialization Specification, Volume 2, for details regarding the format of the dependency expression. /// The dependency expression may refer to protocols installed in either the UEFI or the SMM protocol /// database. EFI_SMM_DEPEX_SECTION2 must be used if the section is 16MB or larger. /// typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION; typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2; /// /// The leaf section which contains a unicode string that /// is human readable file name. /// typedef struct { EFI_COMMON_SECTION_HEADER CommonHeader; /// /// Array of unicode string. /// CHAR16 FileNameString[1]; } EFI_USER_INTERFACE_SECTION; typedef struct { EFI_COMMON_SECTION_HEADER2 CommonHeader; CHAR16 FileNameString[1]; } EFI_USER_INTERFACE_SECTION2; /// /// The leaf section which contains a numeric build number and /// an optional unicode string that represents the file revision. /// typedef struct { EFI_COMMON_SECTION_HEADER CommonHeader; UINT16 BuildNumber; /// /// Array of unicode string. /// CHAR16 VersionString[1]; } EFI_VERSION_SECTION; typedef struct { EFI_COMMON_SECTION_HEADER2 CommonHeader; /// /// A UINT16 that represents a particular build. Subsequent builds have monotonically /// increasing build numbers relative to earlier builds. /// UINT16 BuildNumber; CHAR16 VersionString[1]; } EFI_VERSION_SECTION2; /// /// The argument passed as the SectionHeaderPtr parameter to the SECTION_SIZE() /// and IS_SECTION2() function-like macros below must not have side effects: /// SectionHeaderPtr is evaluated multiple times. /// #define SECTION_SIZE(SectionHeaderPtr) ((UINT32) (\ (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[0] ) | \ (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[1] << 8) | \ (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[2] << 16))) #define IS_SECTION2(SectionHeaderPtr) \ (SECTION_SIZE (SectionHeaderPtr) == 0x00ffffff) #define SECTION2_SIZE(SectionHeaderPtr) \ (((EFI_COMMON_SECTION_HEADER2 *) (UINTN) SectionHeaderPtr)->ExtendedSize) #pragma pack() #endif /** @file The firmware volume related definitions in PI. @par Revision Reference: Version 1.2C Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PI_FIRMWAREVOLUME_H__ #define __PI_FIRMWAREVOLUME_H__ // // EFI_FV_FILE_ATTRIBUTES // typedef UINT32 EFI_FV_FILE_ATTRIBUTES; // // Value of EFI_FV_FILE_ATTRIBUTES. // #define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F #define EFI_FV_FILE_ATTRIB_FIXED 0x00000100 #define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200 typedef UINT32 EFI_FVB_ATTRIBUTES_2; // // Attributes bit definitions // #define EFI_FVB2_READ_DISABLED_CAP 0x00000001 #define EFI_FVB2_READ_ENABLED_CAP 0x00000002 #define EFI_FVB2_READ_STATUS 0x00000004 #define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 #define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 #define EFI_FVB2_WRITE_STATUS 0x00000020 #define EFI_FVB2_LOCK_CAP 0x00000040 #define EFI_FVB2_LOCK_STATUS 0x00000080 #define EFI_FVB2_STICKY_WRITE 0x00000200 #define EFI_FVB2_MEMORY_MAPPED 0x00000400 #define EFI_FVB2_ERASE_POLARITY 0x00000800 #define EFI_FVB2_READ_LOCK_CAP 0x00001000 #define EFI_FVB2_READ_LOCK_STATUS 0x00002000 #define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 #define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 #define EFI_FVB2_ALIGNMENT 0x001F0000 #define EFI_FVB2_WEAK_ALIGNMENT 0x80000000 #define EFI_FVB2_ALIGNMENT_1 0x00000000 #define EFI_FVB2_ALIGNMENT_2 0x00010000 #define EFI_FVB2_ALIGNMENT_4 0x00020000 #define EFI_FVB2_ALIGNMENT_8 0x00030000 #define EFI_FVB2_ALIGNMENT_16 0x00040000 #define EFI_FVB2_ALIGNMENT_32 0x00050000 #define EFI_FVB2_ALIGNMENT_64 0x00060000 #define EFI_FVB2_ALIGNMENT_128 0x00070000 #define EFI_FVB2_ALIGNMENT_256 0x00080000 #define EFI_FVB2_ALIGNMENT_512 0x00090000 #define EFI_FVB2_ALIGNMENT_1K 0x000A0000 #define EFI_FVB2_ALIGNMENT_2K 0x000B0000 #define EFI_FVB2_ALIGNMENT_4K 0x000C0000 #define EFI_FVB2_ALIGNMENT_8K 0x000D0000 #define EFI_FVB2_ALIGNMENT_16K 0x000E0000 #define EFI_FVB2_ALIGNMENT_32K 0x000F0000 #define EFI_FVB2_ALIGNMENT_64K 0x00100000 #define EFI_FVB2_ALIGNMENT_128K 0x00110000 #define EFI_FVB2_ALIGNMENT_256K 0x00120000 #define EFI_FVB2_ALIGNMENT_512K 0x00130000 #define EFI_FVB2_ALIGNMENT_1M 0x00140000 #define EFI_FVB2_ALIGNMENT_2M 0x00150000 #define EFI_FVB2_ALIGNMENT_4M 0x00160000 #define EFI_FVB2_ALIGNMENT_8M 0x00170000 #define EFI_FVB2_ALIGNMENT_16M 0x00180000 #define EFI_FVB2_ALIGNMENT_32M 0x00190000 #define EFI_FVB2_ALIGNMENT_64M 0x001A0000 #define EFI_FVB2_ALIGNMENT_128M 0x001B0000 #define EFI_FVB2_ALIGNMENT_256M 0x001C0000 #define EFI_FVB2_ALIGNMENT_512M 0x001D0000 #define EFI_FVB2_ALIGNMENT_1G 0x001E0000 #define EFI_FVB2_ALIGNMENT_2G 0x001F0000 typedef struct { UINT32 NumBlocks; UINT32 Length; } EFI_FV_BLOCK_MAP_ENTRY; // // Describes the features and layout of the firmware volume. // typedef struct { UINT8 ZeroVector[16]; EFI_GUID FileSystemGuid; UINT64 FvLength; UINT32 Signature; EFI_FVB_ATTRIBUTES_2 Attributes; UINT16 HeaderLength; UINT16 Checksum; UINT16 ExtHeaderOffset; UINT8 Reserved[1]; UINT8 Revision; EFI_FV_BLOCK_MAP_ENTRY BlockMap[1]; } EFI_FIRMWARE_VOLUME_HEADER; #define EFI_FVH_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', 'H') /// /// Firmware Volume Header Revision definition /// #define EFI_FVH_REVISION 0x02 // // Extension header pointed by ExtHeaderOffset of volume header. // typedef struct { EFI_GUID FvName; UINT32 ExtHeaderSize; } EFI_FIRMWARE_VOLUME_EXT_HEADER; typedef struct { UINT16 ExtEntrySize; UINT16 ExtEntryType; } EFI_FIRMWARE_VOLUME_EXT_ENTRY; #define EFI_FV_EXT_TYPE_OEM_TYPE 0x01 typedef struct { EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; UINT32 TypeMask; // // Array of GUIDs. // Each GUID represents an OEM file type. // // EFI_GUID Types[1]; // } EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE; #define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002 typedef struct { EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; EFI_GUID FormatType; // // An array of bytes of length Length. // // UINT8 Data[1]; // } EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE; #define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03 typedef struct { EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; UINT32 UsedSize; } EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE; #endif /** @file HOB related definitions in PI. Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.6 **/ #ifndef __PI_HOB_H__ #define __PI_HOB_H__ // // HobType of EFI_HOB_GENERIC_HEADER. // #define EFI_HOB_TYPE_HANDOFF 0x0001 #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002 #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003 #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004 #define EFI_HOB_TYPE_FV 0x0005 #define EFI_HOB_TYPE_CPU 0x0006 #define EFI_HOB_TYPE_MEMORY_POOL 0x0007 #define EFI_HOB_TYPE_FV2 0x0009 #define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A #define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B #define EFI_HOB_TYPE_FV3 0x000C #define EFI_HOB_TYPE_UNUSED 0xFFFE #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF /// /// Describes the format and size of the data inside the HOB. /// All HOBs must contain this generic HOB header. /// typedef struct { /// /// Identifies the HOB data structure type. /// UINT16 HobType; /// /// The length in bytes of the HOB. /// UINT16 HobLength; /// /// This field must always be set to zero. /// UINT32 Reserved; } EFI_HOB_GENERIC_HEADER; /// /// Value of version in EFI_HOB_HANDOFF_INFO_TABLE. /// #define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009 /// /// Contains general state information used by the HOB producer phase. /// This HOB must be the first one in the HOB list. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_HANDOFF. /// EFI_HOB_GENERIC_HEADER Header; /// /// The version number pertaining to the PHIT HOB definition. /// This value is four bytes in length to provide an 8-byte aligned entry /// when it is combined with the 4-byte BootMode. /// UINT32 Version; /// /// The system boot mode as determined during the HOB producer phase. /// EFI_BOOT_MODE BootMode; /// /// The highest address location of memory that is allocated for use by the HOB producer /// phase. This address must be 4-KB aligned to meet page restrictions of UEFI. /// EFI_PHYSICAL_ADDRESS EfiMemoryTop; /// /// The lowest address location of memory that is allocated for use by the HOB producer phase. /// EFI_PHYSICAL_ADDRESS EfiMemoryBottom; /// /// The highest address location of free memory that is currently available /// for use by the HOB producer phase. /// EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop; /// /// The lowest address location of free memory that is available for use by the HOB producer phase. /// EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom; /// /// The end of the HOB list. /// EFI_PHYSICAL_ADDRESS EfiEndOfHobList; } EFI_HOB_HANDOFF_INFO_TABLE; /// /// EFI_HOB_MEMORY_ALLOCATION_HEADER describes the /// various attributes of the logical memory allocation. The type field will be used for /// subsequent inclusion in the UEFI memory map. /// typedef struct { /// /// A GUID that defines the memory allocation region's type and purpose, as well as /// other fields within the memory allocation HOB. This GUID is used to define the /// additional data within the HOB that may be present for the memory allocation HOB. /// Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0 /// specification. /// EFI_GUID Name; /// /// The base address of memory allocated by this HOB. Type /// EFI_PHYSICAL_ADDRESS is defined in AllocatePages() in the UEFI 2.0 /// specification. /// EFI_PHYSICAL_ADDRESS MemoryBaseAddress; /// /// The length in bytes of memory allocated by this HOB. /// UINT64 MemoryLength; /// /// Defines the type of memory allocated by this HOB. The memory type definition /// follows the EFI_MEMORY_TYPE definition. Type EFI_MEMORY_TYPE is defined /// in AllocatePages() in the UEFI 2.0 specification. /// EFI_MEMORY_TYPE MemoryType; /// /// Padding for Itanium processor family /// UINT8 Reserved[4]; } EFI_HOB_MEMORY_ALLOCATION_HEADER; /// /// Describes all memory ranges used during the HOB producer /// phase that exist outside the HOB list. This HOB type /// describes how memory is used, not the physical attributes of memory. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION. /// EFI_HOB_GENERIC_HEADER Header; /// /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the /// various attributes of the logical memory allocation. /// EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; // // Additional data pertaining to the "Name" Guid memory // may go here. // } EFI_HOB_MEMORY_ALLOCATION; /// /// Describes the memory stack that is produced by the HOB producer /// phase and upon which all post-memory-installed executable /// content in the HOB producer phase is executing. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION. /// EFI_HOB_GENERIC_HEADER Header; /// /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the /// various attributes of the logical memory allocation. /// EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; } EFI_HOB_MEMORY_ALLOCATION_STACK; /// /// Defines the location of the boot-strap /// processor (BSP) BSPStore ("Backing Store Pointer Store"). /// This HOB is valid for the Itanium processor family only /// register overflow store. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION. /// EFI_HOB_GENERIC_HEADER Header; /// /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the /// various attributes of the logical memory allocation. /// EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor; } EFI_HOB_MEMORY_ALLOCATION_BSP_STORE; /// /// Defines the location and entry point of the HOB consumer phase. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION. /// EFI_HOB_GENERIC_HEADER Header; /// /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the /// various attributes of the logical memory allocation. /// EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader; /// /// The GUID specifying the values of the firmware file system name /// that contains the HOB consumer phase component. /// EFI_GUID ModuleName; /// /// The address of the memory-mapped firmware volume /// that contains the HOB consumer phase firmware file. /// EFI_PHYSICAL_ADDRESS EntryPoint; } EFI_HOB_MEMORY_ALLOCATION_MODULE; /// /// The resource type. /// typedef UINT32 EFI_RESOURCE_TYPE; // // Value of ResourceType in EFI_HOB_RESOURCE_DESCRIPTOR. // #define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000 #define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001 #define EFI_RESOURCE_IO 0x00000002 #define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003 #define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004 #define EFI_RESOURCE_MEMORY_RESERVED 0x00000005 #define EFI_RESOURCE_IO_RESERVED 0x00000006 #define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000007 /// /// A type of recount attribute type. /// typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE; // // These types can be ORed together as needed. // // The following attributes are used to describe settings // #define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001 #define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002 #define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080 // // This is typically used as memory cacheability attribute today. // NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED // as Physical write protected attribute, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED // means Memory cacheability attribute: The memory supports being programmed with // a writeprotected cacheable attribute. // #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200 #define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000 // // The rest of the attributes are used to describe capabilities // #define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008 #define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010 #define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020 #define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040 #define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400 #define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800 #define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000 #define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000 #define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000 #define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000 #define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000 #define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000 // // This is typically used as memory cacheability attribute today. // NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE // as Memory capability attribute: The memory supports being protected from processor // writes, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTEC TABLE means Memory cacheability attribute: // The memory supports being programmed with a writeprotected cacheable attribute. // #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000 #define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000 #define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000 #define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000 // // Physical memory relative reliability attribute. This // memory provides higher reliability relative to other // memory in the system. If all memory has the same // reliability, then this bit is not used. // #define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000 /// /// Describes the resource properties of all fixed, /// nonrelocatable resource ranges found on the processor /// host bus during the HOB producer phase. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. /// EFI_HOB_GENERIC_HEADER Header; /// /// A GUID representing the owner of the resource. This GUID is used by HOB /// consumer phase components to correlate device ownership of a resource. /// EFI_GUID Owner; /// /// The resource type enumeration as defined by EFI_RESOURCE_TYPE. /// EFI_RESOURCE_TYPE ResourceType; /// /// Resource attributes as defined by EFI_RESOURCE_ATTRIBUTE_TYPE. /// EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; /// /// The physical start address of the resource region. /// EFI_PHYSICAL_ADDRESS PhysicalStart; /// /// The number of bytes of the resource region. /// UINT64 ResourceLength; } EFI_HOB_RESOURCE_DESCRIPTOR; /// /// Allows writers of executable content in the HOB producer phase to /// maintain and manage HOBs with specific GUID. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_GUID_EXTENSION. /// EFI_HOB_GENERIC_HEADER Header; /// /// A GUID that defines the contents of this HOB. /// EFI_GUID Name; // // Guid specific data goes here // } EFI_HOB_GUID_TYPE; /// /// Details the location of firmware volumes that contain firmware files. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV. /// EFI_HOB_GENERIC_HEADER Header; /// /// The physical memory-mapped base address of the firmware volume. /// EFI_PHYSICAL_ADDRESS BaseAddress; /// /// The length in bytes of the firmware volume. /// UINT64 Length; } EFI_HOB_FIRMWARE_VOLUME; /// /// Details the location of a firmware volume that was extracted /// from a file within another firmware volume. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV2. /// EFI_HOB_GENERIC_HEADER Header; /// /// The physical memory-mapped base address of the firmware volume. /// EFI_PHYSICAL_ADDRESS BaseAddress; /// /// The length in bytes of the firmware volume. /// UINT64 Length; /// /// The name of the firmware volume. /// EFI_GUID FvName; /// /// The name of the firmware file that contained this firmware volume. /// EFI_GUID FileName; } EFI_HOB_FIRMWARE_VOLUME2; /// /// Details the location of a firmware volume that was extracted /// from a file within another firmware volume. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV3. /// EFI_HOB_GENERIC_HEADER Header; /// /// The physical memory-mapped base address of the firmware volume. /// EFI_PHYSICAL_ADDRESS BaseAddress; /// /// The length in bytes of the firmware volume. /// UINT64 Length; /// /// The authentication status. /// UINT32 AuthenticationStatus; /// /// TRUE if the FV was extracted as a file within another firmware volume. /// FALSE otherwise. /// BOOLEAN ExtractedFv; /// /// The name of the firmware volume. /// Valid only if IsExtractedFv is TRUE. /// EFI_GUID FvName; /// /// The name of the firmware file that contained this firmware volume. /// Valid only if IsExtractedFv is TRUE. /// EFI_GUID FileName; } EFI_HOB_FIRMWARE_VOLUME3; /// /// Describes processor information, such as address space and I/O space capabilities. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_CPU. /// EFI_HOB_GENERIC_HEADER Header; /// /// Identifies the maximum physical memory addressability of the processor. /// UINT8 SizeOfMemorySpace; /// /// Identifies the maximum physical I/O addressability of the processor. /// UINT8 SizeOfIoSpace; /// /// This field will always be set to zero. /// UINT8 Reserved[6]; } EFI_HOB_CPU; /// /// Describes pool memory allocations. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_POOL. /// EFI_HOB_GENERIC_HEADER Header; } EFI_HOB_MEMORY_POOL; /// /// Each UEFI capsule HOB details the location of a UEFI capsule. It includes a base address and length /// which is based upon memory blocks with a EFI_CAPSULE_HEADER and the associated /// CapsuleImageSize-based payloads. These HOB's shall be created by the PEI PI firmware /// sometime after the UEFI UpdateCapsule service invocation with the /// CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag set in the EFI_CAPSULE_HEADER. /// typedef struct { /// /// The HOB generic header where Header.HobType = EFI_HOB_TYPE_UEFI_CAPSULE. /// EFI_HOB_GENERIC_HEADER Header; /// /// The physical memory-mapped base address of an UEFI capsule. This value is set to /// point to the base of the contiguous memory of the UEFI capsule. /// The length of the contiguous memory in bytes. /// EFI_PHYSICAL_ADDRESS BaseAddress; UINT64 Length; } EFI_HOB_UEFI_CAPSULE; /// /// Union of all the possible HOB Types. /// typedef union { EFI_HOB_GENERIC_HEADER *Header; EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; EFI_HOB_MEMORY_ALLOCATION *MemoryAllocation; EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore; EFI_HOB_MEMORY_ALLOCATION_STACK *MemoryAllocationStack; EFI_HOB_MEMORY_ALLOCATION_MODULE *MemoryAllocationModule; EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor; EFI_HOB_GUID_TYPE *Guid; EFI_HOB_FIRMWARE_VOLUME *FirmwareVolume; EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2; EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3; EFI_HOB_CPU *Cpu; EFI_HOB_MEMORY_POOL *Pool; EFI_HOB_UEFI_CAPSULE *Capsule; UINT8 *Raw; } EFI_PEI_HOB_POINTERS; #endif /** @file Include file matches things in PI for multiple module types. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: These elements are defined in UEFI Platform Initialization Specification 1.2. **/ #ifndef __PI_MULTIPHASE_H__ #define __PI_MULTIPHASE_H__ #include #include #include #include #include #include #include /** Produces an error code in the range reserved for use by the Platform Initialization Architecture Specification. The supported 32-bit range is 0xA0000000-0xBFFFFFFF The supported 64-bit range is 0xA000000000000000-0xBFFFFFFFFFFFFFFF @param StatusCode The status code value to convert into a warning code. StatusCode must be in the range 0x00000000..0x1FFFFFFF. @return The value specified by StatusCode in the PI reserved range. **/ #define DXE_ERROR(StatusCode) (MAX_BIT | (MAX_BIT >> 2) | StatusCode) /// /// If this value is returned by an EFI image, then the image should be unloaded. /// #define EFI_REQUEST_UNLOAD_IMAGE DXE_ERROR (1) /// /// If this value is returned by an API, it means the capability is not yet /// installed/available/ready to use. /// #define EFI_NOT_AVAILABLE_YET DXE_ERROR (2) /// /// Success and warning codes reserved for use by PI. /// Supported 32-bit range is 0x20000000-0x3fffffff. /// Supported 64-bit range is 0x2000000000000000-0x3fffffffffffffff. /// #define PI_ENCODE_WARNING(a) ((MAX_BIT >> 2) | (a)) /// /// Error codes reserved for use by PI. /// Supported 32-bit range is 0xa0000000-0xbfffffff. /// Supported 64-bit range is 0xa000000000000000-0xbfffffffffffffff. /// #define PI_ENCODE_ERROR(a) (MAX_BIT | (MAX_BIT >> 2) | (a)) /// /// Return status codes defined in SMM CIS. /// #define EFI_INTERRUPT_PENDING PI_ENCODE_ERROR (0) #define EFI_WARN_INTERRUPT_SOURCE_PENDING PI_ENCODE_WARNING (0) #define EFI_WARN_INTERRUPT_SOURCE_QUIESCED PI_ENCODE_WARNING (1) /// /// Bitmask of values for Authentication Status. /// Authentication Status is returned from EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL /// and the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI /// /// xx00 Image was not signed. /// xxx1 Platform security policy override. Assumes the same meaning as 0010 (the image was signed, the /// signature was tested, and the signature passed authentication test). /// 0010 Image was signed, the signature was tested, and the signature passed authentication test. /// 0110 Image was signed and the signature was not tested. /// 1010 Image was signed, the signature was tested, and the signature failed the authentication test. /// ///@{ #define EFI_AUTH_STATUS_PLATFORM_OVERRIDE 0x01 #define EFI_AUTH_STATUS_IMAGE_SIGNED 0x02 #define EFI_AUTH_STATUS_NOT_TESTED 0x04 #define EFI_AUTH_STATUS_TEST_FAILED 0x08 #define EFI_AUTH_STATUS_ALL 0x0f ///@} /// /// MMRAM states and capabilities /// #define EFI_MMRAM_OPEN 0x00000001 #define EFI_MMRAM_CLOSED 0x00000002 #define EFI_MMRAM_LOCKED 0x00000004 #define EFI_CACHEABLE 0x00000008 #define EFI_ALLOCATED 0x00000010 #define EFI_NEEDS_TESTING 0x00000020 #define EFI_NEEDS_ECC_INITIALIZATION 0x00000040 #define EFI_SMRAM_OPEN EFI_MMRAM_OPEN #define EFI_SMRAM_CLOSED EFI_MMRAM_CLOSED #define EFI_SMRAM_LOCKED EFI_MMRAM_LOCKED /// /// Structure describing a MMRAM region and its accessibility attributes. /// typedef struct { /// /// Designates the physical address of the MMRAM in memory. This view of memory is /// the same as seen by I/O-based agents, for example, but it may not be the address seen /// by the processors. /// EFI_PHYSICAL_ADDRESS PhysicalStart; /// /// Designates the address of the MMRAM, as seen by software executing on the /// processors. This address may or may not match PhysicalStart. /// EFI_PHYSICAL_ADDRESS CpuStart; /// /// Describes the number of bytes in the MMRAM region. /// UINT64 PhysicalSize; /// /// Describes the accessibility attributes of the MMRAM. These attributes include the /// hardware state (e.g., Open/Closed/Locked), capability (e.g., cacheable), logical /// allocation (e.g., allocated), and pre-use initialization (e.g., needs testing/ECC /// initialization). /// UINT64 RegionState; } EFI_MMRAM_DESCRIPTOR; typedef EFI_MMRAM_DESCRIPTOR EFI_SMRAM_DESCRIPTOR; /// /// Structure describing a MMRAM region which cannot be used for the MMRAM heap. /// typedef struct _EFI_MM_RESERVED_MMRAM_REGION { /// /// Starting address of the reserved MMRAM area, as it appears while MMRAM is open. /// Ignored if MmramReservedSize is 0. /// EFI_PHYSICAL_ADDRESS MmramReservedStart; /// /// Number of bytes occupied by the reserved MMRAM area. A size of zero indicates the /// last MMRAM area. /// UINT64 MmramReservedSize; } EFI_MM_RESERVED_MMRAM_REGION; typedef enum { EFI_PCD_TYPE_8, EFI_PCD_TYPE_16, EFI_PCD_TYPE_32, EFI_PCD_TYPE_64, EFI_PCD_TYPE_BOOL, EFI_PCD_TYPE_PTR } EFI_PCD_TYPE; typedef struct { /// /// The returned information associated with the requested TokenNumber. If /// TokenNumber is 0, then PcdType is set to EFI_PCD_TYPE_8. /// EFI_PCD_TYPE PcdType; /// /// The size of the data in bytes associated with the TokenNumber specified. If /// TokenNumber is 0, then PcdSize is set 0. /// UINTN PcdSize; /// /// The null-terminated ASCII string associated with a given token. If the /// TokenNumber specified was 0, then this field corresponds to the null-terminated /// ASCII string associated with the token's namespace Guid. If NULL, there is no /// name associated with this request. /// CHAR8 *PcdName; } EFI_PCD_INFO; /** The function prototype for invoking a function on an Application Processor. This definition is used by the UEFI MP Serices Protocol, and the PI SMM System Table. @param[in,out] Buffer The pointer to private data buffer. **/ typedef VOID (EFIAPI *EFI_AP_PROCEDURE)( IN OUT VOID *Buffer ); /** The function prototype for invoking a function on an Application Processor. This definition is used by the UEFI MM MP Serices Protocol. @param[in] ProcedureArgument The pointer to private data buffer. @retval EFI_SUCCESS Excutive the procedure successfully **/ typedef EFI_STATUS (EFIAPI *EFI_AP_PROCEDURE2)( IN VOID *ProcedureArgument ); #endif /** @file This file contains the boot script defintions that are shared between the Boot Script Executor PPI and the Boot Script Save Protocol. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _PI_S3_BOOT_SCRIPT_H_ #define _PI_S3_BOOT_SCRIPT_H_ // ******************************************* // EFI Boot Script Opcode definitions // ******************************************* #define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00 #define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01 #define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02 #define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03 #define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04 #define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05 #define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06 #define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07 #define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08 #define EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE 0x09 #define EFI_BOOT_SCRIPT_INFORMATION_OPCODE 0x0A #define EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE 0x0B #define EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE 0x0C #define EFI_BOOT_SCRIPT_IO_POLL_OPCODE 0x0D #define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE 0x0E #define EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE 0x0F #define EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE 0x10 // ******************************************* // EFI_BOOT_SCRIPT_WIDTH // ******************************************* typedef enum { EfiBootScriptWidthUint8, EfiBootScriptWidthUint16, EfiBootScriptWidthUint32, EfiBootScriptWidthUint64, EfiBootScriptWidthFifoUint8, EfiBootScriptWidthFifoUint16, EfiBootScriptWidthFifoUint32, EfiBootScriptWidthFifoUint64, EfiBootScriptWidthFillUint8, EfiBootScriptWidthFillUint16, EfiBootScriptWidthFillUint32, EfiBootScriptWidthFillUint64, EfiBootScriptWidthMaximum } EFI_BOOT_SCRIPT_WIDTH; #endif /** @file StatusCode related definitions in PI. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: These status codes are defined in UEFI Platform Initialization Specification 1.2, Volume 3: Shared Architectural Elements. **/ #ifndef __PI_STATUS_CODE_H__ #define __PI_STATUS_CODE_H__ // // Required for IA32, X64, IPF, ARM and EBC defines for CPU exception types // #include /// /// Status Code Type Definition. /// typedef UINT32 EFI_STATUS_CODE_TYPE; /// /// A Status Code Type is made up of the code type and severity. /// All values masked by EFI_STATUS_CODE_RESERVED_MASK are /// reserved for use by this specification. /// ///@{ #define EFI_STATUS_CODE_TYPE_MASK 0x000000FF #define EFI_STATUS_CODE_SEVERITY_MASK 0xFF000000 #define EFI_STATUS_CODE_RESERVED_MASK 0x00FFFF00 ///@} /// /// Definition of code types. All other values masked by /// EFI_STATUS_CODE_TYPE_MASK are reserved for use by /// this specification. /// ///@{ #define EFI_PROGRESS_CODE 0x00000001 #define EFI_ERROR_CODE 0x00000002 #define EFI_DEBUG_CODE 0x00000003 ///@} /// /// Definitions of severities, all other values masked by /// EFI_STATUS_CODE_SEVERITY_MASK are reserved for use by /// this specification. /// Uncontained errors are major errors that could not contained /// to the specific component that is reporting the error. /// For example, if a memory error was not detected early enough, /// the bad data could be consumed by other drivers. /// ///@{ #define EFI_ERROR_MINOR 0x40000000 #define EFI_ERROR_MAJOR 0x80000000 #define EFI_ERROR_UNRECOVERED 0x90000000 #define EFI_ERROR_UNCONTAINED 0xa0000000 ///@} /// /// Status Code Value Definition. /// typedef UINT32 EFI_STATUS_CODE_VALUE; /// /// A Status Code Value is made up of the class, subclass, and /// an operation. /// ///@{ #define EFI_STATUS_CODE_CLASS_MASK 0xFF000000 #define EFI_STATUS_CODE_SUBCLASS_MASK 0x00FF0000 #define EFI_STATUS_CODE_OPERATION_MASK 0x0000FFFF ///@} /// /// Definition of Status Code extended data header. /// The data will follow HeaderSize bytes from the beginning of /// the structure and is Size bytes long. /// typedef struct { /// /// The size of the structure. This is specified to enable future expansion. /// UINT16 HeaderSize; /// /// The size of the data in bytes. This does not include the size of the header structure. /// UINT16 Size; /// /// The GUID defining the type of the data. /// EFI_GUID Type; } EFI_STATUS_CODE_DATA; /// /// General partitioning scheme for Progress and Error Codes are: /// - 0x0000-0x0FFF Shared by all sub-classes in a given class. /// - 0x1000-0x7FFF Subclass Specific. /// - 0x8000-0xFFFF OEM specific. ///@{ #define EFI_SUBCLASS_SPECIFIC 0x1000 #define EFI_OEM_SPECIFIC 0x8000 ///@} /// /// Debug Code definitions for all classes and subclass. /// Only one debug code is defined at this point and should /// be used for anything that is sent to the debug stream. /// ///@{ #define EFI_DC_UNSPECIFIED 0x0 ///@} /// /// Class definitions. /// Values of 4-127 are reserved for future use by this specification. /// Values in the range 127-255 are reserved for OEM use. /// ///@{ #define EFI_COMPUTING_UNIT 0x00000000 #define EFI_PERIPHERAL 0x01000000 #define EFI_IO_BUS 0x02000000 #define EFI_SOFTWARE 0x03000000 ///@} /// /// Computing Unit Subclass definitions. /// Values of 8-127 are reserved for future use by this specification. /// Values of 128-255 are reserved for OEM use. /// ///@{ #define EFI_COMPUTING_UNIT_UNSPECIFIED (EFI_COMPUTING_UNIT | 0x00000000) #define EFI_COMPUTING_UNIT_HOST_PROCESSOR (EFI_COMPUTING_UNIT | 0x00010000) #define EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR (EFI_COMPUTING_UNIT | 0x00020000) #define EFI_COMPUTING_UNIT_IO_PROCESSOR (EFI_COMPUTING_UNIT | 0x00030000) #define EFI_COMPUTING_UNIT_CACHE (EFI_COMPUTING_UNIT | 0x00040000) #define EFI_COMPUTING_UNIT_MEMORY (EFI_COMPUTING_UNIT | 0x00050000) #define EFI_COMPUTING_UNIT_CHIPSET (EFI_COMPUTING_UNIT | 0x00060000) ///@} /// /// Computing Unit Class Progress Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_CU_PC_INIT_BEGIN 0x00000000 #define EFI_CU_PC_INIT_END 0x00000001 ///@} // // Computing Unit Unspecified Subclass Progress Code definitions. // /// /// Computing Unit Host Processor Subclass Progress Code definitions. ///@{ #define EFI_CU_HP_PC_POWER_ON_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_HP_PC_CACHE_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_HP_PC_RAM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CU_HP_PC_MEMORY_CONTROLLER_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_CU_HP_PC_IO_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_CU_HP_PC_BSP_SELECT (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_CU_HP_PC_BSP_RESELECT (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_CU_HP_PC_AP_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_CU_HP_PC_SMM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000008) ///@} // // Computing Unit Firmware Processor Subclass Progress Code definitions. // // // Computing Unit IO Processor Subclass Progress Code definitions. // /// /// Computing Unit Cache Subclass Progress Code definitions. /// ///@{ #define EFI_CU_CACHE_PC_PRESENCE_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_CACHE_PC_CONFIGURATION (EFI_SUBCLASS_SPECIFIC | 0x00000001) ///@} /// /// Computing Unit Memory Subclass Progress Code definitions. /// ///@{ #define EFI_CU_MEMORY_PC_SPD_READ (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_MEMORY_PC_PRESENCE_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_MEMORY_PC_TIMING (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CU_MEMORY_PC_CONFIGURING (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_CU_MEMORY_PC_OPTIMIZING (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_CU_MEMORY_PC_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_CU_MEMORY_PC_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000006) ///@} // // Computing Unit Chipset Subclass Progress Code definitions. // /// /// South Bridge initialization prior to memory detection. /// #define EFI_CHIPSET_PC_PEI_CAR_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000000) /// /// North Bridge initialization prior to memory detection. /// #define EFI_CHIPSET_PC_PEI_CAR_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000001) /// /// South Bridge initialization after memory detection. /// #define EFI_CHIPSET_PC_PEI_MEM_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000002) /// /// North Bridge initialization after memory detection. /// #define EFI_CHIPSET_PC_PEI_MEM_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000003) /// /// PCI Host Bridge DXE initialization. /// #define EFI_CHIPSET_PC_DXE_HB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000004) /// /// North Bridge DXE initialization. /// #define EFI_CHIPSET_PC_DXE_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000005) /// /// North Bridge specific SMM initialization in DXE. /// #define EFI_CHIPSET_PC_DXE_NB_SMM_INIT (EFI_SUBCLASS_SPECIFIC|0x00000006) /// /// Initialization of the South Bridge specific UEFI Runtime Services. /// #define EFI_CHIPSET_PC_DXE_SB_RT_INIT (EFI_SUBCLASS_SPECIFIC|0x00000007) /// /// South Bridge DXE initialization /// #define EFI_CHIPSET_PC_DXE_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000008) /// /// South Bridge specific SMM initialization in DXE. /// #define EFI_CHIPSET_PC_DXE_SB_SMM_INIT (EFI_SUBCLASS_SPECIFIC|0x00000009) /// /// Initialization of the South Bridge devices. /// #define EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT (EFI_SUBCLASS_SPECIFIC|0x0000000a) /// /// Computing Unit Class Error Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_CU_EC_NON_SPECIFIC 0x00000000 #define EFI_CU_EC_DISABLED 0x00000001 #define EFI_CU_EC_NOT_SUPPORTED 0x00000002 #define EFI_CU_EC_NOT_DETECTED 0x00000003 #define EFI_CU_EC_NOT_CONFIGURED 0x00000004 ///@} // // Computing Unit Unspecified Subclass Error Code definitions. // /// /// Computing Unit Host Processor Subclass Error Code definitions. /// ///@{ #define EFI_CU_HP_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_HP_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_HP_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CU_HP_EC_TIMER_EXPIRED (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_CU_HP_EC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_CU_HP_EC_INTERNAL (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_CU_HP_EC_THERMAL (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_CU_HP_EC_LOW_VOLTAGE (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_CU_HP_EC_HIGH_VOLTAGE (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_CU_HP_EC_CACHE (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_CU_HP_EC_MICROCODE_UPDATE (EFI_SUBCLASS_SPECIFIC | 0x0000000A) #define EFI_CU_HP_EC_CORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x0000000B) #define EFI_CU_HP_EC_UNCORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x0000000C) #define EFI_CU_HP_EC_NO_MICROCODE_UPDATE (EFI_SUBCLASS_SPECIFIC | 0x0000000D) ///@} /// /// Computing Unit Firmware Processor Subclass Error Code definitions. /// ///@{ #define EFI_CU_FP_EC_HARD_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_FP_EC_SOFT_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_FP_EC_COMM_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} // // Computing Unit IO Processor Subclass Error Code definitions. // /// /// Computing Unit Cache Subclass Error Code definitions. /// ///@{ #define EFI_CU_CACHE_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_CACHE_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_CACHE_EC_INVALID_SIZE (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CU_CACHE_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000003) ///@} /// /// Computing Unit Memory Subclass Error Code definitions. /// ///@{ #define EFI_CU_MEMORY_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CU_MEMORY_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CU_MEMORY_EC_CORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CU_MEMORY_EC_UNCORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_CU_MEMORY_EC_SPD_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_CU_MEMORY_EC_INVALID_SIZE (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_CU_MEMORY_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_CU_MEMORY_EC_S3_RESUME_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_CU_MEMORY_EC_UPDATE_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_CU_MEMORY_EC_NONE_DETECTED (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_CU_MEMORY_EC_NONE_USEFUL (EFI_SUBCLASS_SPECIFIC | 0x0000000A) ///@} /// /// Computing Unit Chipset Subclass Error Code definitions. /// ///@{ #define EFI_CHIPSET_EC_BAD_BATTERY (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_CHIPSET_EC_DXE_NB_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_CHIPSET_EC_DXE_SB_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_CHIPSET_EC_INTRUDER_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000003) ///@} /// /// Peripheral Subclass definitions. /// Values of 12-127 are reserved for future use by this specification. /// Values of 128-255 are reserved for OEM use. /// ///@{ #define EFI_PERIPHERAL_UNSPECIFIED (EFI_PERIPHERAL | 0x00000000) #define EFI_PERIPHERAL_KEYBOARD (EFI_PERIPHERAL | 0x00010000) #define EFI_PERIPHERAL_MOUSE (EFI_PERIPHERAL | 0x00020000) #define EFI_PERIPHERAL_LOCAL_CONSOLE (EFI_PERIPHERAL | 0x00030000) #define EFI_PERIPHERAL_REMOTE_CONSOLE (EFI_PERIPHERAL | 0x00040000) #define EFI_PERIPHERAL_SERIAL_PORT (EFI_PERIPHERAL | 0x00050000) #define EFI_PERIPHERAL_PARALLEL_PORT (EFI_PERIPHERAL | 0x00060000) #define EFI_PERIPHERAL_FIXED_MEDIA (EFI_PERIPHERAL | 0x00070000) #define EFI_PERIPHERAL_REMOVABLE_MEDIA (EFI_PERIPHERAL | 0x00080000) #define EFI_PERIPHERAL_AUDIO_INPUT (EFI_PERIPHERAL | 0x00090000) #define EFI_PERIPHERAL_AUDIO_OUTPUT (EFI_PERIPHERAL | 0x000A0000) #define EFI_PERIPHERAL_LCD_DEVICE (EFI_PERIPHERAL | 0x000B0000) #define EFI_PERIPHERAL_NETWORK (EFI_PERIPHERAL | 0x000C0000) #define EFI_PERIPHERAL_DOCKING (EFI_PERIPHERAL | 0x000D0000) ///@} /// /// Peripheral Class Progress Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_P_PC_INIT 0x00000000 #define EFI_P_PC_RESET 0x00000001 #define EFI_P_PC_DISABLE 0x00000002 #define EFI_P_PC_PRESENCE_DETECT 0x00000003 #define EFI_P_PC_ENABLE 0x00000004 #define EFI_P_PC_RECONFIG 0x00000005 #define EFI_P_PC_DETECTED 0x00000006 #define EFI_P_PC_REMOVED 0x00000007 ///@} // // Peripheral Class Unspecified Subclass Progress Code definitions. // /// /// Peripheral Class Keyboard Subclass Progress Code definitions. /// ///@{ #define EFI_P_KEYBOARD_PC_CLEAR_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_P_KEYBOARD_PC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000001) ///@} /// /// Peripheral Class Mouse Subclass Progress Code definitions. /// ///@{ #define EFI_P_MOUSE_PC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000000) ///@} // // Peripheral Class Local Console Subclass Progress Code definitions. // // // Peripheral Class Remote Console Subclass Progress Code definitions. // /// /// Peripheral Class Serial Port Subclass Progress Code definitions. /// ///@{ #define EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000000) ///@} // // Peripheral Class Parallel Port Subclass Progress Code definitions. // // // Peripheral Class Fixed Media Subclass Progress Code definitions. // // // Peripheral Class Removable Media Subclass Progress Code definitions. // // // Peripheral Class Audio Input Subclass Progress Code definitions. // // // Peripheral Class Audio Output Subclass Progress Code definitions. // // // Peripheral Class LCD Device Subclass Progress Code definitions. // // // Peripheral Class Network Subclass Progress Code definitions. // /// /// Peripheral Class Error Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_P_EC_NON_SPECIFIC 0x00000000 #define EFI_P_EC_DISABLED 0x00000001 #define EFI_P_EC_NOT_SUPPORTED 0x00000002 #define EFI_P_EC_NOT_DETECTED 0x00000003 #define EFI_P_EC_NOT_CONFIGURED 0x00000004 #define EFI_P_EC_INTERFACE_ERROR 0x00000005 #define EFI_P_EC_CONTROLLER_ERROR 0x00000006 #define EFI_P_EC_INPUT_ERROR 0x00000007 #define EFI_P_EC_OUTPUT_ERROR 0x00000008 #define EFI_P_EC_RESOURCE_CONFLICT 0x00000009 ///@} // // Peripheral Class Unspecified Subclass Error Code definitions. // /// /// Peripheral Class Keyboard Subclass Error Code definitions. /// ///@{ #define EFI_P_KEYBOARD_EC_LOCKED (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_P_KEYBOARD_EC_STUCK_KEY (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_P_KEYBOARD_EC_BUFFER_FULL (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} /// /// Peripheral Class Mouse Subclass Error Code definitions. /// ///@{ #define EFI_P_MOUSE_EC_LOCKED (EFI_SUBCLASS_SPECIFIC | 0x00000000) ///@} // // Peripheral Class Local Console Subclass Error Code definitions. // // // Peripheral Class Remote Console Subclass Error Code definitions. // // // Peripheral Class Serial Port Subclass Error Code definitions. // // // Peripheral Class Parallel Port Subclass Error Code definitions. // // // Peripheral Class Fixed Media Subclass Error Code definitions. // // // Peripheral Class Removable Media Subclass Error Code definitions. // // // Peripheral Class Audio Input Subclass Error Code definitions. // // // Peripheral Class Audio Output Subclass Error Code definitions. // // // Peripheral Class LCD Device Subclass Error Code definitions. // // // Peripheral Class Network Subclass Error Code definitions. // /// /// IO Bus Subclass definitions. /// Values of 14-127 are reserved for future use by this specification. /// Values of 128-255 are reserved for OEM use. /// ///@{ #define EFI_IO_BUS_UNSPECIFIED (EFI_IO_BUS | 0x00000000) #define EFI_IO_BUS_PCI (EFI_IO_BUS | 0x00010000) #define EFI_IO_BUS_USB (EFI_IO_BUS | 0x00020000) #define EFI_IO_BUS_IBA (EFI_IO_BUS | 0x00030000) #define EFI_IO_BUS_AGP (EFI_IO_BUS | 0x00040000) #define EFI_IO_BUS_PC_CARD (EFI_IO_BUS | 0x00050000) #define EFI_IO_BUS_LPC (EFI_IO_BUS | 0x00060000) #define EFI_IO_BUS_SCSI (EFI_IO_BUS | 0x00070000) #define EFI_IO_BUS_ATA_ATAPI (EFI_IO_BUS | 0x00080000) #define EFI_IO_BUS_FC (EFI_IO_BUS | 0x00090000) #define EFI_IO_BUS_IP_NETWORK (EFI_IO_BUS | 0x000A0000) #define EFI_IO_BUS_SMBUS (EFI_IO_BUS | 0x000B0000) #define EFI_IO_BUS_I2C (EFI_IO_BUS | 0x000C0000) ///@} /// /// IO Bus Class Progress Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_IOB_PC_INIT 0x00000000 #define EFI_IOB_PC_RESET 0x00000001 #define EFI_IOB_PC_DISABLE 0x00000002 #define EFI_IOB_PC_DETECT 0x00000003 #define EFI_IOB_PC_ENABLE 0x00000004 #define EFI_IOB_PC_RECONFIG 0x00000005 #define EFI_IOB_PC_HOTPLUG 0x00000006 ///@} // // IO Bus Class Unspecified Subclass Progress Code definitions. // /// /// IO Bus Class PCI Subclass Progress Code definitions. /// ///@{ #define EFI_IOB_PCI_BUS_ENUM (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_IOB_PCI_RES_ALLOC (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_IOB_PCI_HPC_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} // // IO Bus Class USB Subclass Progress Code definitions. // // // IO Bus Class IBA Subclass Progress Code definitions. // // // IO Bus Class AGP Subclass Progress Code definitions. // // // IO Bus Class PC Card Subclass Progress Code definitions. // // // IO Bus Class LPC Subclass Progress Code definitions. // // // IO Bus Class SCSI Subclass Progress Code definitions. // // // IO Bus Class ATA/ATAPI Subclass Progress Code definitions. // #define EFI_IOB_ATA_BUS_SMART_ENABLE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_IOB_ATA_BUS_SMART_DISABLE (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000003) // // IO Bus Class FC Subclass Progress Code definitions. // // // IO Bus Class IP Network Subclass Progress Code definitions. // // // IO Bus Class SMBUS Subclass Progress Code definitions. // // // IO Bus Class I2C Subclass Progress Code definitions. // /// /// IO Bus Class Error Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_IOB_EC_NON_SPECIFIC 0x00000000 #define EFI_IOB_EC_DISABLED 0x00000001 #define EFI_IOB_EC_NOT_SUPPORTED 0x00000002 #define EFI_IOB_EC_NOT_DETECTED 0x00000003 #define EFI_IOB_EC_NOT_CONFIGURED 0x00000004 #define EFI_IOB_EC_INTERFACE_ERROR 0x00000005 #define EFI_IOB_EC_CONTROLLER_ERROR 0x00000006 #define EFI_IOB_EC_READ_ERROR 0x00000007 #define EFI_IOB_EC_WRITE_ERROR 0x00000008 #define EFI_IOB_EC_RESOURCE_CONFLICT 0x00000009 ///@} // // IO Bus Class Unspecified Subclass Error Code definitions. // /// /// IO Bus Class PCI Subclass Error Code definitions. /// ///@{ #define EFI_IOB_PCI_EC_PERR (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_IOB_PCI_EC_SERR (EFI_SUBCLASS_SPECIFIC | 0x00000001) ///@} // // IO Bus Class USB Subclass Error Code definitions. // // // IO Bus Class IBA Subclass Error Code definitions. // // // IO Bus Class AGP Subclass Error Code definitions. // // // IO Bus Class PC Card Subclass Error Code definitions. // // // IO Bus Class LPC Subclass Error Code definitions. // // // IO Bus Class SCSI Subclass Error Code definitions. // // // IO Bus Class ATA/ATAPI Subclass Error Code definitions. // #define EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_IOB_ATA_BUS_SMART_DISABLED (EFI_SUBCLASS_SPECIFIC | 0x00000001) // // IO Bus Class FC Subclass Error Code definitions. // // // IO Bus Class IP Network Subclass Error Code definitions. // // // IO Bus Class SMBUS Subclass Error Code definitions. // // // IO Bus Class I2C Subclass Error Code definitions. // /// /// Software Subclass definitions. /// Values of 14-127 are reserved for future use by this specification. /// Values of 128-255 are reserved for OEM use. /// ///@{ #define EFI_SOFTWARE_UNSPECIFIED (EFI_SOFTWARE | 0x00000000) #define EFI_SOFTWARE_SEC (EFI_SOFTWARE | 0x00010000) #define EFI_SOFTWARE_PEI_CORE (EFI_SOFTWARE | 0x00020000) #define EFI_SOFTWARE_PEI_MODULE (EFI_SOFTWARE | 0x00030000) #define EFI_SOFTWARE_DXE_CORE (EFI_SOFTWARE | 0x00040000) #define EFI_SOFTWARE_DXE_BS_DRIVER (EFI_SOFTWARE | 0x00050000) #define EFI_SOFTWARE_DXE_RT_DRIVER (EFI_SOFTWARE | 0x00060000) #define EFI_SOFTWARE_SMM_DRIVER (EFI_SOFTWARE | 0x00070000) #define EFI_SOFTWARE_EFI_APPLICATION (EFI_SOFTWARE | 0x00080000) #define EFI_SOFTWARE_EFI_OS_LOADER (EFI_SOFTWARE | 0x00090000) #define EFI_SOFTWARE_RT (EFI_SOFTWARE | 0x000A0000) #define EFI_SOFTWARE_AL (EFI_SOFTWARE | 0x000B0000) #define EFI_SOFTWARE_EBC_EXCEPTION (EFI_SOFTWARE | 0x000C0000) #define EFI_SOFTWARE_IA32_EXCEPTION (EFI_SOFTWARE | 0x000D0000) #define EFI_SOFTWARE_IPF_EXCEPTION (EFI_SOFTWARE | 0x000E0000) #define EFI_SOFTWARE_PEI_SERVICE (EFI_SOFTWARE | 0x000F0000) #define EFI_SOFTWARE_EFI_BOOT_SERVICE (EFI_SOFTWARE | 0x00100000) #define EFI_SOFTWARE_EFI_RUNTIME_SERVICE (EFI_SOFTWARE | 0x00110000) #define EFI_SOFTWARE_EFI_DXE_SERVICE (EFI_SOFTWARE | 0x00120000) #define EFI_SOFTWARE_X64_EXCEPTION (EFI_SOFTWARE | 0x00130000) #define EFI_SOFTWARE_ARM_EXCEPTION (EFI_SOFTWARE | 0x00140000) ///@} /// /// Software Class Progress Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_SW_PC_INIT 0x00000000 #define EFI_SW_PC_LOAD 0x00000001 #define EFI_SW_PC_INIT_BEGIN 0x00000002 #define EFI_SW_PC_INIT_END 0x00000003 #define EFI_SW_PC_AUTHENTICATE_BEGIN 0x00000004 #define EFI_SW_PC_AUTHENTICATE_END 0x00000005 #define EFI_SW_PC_INPUT_WAIT 0x00000006 #define EFI_SW_PC_USER_SETUP 0x00000007 ///@} // // Software Class Unspecified Subclass Progress Code definitions. // /// /// Software Class SEC Subclass Progress Code definitions. /// ///@{ #define EFI_SW_SEC_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_SEC_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001) ///@} /// /// Software Class PEI Core Subclass Progress Code definitions. /// ///@{ #define EFI_SW_PEI_CORE_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_PEI_CORE_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} /// /// Software Class PEI Module Subclass Progress Code definitions. /// ///@{ #define EFI_SW_PEI_PC_RECOVERY_BEGIN (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PEI_PC_CAPSULE_LOAD (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_PEI_PC_CAPSULE_START (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_PEI_PC_RECOVERY_USER (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_PEI_PC_RECOVERY_AUTO (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_PEI_PC_S3_BOOT_SCRIPT (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_PEI_PC_OS_WAKE (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_PEI_PC_S3_STARTED (EFI_SUBCLASS_SPECIFIC | 0x00000007) ///@} /// /// Software Class DXE Core Subclass Progress Code definitions. /// ///@{ #define EFI_SW_DXE_CORE_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_DXE_CORE_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_DXE_CORE_PC_START_DRIVER (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_DXE_CORE_PC_ARCH_READY (EFI_SUBCLASS_SPECIFIC | 0x00000004) ///@} /// /// Software Class DXE BS Driver Subclass Progress Code definitions. /// ///@{ #define EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_DXE_BS_PC_VARIABLE_SERVICES_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_DXE_BS_PC_VARIABLE_RECLAIM (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_DXE_BS_PC_ATTEMPT_BOOT_ORDER_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_DXE_BS_PC_CONFIG_RESET (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_DXE_BS_PC_CSM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000009) ///@} // // Software Class SMM Driver Subclass Progress Code definitions. // // // Software Class EFI Application Subclass Progress Code definitions. // // // Software Class EFI OS Loader Subclass Progress Code definitions. // /// /// Software Class EFI RT Subclass Progress Code definitions. /// ///@{ #define EFI_SW_RT_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_RT_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_RT_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} // // Software Class X64 Exception Subclass Progress Code definitions. // // // Software Class ARM Exception Subclass Progress Code definitions. // // // Software Class EBC Exception Subclass Progress Code definitions. // // // Software Class IA32 Exception Subclass Progress Code definitions. // // // Software Class X64 Exception Subclass Progress Code definitions. // // // Software Class IPF Exception Subclass Progress Code definitions. // /// /// Software Class PEI Services Subclass Progress Code definitions. /// ///@{ #define EFI_SW_PS_PC_INSTALL_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PS_PC_REINSTALL_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_PS_PC_LOCATE_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_PS_PC_NOTIFY_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_PS_PC_GET_BOOT_MODE (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_PS_PC_SET_BOOT_MODE (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_PS_PC_GET_HOB_LIST (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_PS_PC_CREATE_HOB (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_PS_PC_FFS_FIND_NEXT_VOLUME (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_PS_PC_FFS_FIND_NEXT_FILE (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_SW_PS_PC_FFS_FIND_SECTION_DATA (EFI_SUBCLASS_SPECIFIC | 0x0000000A) #define EFI_SW_PS_PC_INSTALL_PEI_MEMORY (EFI_SUBCLASS_SPECIFIC | 0x0000000B) #define EFI_SW_PS_PC_ALLOCATE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x0000000C) #define EFI_SW_PS_PC_ALLOCATE_POOL (EFI_SUBCLASS_SPECIFIC | 0x0000000D) #define EFI_SW_PS_PC_COPY_MEM (EFI_SUBCLASS_SPECIFIC | 0x0000000E) #define EFI_SW_PS_PC_SET_MEM (EFI_SUBCLASS_SPECIFIC | 0x0000000F) #define EFI_SW_PS_PC_RESET_SYSTEM (EFI_SUBCLASS_SPECIFIC | 0x00000010) #define EFI_SW_PS_PC_FFS_FIND_FILE_BY_NAME (EFI_SUBCLASS_SPECIFIC | 0x00000013) #define EFI_SW_PS_PC_FFS_GET_FILE_INFO (EFI_SUBCLASS_SPECIFIC | 0x00000014) #define EFI_SW_PS_PC_FFS_GET_VOLUME_INFO (EFI_SUBCLASS_SPECIFIC | 0x00000015) #define EFI_SW_PS_PC_FFS_REGISTER_FOR_SHADOW (EFI_SUBCLASS_SPECIFIC | 0x00000016) ///@} /// /// Software Class EFI Boot Services Subclass Progress Code definitions. /// ///@{ #define EFI_SW_BS_PC_RAISE_TPL (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_BS_PC_RESTORE_TPL (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_BS_PC_ALLOCATE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_BS_PC_FREE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_BS_PC_GET_MEMORY_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_BS_PC_ALLOCATE_POOL (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_BS_PC_FREE_POOL (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_BS_PC_CREATE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_BS_PC_SET_TIMER (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_BS_PC_WAIT_FOR_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_SW_BS_PC_SIGNAL_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000A) #define EFI_SW_BS_PC_CLOSE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000B) #define EFI_SW_BS_PC_CHECK_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000C) #define EFI_SW_BS_PC_INSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000D) #define EFI_SW_BS_PC_REINSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000E) #define EFI_SW_BS_PC_UNINSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000F) #define EFI_SW_BS_PC_HANDLE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000010) #define EFI_SW_BS_PC_PC_HANDLE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000011) #define EFI_SW_BS_PC_REGISTER_PROTOCOL_NOTIFY (EFI_SUBCLASS_SPECIFIC | 0x00000012) #define EFI_SW_BS_PC_LOCATE_HANDLE (EFI_SUBCLASS_SPECIFIC | 0x00000013) #define EFI_SW_BS_PC_INSTALL_CONFIGURATION_TABLE (EFI_SUBCLASS_SPECIFIC | 0x00000014) #define EFI_SW_BS_PC_LOAD_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000015) #define EFI_SW_BS_PC_START_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000016) #define EFI_SW_BS_PC_EXIT (EFI_SUBCLASS_SPECIFIC | 0x00000017) #define EFI_SW_BS_PC_UNLOAD_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000018) #define EFI_SW_BS_PC_EXIT_BOOT_SERVICES (EFI_SUBCLASS_SPECIFIC | 0x00000019) #define EFI_SW_BS_PC_GET_NEXT_MONOTONIC_COUNT (EFI_SUBCLASS_SPECIFIC | 0x0000001A) #define EFI_SW_BS_PC_STALL (EFI_SUBCLASS_SPECIFIC | 0x0000001B) #define EFI_SW_BS_PC_SET_WATCHDOG_TIMER (EFI_SUBCLASS_SPECIFIC | 0x0000001C) #define EFI_SW_BS_PC_CONNECT_CONTROLLER (EFI_SUBCLASS_SPECIFIC | 0x0000001D) #define EFI_SW_BS_PC_DISCONNECT_CONTROLLER (EFI_SUBCLASS_SPECIFIC | 0x0000001E) #define EFI_SW_BS_PC_OPEN_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x0000001F) #define EFI_SW_BS_PC_CLOSE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000020) #define EFI_SW_BS_PC_OPEN_PROTOCOL_INFORMATION (EFI_SUBCLASS_SPECIFIC | 0x00000021) #define EFI_SW_BS_PC_PROTOCOLS_PER_HANDLE (EFI_SUBCLASS_SPECIFIC | 0x00000022) #define EFI_SW_BS_PC_LOCATE_HANDLE_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000023) #define EFI_SW_BS_PC_LOCATE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000024) #define EFI_SW_BS_PC_INSTALL_MULTIPLE_INTERFACES (EFI_SUBCLASS_SPECIFIC | 0x00000025) #define EFI_SW_BS_PC_UNINSTALL_MULTIPLE_INTERFACES (EFI_SUBCLASS_SPECIFIC | 0x00000026) #define EFI_SW_BS_PC_CALCULATE_CRC_32 (EFI_SUBCLASS_SPECIFIC | 0x00000027) #define EFI_SW_BS_PC_COPY_MEM (EFI_SUBCLASS_SPECIFIC | 0x00000028) #define EFI_SW_BS_PC_SET_MEM (EFI_SUBCLASS_SPECIFIC | 0x00000029) #define EFI_SW_BS_PC_CREATE_EVENT_EX (EFI_SUBCLASS_SPECIFIC | 0x0000002A) ///@} /// /// Software Class EFI Runtime Services Subclass Progress Code definitions. /// ///@{ #define EFI_SW_RS_PC_GET_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_RS_PC_SET_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_RS_PC_GET_WAKEUP_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_RS_PC_SET_WAKEUP_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_RS_PC_CONVERT_POINTER (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_RS_PC_GET_VARIABLE (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_RS_PC_GET_NEXT_VARIABLE_NAME (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_RS_PC_SET_VARIABLE (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_RS_PC_GET_NEXT_HIGH_MONOTONIC_COUNT (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_SW_RS_PC_RESET_SYSTEM (EFI_SUBCLASS_SPECIFIC | 0x0000000A) #define EFI_SW_RS_PC_UPDATE_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x0000000B) #define EFI_SW_RS_PC_QUERY_CAPSULE_CAPABILITIES (EFI_SUBCLASS_SPECIFIC | 0x0000000C) #define EFI_SW_RS_PC_QUERY_VARIABLE_INFO (EFI_SUBCLASS_SPECIFIC | 0x0000000D) ///@} /// /// Software Class EFI DXE Services Subclass Progress Code definitions /// ///@{ #define EFI_SW_DS_PC_ADD_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_DS_PC_ALLOCATE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_DS_PC_FREE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_DS_PC_REMOVE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_DS_PC_GET_MEMORY_SPACE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_DS_PC_SET_MEMORY_SPACE_ATTRIBUTES (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_DS_PC_GET_MEMORY_SPACE_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_DS_PC_ADD_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_DS_PC_ALLOCATE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_DS_PC_FREE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000009) #define EFI_SW_DS_PC_REMOVE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x0000000A) #define EFI_SW_DS_PC_GET_IO_SPACE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x0000000B) #define EFI_SW_DS_PC_GET_IO_SPACE_MAP (EFI_SUBCLASS_SPECIFIC | 0x0000000C) #define EFI_SW_DS_PC_DISPATCH (EFI_SUBCLASS_SPECIFIC | 0x0000000D) #define EFI_SW_DS_PC_SCHEDULE (EFI_SUBCLASS_SPECIFIC | 0x0000000E) #define EFI_SW_DS_PC_TRUST (EFI_SUBCLASS_SPECIFIC | 0x0000000F) #define EFI_SW_DS_PC_PROCESS_FIRMWARE_VOLUME (EFI_SUBCLASS_SPECIFIC | 0x00000010) ///@} /// /// Software Class Error Code definitions. /// These are shared by all subclasses. /// ///@{ #define EFI_SW_EC_NON_SPECIFIC 0x00000000 #define EFI_SW_EC_LOAD_ERROR 0x00000001 #define EFI_SW_EC_INVALID_PARAMETER 0x00000002 #define EFI_SW_EC_UNSUPPORTED 0x00000003 #define EFI_SW_EC_INVALID_BUFFER 0x00000004 #define EFI_SW_EC_OUT_OF_RESOURCES 0x00000005 #define EFI_SW_EC_ABORTED 0x00000006 #define EFI_SW_EC_ILLEGAL_SOFTWARE_STATE 0x00000007 #define EFI_SW_EC_ILLEGAL_HARDWARE_STATE 0x00000008 #define EFI_SW_EC_START_ERROR 0x00000009 #define EFI_SW_EC_BAD_DATE_TIME 0x0000000A #define EFI_SW_EC_CFG_INVALID 0x0000000B #define EFI_SW_EC_CFG_CLR_REQUEST 0x0000000C #define EFI_SW_EC_CFG_DEFAULT 0x0000000D #define EFI_SW_EC_PWD_INVALID 0x0000000E #define EFI_SW_EC_PWD_CLR_REQUEST 0x0000000F #define EFI_SW_EC_PWD_CLEARED 0x00000010 #define EFI_SW_EC_EVENT_LOG_FULL 0x00000011 #define EFI_SW_EC_WRITE_PROTECTED 0x00000012 #define EFI_SW_EC_FV_CORRUPTED 0x00000013 ///@} // // Software Class Unspecified Subclass Error Code definitions. // // // Software Class SEC Subclass Error Code definitions. // /// /// Software Class PEI Core Subclass Error Code definitions. /// ///@{ #define EFI_SW_PEI_CORE_EC_DXE_CORRUPT (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED (EFI_SUBCLASS_SPECIFIC | 0x00000002) ///@} /// /// Software Class PEI Module Subclass Error Code definitions. /// ///@{ #define EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_PEI_EC_S3_OS_WAKE_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_PEI_EC_S3_RESUME_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000006) #define EFI_SW_PEI_EC_RECOVERY_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000007) #define EFI_SW_PEI_EC_S3_RESUME_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000008) #define EFI_SW_PEI_EC_INVALID_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x00000009) ///@} /// /// Software Class DXE Foundation Subclass Error Code definitions. /// ///@{ #define EFI_SW_DXE_CORE_EC_NO_ARCH (EFI_SUBCLASS_SPECIFIC | 0x00000000) ///@} /// /// Software Class DXE Boot Service Driver Subclass Error Code definitions. /// ///@{ #define EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_DXE_BS_EC_INVALID_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000004) ///@} // // Software Class DXE Runtime Service Driver Subclass Error Code definitions. // // // Software Class SMM Driver Subclass Error Code definitions. // // // Software Class EFI Application Subclass Error Code definitions. // // // Software Class EFI OS Loader Subclass Error Code definitions. // // // Software Class EFI RT Subclass Error Code definitions. // // // Software Class EFI AL Subclass Error Code definitions. // /// /// Software Class EBC Exception Subclass Error Code definitions. /// These exceptions are derived from the debug protocol definitions in the EFI /// specification. /// ///@{ #define EFI_SW_EC_EBC_UNDEFINED 0x00000000 #define EFI_SW_EC_EBC_DIVIDE_ERROR EXCEPT_EBC_DIVIDE_ERROR #define EFI_SW_EC_EBC_DEBUG EXCEPT_EBC_DEBUG #define EFI_SW_EC_EBC_BREAKPOINT EXCEPT_EBC_BREAKPOINT #define EFI_SW_EC_EBC_OVERFLOW EXCEPT_EBC_OVERFLOW #define EFI_SW_EC_EBC_INVALID_OPCODE EXCEPT_EBC_INVALID_OPCODE #define EFI_SW_EC_EBC_STACK_FAULT EXCEPT_EBC_STACK_FAULT #define EFI_SW_EC_EBC_ALIGNMENT_CHECK EXCEPT_EBC_ALIGNMENT_CHECK #define EFI_SW_EC_EBC_INSTRUCTION_ENCODING EXCEPT_EBC_INSTRUCTION_ENCODING #define EFI_SW_EC_EBC_BAD_BREAK EXCEPT_EBC_BAD_BREAK #define EFI_SW_EC_EBC_STEP EXCEPT_EBC_STEP ///@} /// /// Software Class IA32 Exception Subclass Error Code definitions. /// These exceptions are derived from the debug protocol definitions in the EFI /// specification. /// ///@{ #define EFI_SW_EC_IA32_DIVIDE_ERROR EXCEPT_IA32_DIVIDE_ERROR #define EFI_SW_EC_IA32_DEBUG EXCEPT_IA32_DEBUG #define EFI_SW_EC_IA32_NMI EXCEPT_IA32_NMI #define EFI_SW_EC_IA32_BREAKPOINT EXCEPT_IA32_BREAKPOINT #define EFI_SW_EC_IA32_OVERFLOW EXCEPT_IA32_OVERFLOW #define EFI_SW_EC_IA32_BOUND EXCEPT_IA32_BOUND #define EFI_SW_EC_IA32_INVALID_OPCODE EXCEPT_IA32_INVALID_OPCODE #define EFI_SW_EC_IA32_DOUBLE_FAULT EXCEPT_IA32_DOUBLE_FAULT #define EFI_SW_EC_IA32_INVALID_TSS EXCEPT_IA32_INVALID_TSS #define EFI_SW_EC_IA32_SEG_NOT_PRESENT EXCEPT_IA32_SEG_NOT_PRESENT #define EFI_SW_EC_IA32_STACK_FAULT EXCEPT_IA32_STACK_FAULT #define EFI_SW_EC_IA32_GP_FAULT EXCEPT_IA32_GP_FAULT #define EFI_SW_EC_IA32_PAGE_FAULT EXCEPT_IA32_PAGE_FAULT #define EFI_SW_EC_IA32_FP_ERROR EXCEPT_IA32_FP_ERROR #define EFI_SW_EC_IA32_ALIGNMENT_CHECK EXCEPT_IA32_ALIGNMENT_CHECK #define EFI_SW_EC_IA32_MACHINE_CHECK EXCEPT_IA32_MACHINE_CHECK #define EFI_SW_EC_IA32_SIMD EXCEPT_IA32_SIMD ///@} /// /// Software Class IPF Exception Subclass Error Code definitions. /// These exceptions are derived from the debug protocol definitions in the EFI /// specification. /// ///@{ #define EFI_SW_EC_IPF_ALT_DTLB EXCEPT_IPF_ALT_DTLB #define EFI_SW_EC_IPF_DNESTED_TLB EXCEPT_IPF_DNESTED_TLB #define EFI_SW_EC_IPF_BREAKPOINT EXCEPT_IPF_BREAKPOINT #define EFI_SW_EC_IPF_EXTERNAL_INTERRUPT EXCEPT_IPF_EXTERNAL_INTERRUPT #define EFI_SW_EC_IPF_GEN_EXCEPT EXCEPT_IPF_GEN_EXCEPT #define EFI_SW_EC_IPF_NAT_CONSUMPTION EXCEPT_IPF_NAT_CONSUMPTION #define EFI_SW_EC_IPF_DEBUG_EXCEPT EXCEPT_IPF_DEBUG_EXCEPT #define EFI_SW_EC_IPF_UNALIGNED_ACCESS EXCEPT_IPF_UNALIGNED_ACCESS #define EFI_SW_EC_IPF_FP_FAULT EXCEPT_IPF_FP_FAULT #define EFI_SW_EC_IPF_FP_TRAP EXCEPT_IPF_FP_TRAP #define EFI_SW_EC_IPF_TAKEN_BRANCH EXCEPT_IPF_TAKEN_BRANCH #define EFI_SW_EC_IPF_SINGLE_STEP EXCEPT_IPF_SINGLE_STEP ///@} /// /// Software Class PEI Service Subclass Error Code definitions. /// ///@{ #define EFI_SW_PS_EC_RESET_NOT_AVAILABLE (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE (EFI_SUBCLASS_SPECIFIC | 0x00000001) ///@} // // Software Class EFI Boot Service Subclass Error Code definitions. // // // Software Class EFI Runtime Service Subclass Error Code definitions. // /// /// Software Class EFI DXE Service Subclass Error Code definitions. /// ///@{ #define EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS (EFI_SUBCLASS_SPECIFIC | 0x00000005) #define EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000006) ///@} /// /// Software Class DXE RT Driver Subclass Progress Code definitions. /// ///@{ #define EFI_SW_DXE_RT_PC_S0 (EFI_SUBCLASS_SPECIFIC | 0x00000000) #define EFI_SW_DXE_RT_PC_S1 (EFI_SUBCLASS_SPECIFIC | 0x00000001) #define EFI_SW_DXE_RT_PC_S2 (EFI_SUBCLASS_SPECIFIC | 0x00000002) #define EFI_SW_DXE_RT_PC_S3 (EFI_SUBCLASS_SPECIFIC | 0x00000003) #define EFI_SW_DXE_RT_PC_S4 (EFI_SUBCLASS_SPECIFIC | 0x00000004) #define EFI_SW_DXE_RT_PC_S5 (EFI_SUBCLASS_SPECIFIC | 0x00000005) ///@} /// /// Software Class X64 Exception Subclass Error Code definitions. /// These exceptions are derived from the debug protocol /// definitions in the EFI specification. /// ///@{ #define EFI_SW_EC_X64_DIVIDE_ERROR EXCEPT_X64_DIVIDE_ERROR #define EFI_SW_EC_X64_DEBUG EXCEPT_X64_DEBUG #define EFI_SW_EC_X64_NMI EXCEPT_X64_NMI #define EFI_SW_EC_X64_BREAKPOINT EXCEPT_X64_BREAKPOINT #define EFI_SW_EC_X64_OVERFLOW EXCEPT_X64_OVERFLOW #define EFI_SW_EC_X64_BOUND EXCEPT_X64_BOUND #define EFI_SW_EC_X64_INVALID_OPCODE EXCEPT_X64_INVALID_OPCODE #define EFI_SW_EC_X64_DOUBLE_FAULT EXCEPT_X64_DOUBLE_FAULT #define EFI_SW_EC_X64_INVALID_TSS EXCEPT_X64_INVALID_TSS #define EFI_SW_EC_X64_SEG_NOT_PRESENT EXCEPT_X64_SEG_NOT_PRESENT #define EFI_SW_EC_X64_STACK_FAULT EXCEPT_X64_STACK_FAULT #define EFI_SW_EC_X64_GP_FAULT EXCEPT_X64_GP_FAULT #define EFI_SW_EC_X64_PAGE_FAULT EXCEPT_X64_PAGE_FAULT #define EFI_SW_EC_X64_FP_ERROR EXCEPT_X64_FP_ERROR #define EFI_SW_EC_X64_ALIGNMENT_CHECK EXCEPT_X64_ALIGNMENT_CHECK #define EFI_SW_EC_X64_MACHINE_CHECK EXCEPT_X64_MACHINE_CHECK #define EFI_SW_EC_X64_SIMD EXCEPT_X64_SIMD ///@} /// /// Software Class ARM Exception Subclass Error Code definitions. /// These exceptions are derived from the debug protocol /// definitions in the EFI specification. /// ///@{ #define EFI_SW_EC_ARM_RESET EXCEPT_ARM_RESET #define EFI_SW_EC_ARM_UNDEFINED_INSTRUCTION EXCEPT_ARM_UNDEFINED_INSTRUCTION #define EFI_SW_EC_ARM_SOFTWARE_INTERRUPT EXCEPT_ARM_SOFTWARE_INTERRUPT #define EFI_SW_EC_ARM_PREFETCH_ABORT EXCEPT_ARM_PREFETCH_ABORT #define EFI_SW_EC_ARM_DATA_ABORT EXCEPT_ARM_DATA_ABORT #define EFI_SW_EC_ARM_RESERVED EXCEPT_ARM_RESERVED #define EFI_SW_EC_ARM_IRQ EXCEPT_ARM_IRQ #define EFI_SW_EC_ARM_FIQ EXCEPT_ARM_FIQ ///@} #endif /** @file The file provides services that allow information about an absolute pointer device to be retrieved. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.3. **/ #ifndef __ABSOLUTE_POINTER_H__ #define __ABSOLUTE_POINTER_H__ #define EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } } typedef struct _EFI_ABSOLUTE_POINTER_PROTOCOL EFI_ABSOLUTE_POINTER_PROTOCOL; // ******************************************************* // EFI_ABSOLUTE_POINTER_MODE // ******************************************************* /** The following data values in the EFI_ABSOLUTE_POINTER_MODE interface are read-only and are changed by using the appropriate interface functions. **/ typedef struct { UINT64 AbsoluteMinX; ///< The Absolute Minimum of the device on the x-axis UINT64 AbsoluteMinY; ///< The Absolute Minimum of the device on the y axis. UINT64 AbsoluteMinZ; ///< The Absolute Minimum of the device on the z-axis UINT64 AbsoluteMaxX; ///< The Absolute Maximum of the device on the x-axis. If 0, and the ///< AbsoluteMinX is 0, then the pointer device does not support a xaxis UINT64 AbsoluteMaxY; ///< The Absolute Maximum of the device on the y -axis. If 0, and the ///< AbsoluteMinX is 0, then the pointer device does not support a yaxis. UINT64 AbsoluteMaxZ; ///< The Absolute Maximum of the device on the z-axis. If 0 , and the ///< AbsoluteMinX is 0, then the pointer device does not support a zaxis UINT32 Attributes; ///< The following bits are set as needed (or'd together) to indicate the ///< capabilities of the device supported. The remaining bits are undefined ///< and should be 0 } EFI_ABSOLUTE_POINTER_MODE; /// /// If set, indicates this device supports an alternate button input. /// #define EFI_ABSP_SupportsAltActive 0x00000001 /// /// If set, indicates this device returns pressure data in parameter CurrentZ. /// #define EFI_ABSP_SupportsPressureAsZ 0x00000002 /** This function resets the pointer device hardware. As part of initialization process, the firmware/device will make a quick but reasonable attempt to verify that the device is functioning. If the ExtendedVerification flag is TRUE the firmware may take an extended amount of time to verify the device is operating on reset. Otherwise the reset operation is to occur as quickly as possible. The hardware verification process is not defined by this specification and is left up to the platform firmware or driver to implement. @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance. @param ExtendedVerification Indicates that the driver may perform a more exhaustive verification operation of the device during reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_ABSOLUTE_POINTER_RESET)( IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /// /// This bit is set if the touch sensor is active. /// #define EFI_ABSP_TouchActive 0x00000001 /// /// This bit is set if the alt sensor, such as pen-side button, is active /// #define EFI_ABS_AltActive 0x00000002 /** Definition of EFI_ABSOLUTE_POINTER_STATE. **/ typedef struct { /// /// The unsigned position of the activation on the x axis. If the AboluteMinX /// and the AboluteMaxX fields of the EFI_ABSOLUTE_POINTER_MODE structure are /// both 0, then this pointer device does not support an x-axis, and this field /// must be ignored. /// UINT64 CurrentX; /// /// The unsigned position of the activation on the y axis. If the AboluteMinY /// and the AboluteMaxY fields of the EFI_ABSOLUTE_POINTER_MODE structure are /// both 0, then this pointer device does not support an y-axis, and this field /// must be ignored. /// UINT64 CurrentY; /// /// The unsigned position of the activation on the z axis, or the pressure /// measurement. If the AboluteMinZ and the AboluteMaxZ fields of the /// EFI_ABSOLUTE_POINTER_MODE structure are both 0, then this pointer device /// does not support an z-axis, and this field must be ignored. /// UINT64 CurrentZ; /// /// Bits are set to 1 in this structure item to indicate that device buttons are /// active. /// UINT32 ActiveButtons; } EFI_ABSOLUTE_POINTER_STATE; /** The GetState() function retrieves the current state of a pointer device. This includes information on the active state associated with the pointer device and the current position of the axes associated with the pointer device. If the state of the pointer device has not changed since the last call to GetState(), then EFI_NOT_READY is returned. If the state of the pointer device has changed since the last call to GetState(), then the state information is placed in State, and EFI_SUCCESS is returned. If a device error occurs while attempting to retrieve the state information, then EFI_DEVICE_ERROR is returned. @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance. @param State A pointer to the state information on the pointer device. @retval EFI_SUCCESS The state of the pointer device was returned in State. @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to GetState(). @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's current state. **/ typedef EFI_STATUS (EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE)( IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, OUT EFI_ABSOLUTE_POINTER_STATE *State ); /// /// The EFI_ABSOLUTE_POINTER_PROTOCOL provides a set of services /// for a pointer device that can be used as an input device from an /// application written to this specification. The services include /// the ability to: reset the pointer device, retrieve the state of /// the pointer device, and retrieve the capabilities of the pointer /// device. The service also provides certain data items describing the device. /// struct _EFI_ABSOLUTE_POINTER_PROTOCOL { EFI_ABSOLUTE_POINTER_RESET Reset; EFI_ABSOLUTE_POINTER_GET_STATE GetState; /// /// Event to use with WaitForEvent() to wait for input from the pointer device. /// EFI_EVENT WaitForInput; /// /// Pointer to EFI_ABSOLUTE_POINTER_MODE data. /// EFI_ABSOLUTE_POINTER_MODE *Mode; }; extern EFI_GUID gEfiAbsolutePointerProtocolGuid; #endif /** @file EFI Adapter Information Protocol definition. The EFI Adapter Information Protocol is used to dynamically and quickly discover or set device information for an adapter. Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.4 **/ #ifndef __EFI_ADAPTER_INFORMATION_PROTOCOL_H__ #define __EFI_ADAPTER_INFORMATION_PROTOCOL_H__ #define EFI_ADAPTER_INFORMATION_PROTOCOL_GUID \ { \ 0xE5DD1403, 0xD622, 0xC24E, {0x84, 0x88, 0xC7, 0x1B, 0x17, 0xF5, 0xE8, 0x02 } \ } #define EFI_ADAPTER_INFO_MEDIA_STATE_GUID \ { \ 0xD7C74207, 0xA831, 0x4A26, {0xB1, 0xF5, 0xD1, 0x93, 0x06, 0x5C, 0xE8, 0xB6 } \ } #define EFI_ADAPTER_INFO_NETWORK_BOOT_GUID \ { \ 0x1FBD2960, 0x4130, 0x41E5, {0x94, 0xAC, 0xD2, 0xCF, 0x03, 0x7F, 0xB3, 0x7C } \ } #define EFI_ADAPTER_INFO_SAN_MAC_ADDRESS_GUID \ { \ 0x114da5ef, 0x2cf1, 0x4e12, {0x9b, 0xbb, 0xc4, 0x70, 0xb5, 0x52, 0x5, 0xd9 } \ } #define EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT_GUID \ { \ 0x4bd56be3, 0x4975, 0x4d8a, {0xa0, 0xad, 0xc4, 0x91, 0x20, 0x4b, 0x5d, 0x4d} \ } #define EFI_ADAPTER_INFO_MEDIA_TYPE_GUID \ { \ 0x8484472f, 0x71ec, 0x411a, { 0xb3, 0x9c, 0x62, 0xcd, 0x94, 0xd9, 0x91, 0x6e } \ } typedef struct _EFI_ADAPTER_INFORMATION_PROTOCOL EFI_ADAPTER_INFORMATION_PROTOCOL; /// /// EFI_ADAPTER_INFO_MEDIA_STATE /// typedef struct { /// /// Returns the current media state status. MediaState can have any of the following values: /// EFI_SUCCESS: There is media attached to the network adapter. EFI_NOT_READY: This detects a bounced state. /// There was media attached to the network adapter, but it was removed and reattached. EFI_NO_MEDIA: There is /// not any media attached to the network. /// EFI_STATUS MediaState; } EFI_ADAPTER_INFO_MEDIA_STATE; /// /// EFI_ADAPTER_INFO_MEDIA_TYPE /// typedef struct { /// /// Indicates the current media type. MediaType can have any of the following values: /// 1: Ethernet Network Adapter /// 2: Ethernet Wireless Network Adapter /// 3~255: Reserved /// UINT8 MediaType; } EFI_ADAPTER_INFO_MEDIA_TYPE; /// /// EFI_ADAPTER_INFO_NETWORK_BOOT /// typedef struct { /// /// TRUE if the adapter supports booting from iSCSI IPv4 targets. /// BOOLEAN iScsiIpv4BootCapablity; /// /// TRUE if the adapter supports booting from iSCSI IPv6 targets. /// BOOLEAN iScsiIpv6BootCapablity; /// /// TRUE if the adapter supports booting from FCoE targets. /// BOOLEAN FCoeBootCapablity; /// /// TRUE if the adapter supports an offload engine (such as TCP /// Offload Engine (TOE)) for its iSCSI or FCoE boot operations. /// BOOLEAN OffloadCapability; /// /// TRUE if the adapter supports multipath I/O (MPIO) for its iSCSI /// boot operations. /// BOOLEAN iScsiMpioCapability; /// /// TRUE if the adapter is currently configured to boot from iSCSI /// IPv4 targets. /// BOOLEAN iScsiIpv4Boot; /// /// TRUE if the adapter is currently configured to boot from iSCSI /// IPv6 targets. /// BOOLEAN iScsiIpv6Boot; /// /// TRUE if the adapter is currently configured to boot from FCoE targets. /// BOOLEAN FCoeBoot; } EFI_ADAPTER_INFO_NETWORK_BOOT; /// /// EFI_ADAPTER_INFO_SAN_MAC_ADDRESS /// typedef struct { /// /// Returns the SAN MAC address for the adapter.For adapters that support today's 802.3 ethernet /// networking and Fibre-Channel Over Ethernet (FCOE), this conveys the FCOE SAN MAC address from the adapter. /// EFI_MAC_ADDRESS SanMacAddress; } EFI_ADAPTER_INFO_SAN_MAC_ADDRESS; /// /// EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT /// typedef struct { /// /// Returns capability of UNDI to support IPv6 traffic. /// BOOLEAN Ipv6Support; } EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT; /** Returns the current state information for the adapter. This function returns information of type InformationType from the adapter. If an adapter does not support the requested informational type, then EFI_UNSUPPORTED is returned. @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. @param[in] InformationType A pointer to an EFI_GUID that defines the contents of InformationBlock. @param[out] InforamtionBlock The service returns a pointer to the buffer with the InformationBlock structure which contains details about the data specific to InformationType. @param[out] InforamtionBlockSize The driver returns the size of the InformationBlock in bytes. @retval EFI_SUCCESS The InformationType information was retrieved. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER InformationBlock is NULL. @retval EFI_INVALID_PARAMETER InformationBlockSize is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_ADAPTER_INFO_GET_INFO)( IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, IN EFI_GUID *InformationType, OUT VOID **InformationBlock, OUT UINTN *InformationBlockSize ); /** Sets state information for an adapter. This function sends information of type InformationType for an adapter. If an adapter does not support the requested information type, then EFI_UNSUPPORTED is returned. @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. @param[in] InformationType A pointer to an EFI_GUID that defines the contents of InformationBlock. @param[in] InforamtionBlock A pointer to the InformationBlock structure which contains details about the data specific to InformationType. @param[in] InforamtionBlockSize The size of the InformationBlock in bytes. @retval EFI_SUCCESS The information was received and interpreted successfully. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER InformationBlock is NULL. @retval EFI_WRITE_PROTECTED The InformationType cannot be modified using EFI_ADAPTER_INFO_SET_INFO(). **/ typedef EFI_STATUS (EFIAPI *EFI_ADAPTER_INFO_SET_INFO)( IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, IN EFI_GUID *InformationType, IN VOID *InformationBlock, IN UINTN InformationBlockSize ); /** Get a list of supported information types for this instance of the protocol. This function returns a list of InformationType GUIDs that are supported on an adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL. The list is returned in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is returned in InfoTypesBufferCount. @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. @param[out] InfoTypesBuffer A pointer to the array of InformationType GUIDs that are supported by This. @param[out] InfoTypesBufferCount A pointer to the number of GUIDs present in InfoTypesBuffer. @retval EFI_SUCCESS The list of information type GUIDs that are supported on this adapter was returned in InfoTypesBuffer. The number of information type GUIDs was returned in InfoTypesBufferCount. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER InfoTypesBuffer is NULL. @retval EFI_INVALID_PARAMETER InfoTypesBufferCount is NULL. @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the results. **/ typedef EFI_STATUS (EFIAPI *EFI_ADAPTER_INFO_GET_SUPPORTED_TYPES)( IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, OUT EFI_GUID **InfoTypesBuffer, OUT UINTN *InfoTypesBufferCount ); /// /// EFI_ADAPTER_INFORMATION_PROTOCOL /// The protocol for adapter provides the following services. /// - Gets device state information from adapter. /// - Sets device information for adapter. /// - Gets a list of supported information types for this instance of the protocol. /// struct _EFI_ADAPTER_INFORMATION_PROTOCOL { EFI_ADAPTER_INFO_GET_INFO GetInformation; EFI_ADAPTER_INFO_SET_INFO SetInformation; EFI_ADAPTER_INFO_GET_SUPPORTED_TYPES GetSupportedTypes; }; extern EFI_GUID gEfiAdapterInformationProtocolGuid; extern EFI_GUID gEfiAdapterInfoMediaStateGuid; extern EFI_GUID gEfiAdapterInfoNetworkBootGuid; extern EFI_GUID gEfiAdapterInfoSanMacAddressGuid; extern EFI_GUID gEfiAdapterInfoUndiIpv6SupportGuid; #endif /** @file EFI ARP Protocol Definition The EFI ARP Service Binding Protocol is used to locate EFI ARP Protocol drivers to create and destroy child of the driver to communicate with other host using ARP protocol. The EFI ARP Protocol provides services to map IP network address to hardware address used by a data link protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.0. **/ #ifndef __EFI_ARP_PROTOCOL_H__ #define __EFI_ARP_PROTOCOL_H__ #define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3 } \ } #define EFI_ARP_PROTOCOL_GUID \ { \ 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c } \ } typedef struct _EFI_ARP_PROTOCOL EFI_ARP_PROTOCOL; typedef struct { /// /// Length in bytes of this entry. /// UINT32 Size; /// /// Set to TRUE if this entry is a "deny" entry. /// Set to FALSE if this entry is a "normal" entry. /// BOOLEAN DenyFlag; /// /// Set to TRUE if this entry will not time out. /// Set to FALSE if this entry will time out. /// BOOLEAN StaticFlag; /// /// 16-bit ARP hardware identifier number. /// UINT16 HwAddressType; /// /// 16-bit protocol type number. /// UINT16 SwAddressType; /// /// The length of the hardware address. /// UINT8 HwAddressLength; /// /// The length of the protocol address. /// UINT8 SwAddressLength; } EFI_ARP_FIND_DATA; typedef struct { /// /// 16-bit protocol type number in host byte order. /// UINT16 SwAddressType; /// /// The length in bytes of the station's protocol address to register. /// UINT8 SwAddressLength; /// /// The pointer to the first byte of the protocol address to register. For /// example, if SwAddressType is 0x0800 (IP), then /// StationAddress points to the first byte of this station's IP /// address stored in network byte order. /// VOID *StationAddress; /// /// The timeout value in 100-ns units that is associated with each /// new dynamic ARP cache entry. If it is set to zero, the value is /// implementation-specific. /// UINT32 EntryTimeOut; /// /// The number of retries before a MAC address is resolved. If it is /// set to zero, the value is implementation-specific. /// UINT32 RetryCount; /// /// The timeout value in 100-ns units that is used to wait for the ARP /// reply packet or the timeout value between two retries. Set to zero /// to use implementation-specific value. /// UINT32 RetryTimeOut; } EFI_ARP_CONFIG_DATA; /** This function is used to assign a station address to the ARP cache for this instance of the ARP driver. Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will respond to ARP requests that match this registered station address. A call to this function with the ConfigData field set to NULL will reset this ARP instance. Once a protocol type and station address have been assigned to this ARP instance, all the following ARP functions will use this information. Attempting to change the protocol type or station address to a configured ARP instance will result in errors. @param This The pointer to the EFI_ARP_PROTOCOL instance. @param ConfigData The pointer to the EFI_ARP_CONFIG_DATA structure. @retval EFI_SUCCESS The new station address was successfully registered. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: * This is NULL. * SwAddressLength is zero when ConfigData is not NULL. * StationAddress is NULL when ConfigData is not NULL. @retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or StationAddress is different from the one that is already registered. @retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_CONFIGURE)( IN EFI_ARP_PROTOCOL *This, IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL ); /** This function is used to insert entries into the ARP cache. ARP cache entries are typically inserted and updated by network protocol drivers as network traffic is processed. Most ARP cache entries will time out and be deleted if the network traffic stops. ARP cache entries that were inserted by the Add() function may be static (will not time out) or dynamic (will time out). Default ARP cache timeout values are not covered in most network protocol specifications (although RFC 1122 comes pretty close) and will only be discussed in general terms in this specification. The timeout values that are used in the EFI Sample Implementation should be used only as a guideline. Final product implementations of the EFI network stack should be tuned for their expected network environments. @param This Pointer to the EFI_ARP_PROTOCOL instance. @param DenyFlag Set to TRUE if this entry is a deny entry. Set to FALSE if this entry is a normal entry. @param TargetSwAddress Pointer to a protocol address to add (or deny). May be set to NULL if DenyFlag is TRUE. @param TargetHwAddress Pointer to a hardware address to add (or deny). May be set to NULL if DenyFlag is TRUE. @param TimeoutValue Time in 100-ns units that this entry will remain in the ARP cache. A value of zero means that the entry is permanent. A nonzero value will override the one given by Configure() if the entry to be added is a dynamic entry. @param Overwrite If TRUE, the matching cache entry will be overwritten with the supplied parameters. If FALSE, EFI_ACCESS_DENIED is returned if the corresponding cache entry already exists. @retval EFI_SUCCESS The entry has been added or updated. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: * This is NULL. * DenyFlag is FALSE and TargetHwAddress is NULL. * DenyFlag is FALSE and TargetSwAddress is NULL. * TargetHwAddress is NULL and TargetSwAddress is NULL. * Neither TargetSwAddress nor TargetHwAddress are NULL when DenyFlag is TRUE. @retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated. @retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite is not true. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_ADD)( IN EFI_ARP_PROTOCOL *This, IN BOOLEAN DenyFlag, IN VOID *TargetSwAddress OPTIONAL, IN VOID *TargetHwAddress OPTIONAL, IN UINT32 TimeoutValue, IN BOOLEAN Overwrite ); /** This function searches the ARP cache for matching entries and allocates a buffer into which those entries are copied. The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which are protocol address pairs and hardware address pairs. When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer is not NULL), the ARP cache timeout for the found entry is reset if Refresh is set to TRUE. If the found ARP cache entry is a permanent entry, it is not affected by Refresh. @param This The pointer to the EFI_ARP_PROTOCOL instance. @param BySwAddress Set to TRUE to look for matching software protocol addresses. Set to FALSE to look for matching hardware protocol addresses. @param AddressBuffer The pointer to the address buffer. Set to NULL to match all addresses. @param EntryLength The size of an entry in the entries buffer. @param EntryCount The number of ARP cache entries that are found by the specified criteria. @param Entries The pointer to the buffer that will receive the ARP cache entries. @param Refresh Set to TRUE to refresh the timeout value of the matching ARP cache entry. @retval EFI_SUCCESS The requested ARP cache entries were copied into the buffer. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Both EntryCount and EntryLength are NULL, when Refresh is FALSE. @retval EFI_NOT_FOUND No matching entries were found. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_FIND)( IN EFI_ARP_PROTOCOL *This, IN BOOLEAN BySwAddress, IN VOID *AddressBuffer OPTIONAL, OUT UINT32 *EntryLength OPTIONAL, OUT UINT32 *EntryCount OPTIONAL, OUT EFI_ARP_FIND_DATA **Entries OPTIONAL, IN BOOLEAN Refresh ); /** This function removes specified ARP cache entries. @param This The pointer to the EFI_ARP_PROTOCOL instance. @param BySwAddress Set to TRUE to delete matching protocol addresses. Set to FALSE to delete matching hardware addresses. @param AddressBuffer The pointer to the address buffer that is used as a key to look for the cache entry. Set to NULL to delete all entries. @retval EFI_SUCCESS The entry was removed from the ARP cache. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_FOUND The specified deletion key was not found. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_DELETE)( IN EFI_ARP_PROTOCOL *This, IN BOOLEAN BySwAddress, IN VOID *AddressBuffer OPTIONAL ); /** This function delete all dynamic entries from the ARP cache that match the specified software protocol type. @param This The pointer to the EFI_ARP_PROTOCOL instance. @retval EFI_SUCCESS The cache has been flushed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_FOUND There are no matching dynamic cache entries. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_FLUSH)( IN EFI_ARP_PROTOCOL *This ); /** This function tries to resolve the TargetSwAddress and optionally returns a TargetHwAddress if it already exists in the ARP cache. @param This The pointer to the EFI_ARP_PROTOCOL instance. @param TargetSwAddress The pointer to the protocol address to resolve. @param ResolvedEvent The pointer to the event that will be signaled when the address is resolved or some error occurs. @param TargetHwAddress The pointer to the buffer for the resolved hardware address in network byte order. @retval EFI_SUCCESS The data is copied from the ARP cache into the TargetHwAddress buffer. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. TargetHwAddress is NULL. @retval EFI_ACCESS_DENIED The requested address is not present in the normal ARP cache but is present in the deny address list. Outgoing traffic to that address is forbidden. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. @retval EFI_NOT_READY The request has been started and is not finished. **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_REQUEST)( IN EFI_ARP_PROTOCOL *This, IN VOID *TargetSwAddress OPTIONAL, IN EFI_EVENT ResolvedEvent OPTIONAL, OUT VOID *TargetHwAddress ); /** This function aborts the previous ARP request (identified by This, TargetSwAddress and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request(). If the request is in the internal ARP request queue, the request is aborted immediately and its ResolvedEvent is signaled. Only an asynchronous address request needs to be canceled. If TargeSwAddress and ResolveEvent are both NULL, all the pending asynchronous requests that have been issued by This instance will be cancelled and their corresponding events will be signaled. @param This The pointer to the EFI_ARP_PROTOCOL instance. @param TargetSwAddress The pointer to the protocol address in previous request session. @param ResolvedEvent Pointer to the event that is used as the notification event in previous request session. @retval EFI_SUCCESS The pending request session(s) is/are aborted and corresponding event(s) is/are signaled. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. TargetSwAddress is not NULL and ResolvedEvent is NULL. TargetSwAddress is NULL and ResolvedEvent is not NULL. @retval EFI_NOT_STARTED The ARP driver instance has not been configured. @retval EFI_NOT_FOUND The request is not issued by EFI_ARP_PROTOCOL.Request(). **/ typedef EFI_STATUS (EFIAPI *EFI_ARP_CANCEL)( IN EFI_ARP_PROTOCOL *This, IN VOID *TargetSwAddress OPTIONAL, IN EFI_EVENT ResolvedEvent OPTIONAL ); /// /// ARP is used to resolve local network protocol addresses into /// network hardware addresses. /// struct _EFI_ARP_PROTOCOL { EFI_ARP_CONFIGURE Configure; EFI_ARP_ADD Add; EFI_ARP_FIND Find; EFI_ARP_DELETE Delete; EFI_ARP_FLUSH Flush; EFI_ARP_REQUEST Request; EFI_ARP_CANCEL Cancel; }; extern EFI_GUID gEfiArpServiceBindingProtocolGuid; extern EFI_GUID gEfiArpProtocolGuid; #endif /** @file The EFI_ATA_PASS_THRU_PROTOCOL provides information about an ATA controller and the ability to send ATA Command Blocks to any ATA device attached to that ATA controller. The information includes the attributes of the ATA controller. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.3. **/ #ifndef __ATA_PASS_THROUGH_H__ #define __ATA_PASS_THROUGH_H__ #define EFI_ATA_PASS_THRU_PROTOCOL_GUID \ { \ 0x1d3de7f0, 0x807, 0x424f, {0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f } \ } typedef struct _EFI_ATA_PASS_THRU_PROTOCOL EFI_ATA_PASS_THRU_PROTOCOL; typedef struct { UINT32 Attributes; UINT32 IoAlign; } EFI_ATA_PASS_THRU_MODE; /// /// If this bit is set, then the EFI_ATA_PASS_THRU_PROTOCOL interface is for physical /// devices on the ATA controller. /// #define EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 /// /// If this bit is set, then the EFI_ATA_PASS_THRU_PROTOCOL interface is for logical /// devices on the ATA controller. /// #define EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 /// /// If this bit is set, then the EFI_ATA_PASS_THRU_PROTOCOL interface supports non blocking /// I/O. Every EFI_ATA_PASS_THRU_PROTOCOL must support blocking I/O. The support of non-blocking /// I/O is optional. /// #define EFI_ATA_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 typedef struct _EFI_ATA_COMMAND_BLOCK { UINT8 Reserved1[2]; UINT8 AtaCommand; UINT8 AtaFeatures; UINT8 AtaSectorNumber; UINT8 AtaCylinderLow; UINT8 AtaCylinderHigh; UINT8 AtaDeviceHead; UINT8 AtaSectorNumberExp; UINT8 AtaCylinderLowExp; UINT8 AtaCylinderHighExp; UINT8 AtaFeaturesExp; UINT8 AtaSectorCount; UINT8 AtaSectorCountExp; UINT8 Reserved2[6]; } EFI_ATA_COMMAND_BLOCK; typedef struct _EFI_ATA_STATUS_BLOCK { UINT8 Reserved1[2]; UINT8 AtaStatus; UINT8 AtaError; UINT8 AtaSectorNumber; UINT8 AtaCylinderLow; UINT8 AtaCylinderHigh; UINT8 AtaDeviceHead; UINT8 AtaSectorNumberExp; UINT8 AtaCylinderLowExp; UINT8 AtaCylinderHighExp; UINT8 Reserved2; UINT8 AtaSectorCount; UINT8 AtaSectorCountExp; UINT8 Reserved3[6]; } EFI_ATA_STATUS_BLOCK; typedef UINT8 EFI_ATA_PASS_THRU_CMD_PROTOCOL; #define EFI_ATA_PASS_THRU_PROTOCOL_ATA_HARDWARE_RESET 0x00 #define EFI_ATA_PASS_THRU_PROTOCOL_ATA_SOFTWARE_RESET 0x01 #define EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA 0x02 #define EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN 0x04 #define EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT 0x05 #define EFI_ATA_PASS_THRU_PROTOCOL_DMA 0x06 #define EFI_ATA_PASS_THRU_PROTOCOL_DMA_QUEUED 0x07 #define EFI_ATA_PASS_THRU_PROTOCOL_DEVICE_DIAGNOSTIC 0x08 #define EFI_ATA_PASS_THRU_PROTOCOL_DEVICE_RESET 0x09 #define EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN 0x0A #define EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT 0x0B #define EFI_ATA_PASS_THRU_PROTOCOL_FPDMA 0x0C #define EFI_ATA_PASS_THRU_PROTOCOL_RETURN_RESPONSE 0xFF typedef UINT8 EFI_ATA_PASS_THRU_LENGTH; #define EFI_ATA_PASS_THRU_LENGTH_BYTES 0x80 #define EFI_ATA_PASS_THRU_LENGTH_MASK 0x70 #define EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER 0x00 #define EFI_ATA_PASS_THRU_LENGTH_FEATURES 0x10 #define EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT 0x20 #define EFI_ATA_PASS_THRU_LENGTH_TPSIU 0x30 #define EFI_ATA_PASS_THRU_LENGTH_COUNT 0x0F typedef struct { /// /// A pointer to the sense data that was generated by the execution of the ATA /// command. It must be aligned to the boundary specified in the IoAlign field /// in the EFI_ATA_PASS_THRU_MODE structure. /// EFI_ATA_STATUS_BLOCK *Asb; /// /// A pointer to buffer that contains the Command Data Block to send to the ATA /// device specified by Port and PortMultiplierPort. /// EFI_ATA_COMMAND_BLOCK *Acb; /// /// The timeout, in 100 ns units, to use for the execution of this ATA command. /// A Timeout value of 0 means that this function will wait indefinitely for the /// ATA command to execute. If Timeout is greater than zero, then this function /// will return EFI_TIMEOUT if the time required to execute the ATA command is /// greater than Timeout. /// UINT64 Timeout; /// /// A pointer to the data buffer to transfer between the ATA controller and the /// ATA device for read and bidirectional commands. For all write and non data /// commands where InTransferLength is 0 this field is optional and may be NULL. /// If this field is not NULL, then it must be aligned on the boundary specified /// by the IoAlign field in the EFI_ATA_PASS_THRU_MODE structure. /// VOID *InDataBuffer; /// /// A pointer to the data buffer to transfer between the ATA controller and the /// ATA device for write or bidirectional commands. For all read and non data /// commands where OutTransferLength is 0 this field is optional and may be NULL. /// If this field is not NULL, then it must be aligned on the boundary specified /// by the IoAlign field in the EFI_ATA_PASS_THRU_MODE structure. /// VOID *OutDataBuffer; /// /// On input, the size, in bytes, of InDataBuffer. On output, the number of bytes /// transferred between the ATA controller and the ATA device. If InTransferLength /// is larger than the ATA controller can handle, no data will be transferred, /// InTransferLength will be updated to contain the number of bytes that the ATA /// controller is able to transfer, and EFI_BAD_BUFFER_SIZE will be returned. /// UINT32 InTransferLength; /// /// On Input, the size, in bytes of OutDataBuffer. On Output, the Number of bytes /// transferred between ATA Controller and the ATA device. If OutTransferLength is /// larger than the ATA controller can handle, no data will be transferred, /// OutTransferLength will be updated to contain the number of bytes that the ATA /// controller is able to transfer, and EFI_BAD_BUFFER_SIZE will be returned. /// UINT32 OutTransferLength; /// /// Specifies the protocol used when the ATA device executes the command. /// EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol; /// /// Specifies the way in which the ATA command length is encoded. /// EFI_ATA_PASS_THRU_LENGTH Length; } EFI_ATA_PASS_THRU_COMMAND_PACKET; /** Sends an ATA command to an ATA device that is attached to the ATA controller. This function supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required, and the non-blocking I/O functionality is optional. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] Port The port number of the ATA device to send the command. @param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command. If there is no port multiplier, then specify 0xFFFF. @param[in,out] Packet A pointer to the ATA command to send to the ATA device specified by Port and PortMultiplierPort. @param[in] Event If non-blocking I/O is not supported then Event is ignored, and blocking I/O is performed. If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O is supported, then non-blocking I/O is performed, and Event will be signaled when the ATA command completes. @retval EFI_SUCCESS The ATA command was sent by the host. For bi-directional commands, InTransferLength bytes were transferred from InDataBuffer. For write and bi-directional commands, OutTransferLength bytes were transferred by OutDataBuffer. @retval EFI_BAD_BUFFER_SIZE The ATA command was not executed. The number of bytes that could be transferred is returned in InTransferLength. For write and bi-directional commands, OutTransferLength bytes were transferred by OutDataBuffer. @retval EFI_NOT_READY The ATA command could not be sent because there are too many ATA commands already queued. The caller may retry again later. @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the ATA command. @retval EFI_INVALID_PARAMETER Port, PortMultiplierPort, or the contents of Acb are invalid. The ATA command was not sent, so no additional status information is available. **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_PASSTHRU)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ); /** Used to retrieve the list of legal port numbers for ATA devices on an ATA controller. These can either be the list of ports where ATA devices are actually present or the list of legal port numbers for the ATA controller. Regardless, the caller of this function must probe the port number returned to see if an ATA device is actually present at that location on the ATA controller. The GetNextPort() function retrieves the port number on an ATA controller. If on input Port is 0xFFFF, then the port number of the first port on the ATA controller is returned in Port and EFI_SUCCESS is returned. If Port is a port number that was returned on a previous call to GetNextPort(), then the port number of the next port on the ATA controller is returned in Port, and EFI_SUCCESS is returned. If Port is not 0xFFFF and Port was not returned on a previous call to GetNextPort(), then EFI_INVALID_PARAMETER is returned. If Port is the port number of the last port on the ATA controller, then EFI_NOT_FOUND is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in,out] Port On input, a pointer to the port number on the ATA controller. On output, a pointer to the next port number on the ATA controller. An input value of 0xFFFF retrieves the first port number on the ATA controller. @retval EFI_SUCCESS The next port number on the ATA controller was returned in Port. @retval EFI_NOT_FOUND There are no more ports on this ATA controller. @retval EFI_INVALID_PARAMETER Port is not 0xFFFF and Port was not returned on a previous call to GetNextPort(). **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_GET_NEXT_PORT)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN OUT UINT16 *Port ); /** Used to retrieve the list of legal port multiplier port numbers for ATA devices on a port of an ATA controller. These can either be the list of port multiplier ports where ATA devices are actually present on port or the list of legal port multiplier ports on that port. Regardless, the caller of this function must probe the port number and port multiplier port number returned to see if an ATA device is actually present. The GetNextDevice() function retrieves the port multiplier port number of an ATA device present on a port of an ATA controller. If PortMultiplierPort points to a port multiplier port number value that was returned on a previous call to GetNextDevice(), then the port multiplier port number of the next ATA device on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is returned. If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first ATA device on port of the ATA controller is returned in PortMultiplierPort and EFI_SUCCESS is returned. If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER is returned. If PortMultiplierPort is the port multiplier port number of the last ATA device on the port of the ATA controller, then EFI_NOT_FOUND is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] Port The port number present on the ATA controller. @param[in,out] PortMultiplierPort On input, a pointer to the port multiplier port number of an ATA device present on the ATA controller. If on input a PortMultiplierPort of 0xFFFF is specified, then the port multiplier port number of the first ATA device is returned. On output, a pointer to the port multiplier port number of the next ATA device present on an ATA controller. @retval EFI_SUCCESS The port multiplier port number of the next ATA device on the port of the ATA controller was returned in PortMultiplierPort. @retval EFI_NOT_FOUND There are no more ATA devices on this port of the ATA controller. @retval EFI_INVALID_PARAMETER PortMultiplierPort is not 0xFFFF, and PortMultiplierPort was not returned on a previous call to GetNextDevice(). **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_GET_NEXT_DEVICE)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN OUT UINT16 *PortMultiplierPort ); /** Used to allocate and build a device path node for an ATA device on an ATA controller. The BuildDevicePath() function allocates and builds a single device node for the ATA device specified by Port and PortMultiplierPort. If the ATA device specified by Port and PortMultiplierPort is not present on the ATA controller, then EFI_NOT_FOUND is returned. If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are initialized to describe the ATA device specified by Port and PortMultiplierPort, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] Port Port specifies the port number of the ATA device for which a device path node is to be allocated and built. @param[in] PortMultiplierPort The port multiplier port number of the ATA device for which a device path node is to be allocated and built. If there is no port multiplier, then specify 0xFFFF. @param[out] DevicePath A pointer to a single device path node that describes the ATA device specified by Port and PortMultiplierPort. This function is responsible for allocating the buffer DevicePath with the boot service AllocatePool(). It is the caller's responsibility to free DevicePath when the caller is finished with DevicePath. @retval EFI_SUCCESS The device path node that describes the ATA device specified by Port and PortMultiplierPort was allocated and returned in DevicePath. @retval EFI_NOT_FOUND The ATA device specified by Port and PortMultiplierPort does not exist on the ATA controller. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate DevicePath. **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_BUILD_DEVICE_PATH)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ); /** Used to translate a device path node to a port number and port multiplier port number. The GetDevice() function determines the port and port multiplier port number associated with the ATA device described by DevicePath. If DevicePath is a device path node type that the ATA Pass Thru driver supports, then the ATA Pass Thru driver will attempt to translate the contents DevicePath into a port number and port multiplier port number. If this translation is successful, then that port number and port multiplier port number are returned in Port and PortMultiplierPort, and EFI_SUCCESS is returned. If DevicePath, Port, or PortMultiplierPort are NULL, then EFI_INVALID_PARAMETER is returned. If DevicePath is not a device path node type that the ATA Pass Thru driver supports, then EFI_UNSUPPORTED is returned. If DevicePath is a device path node type that the ATA Pass Thru driver supports, but there is not a valid translation from DevicePath to a port number and port multiplier port number, then EFI_NOT_FOUND is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] DevicePath A pointer to the device path node that describes an ATA device on the ATA controller. @param[out] Port On return, points to the port number of an ATA device on the ATA controller. @param[out] PortMultiplierPort On return, points to the port multiplier port number of an ATA device on the ATA controller. @retval EFI_SUCCESS DevicePath was successfully translated to a port number and port multiplier port number, and they were returned in Port and PortMultiplierPort. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_INVALID_PARAMETER Port is NULL. @retval EFI_INVALID_PARAMETER PortMultiplierPort is NULL. @retval EFI_UNSUPPORTED This driver does not support the device path node type in DevicePath. @retval EFI_NOT_FOUND A valid translation from DevicePath to a port number and port multiplier port number does not exist. **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_GET_DEVICE)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT16 *Port, OUT UINT16 *PortMultiplierPort ); /** Resets a specific port on the ATA controller. This operation also resets all the ATA devices connected to the port. The ResetChannel() function resets an a specific port on an ATA controller. This operation resets all the ATA devices connected to that port. If this ATA controller does not support a reset port operation, then EFI_UNSUPPORTED is returned. If a device error occurs while executing that port reset operation, then EFI_DEVICE_ERROR is returned. If a timeout occurs during the execution of the port reset operation, then EFI_TIMEOUT is returned. If the port reset operation is completed, then EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] Port The port number on the ATA controller. @retval EFI_SUCCESS The ATA controller port was reset. @retval EFI_UNSUPPORTED The ATA controller does not support a port reset operation. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the ATA port. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the ATA port. **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_RESET_PORT)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port ); /** Resets an ATA device that is connected to an ATA controller. The ResetDevice() function resets the ATA device specified by Port and PortMultiplierPort. If this ATA controller does not support a device reset operation, then EFI_UNSUPPORTED is returned. If Port or PortMultiplierPort are not in a valid range for this ATA controller, then EFI_INVALID_PARAMETER is returned. If a device error occurs while executing that device reset operation, then EFI_DEVICE_ERROR is returned. If a timeout occurs during the execution of the device reset operation, then EFI_TIMEOUT is returned. If the device reset operation is completed, then EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance. @param[in] Port Port represents the port number of the ATA device to be reset. @param[in] PortMultiplierPort The port multiplier port number of the ATA device to reset. If there is no port multiplier, then specify 0xFFFF. @retval EFI_SUCCESS The ATA device specified by Port and PortMultiplierPort was reset. @retval EFI_UNSUPPORTED The ATA controller does not support a device reset operation. @retval EFI_INVALID_PARAMETER Port or PortMultiplierPort are invalid. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the ATA device specified by Port and PortMultiplierPort. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the ATA device specified by Port and PortMultiplierPort. **/ typedef EFI_STATUS (EFIAPI *EFI_ATA_PASS_THRU_RESET_DEVICE)( IN EFI_ATA_PASS_THRU_PROTOCOL *This, IN UINT16 Port, IN UINT16 PortMultiplierPort ); struct _EFI_ATA_PASS_THRU_PROTOCOL { EFI_ATA_PASS_THRU_MODE *Mode; EFI_ATA_PASS_THRU_PASSTHRU PassThru; EFI_ATA_PASS_THRU_GET_NEXT_PORT GetNextPort; EFI_ATA_PASS_THRU_GET_NEXT_DEVICE GetNextDevice; EFI_ATA_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; EFI_ATA_PASS_THRU_GET_DEVICE GetDevice; EFI_ATA_PASS_THRU_RESET_PORT ResetPort; EFI_ATA_PASS_THRU_RESET_DEVICE ResetDevice; }; extern EFI_GUID gEfiAtaPassThruProtocolGuid; #endif /** @file Boot Device Selection Architectural Protocol as defined in PI spec Volume 2 DXE When the DXE core is done it calls the BDS via this protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_BDS_H__ #define __ARCH_PROTOCOL_BDS_H__ /// /// Global ID for the BDS Architectural Protocol /// #define EFI_BDS_ARCH_PROTOCOL_GUID \ { 0x665E3FF6, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } /// /// Declare forward reference for the BDS Architectural Protocol /// typedef struct _EFI_BDS_ARCH_PROTOCOL EFI_BDS_ARCH_PROTOCOL; /** This function uses policy data from the platform to determine what operating system or system utility should be loaded and invoked. This function call also optionally make the use of user input to determine the operating system or system utility to be loaded and invoked. When the DXE Core has dispatched all the drivers on the dispatch queue, this function is called. This function will attempt to connect the boot devices required to load and invoke the selected operating system or system utility. During this process, additional firmware volumes may be discovered that may contain addition DXE drivers that can be dispatched by the DXE Core. If a boot device cannot be fully connected, this function calls the DXE Service Dispatch() to allow the DXE drivers from any newly discovered firmware volumes to be dispatched. Then the boot device connection can be attempted again. If the same boot device connection operation fails twice in a row, then that boot device has failed, and should be skipped. This function should never return. @param This The EFI_BDS_ARCH_PROTOCOL instance. @return None. **/ typedef VOID (EFIAPI *EFI_BDS_ENTRY)( IN EFI_BDS_ARCH_PROTOCOL *This ); /// /// The EFI_BDS_ARCH_PROTOCOL transfers control from DXE to an operating /// system or a system utility. If there are not enough drivers initialized /// when this protocol is used to access the required boot device(s), then /// this protocol should add drivers to the dispatch queue and return control /// back to the dispatcher. Once the required boot devices are available, then /// the boot device can be used to load and invoke an OS or a system utility. /// struct _EFI_BDS_ARCH_PROTOCOL { EFI_BDS_ENTRY Entry; }; extern EFI_GUID gEfiBdsArchProtocolGuid; #endif /** @file Block IO protocol as defined in the UEFI 2.0 specification. The Block IO protocol is used to abstract block devices like hard drives, DVD-ROMs and floppy drives. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __BLOCK_IO_H__ #define __BLOCK_IO_H__ #define EFI_BLOCK_IO_PROTOCOL_GUID \ { \ 0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } typedef struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL; /// /// Protocol GUID name defined in EFI1.1. /// #define BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL_GUID /// /// Protocol defined in EFI1.1. /// typedef EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO; /** Reset the Block Device. @param This Indicates a pointer to the calling context. @param ExtendedVerification Driver may perform diagnostics on reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_RESET)( IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Read BufferSize bytes from Lba into Buffer. @param This Indicates a pointer to the calling context. @param MediaId Id of the media, changes every time the media is replaced. @param Lba The starting Logical Block Address to read from @param BufferSize Size of Buffer, must be a multiple of device block size. @param Buffer A pointer to the destination buffer for the data. The caller is responsible for either having implicit or explicit ownership of the buffer. @retval EFI_SUCCESS The data was read correctly from the device. @retval EFI_DEVICE_ERROR The device reported an error while performing the read. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, or the buffer is not on proper alignment. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_READ)( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer ); /** Write BufferSize bytes from Lba into Buffer. @param This Indicates a pointer to the calling context. @param MediaId The media ID that the write request is for. @param Lba The starting logical block address to be written. The caller is responsible for writing to only legitimate locations. @param BufferSize Size of Buffer, must be a multiple of device block size. @param Buffer A pointer to the source buffer for the data. @retval EFI_SUCCESS The data was written correctly to the device. @retval EFI_WRITE_PROTECTED The device can not be written to. @retval EFI_DEVICE_ERROR The device reported an error while performing the write. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, or the buffer is not on proper alignment. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_WRITE)( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, IN VOID *Buffer ); /** Flush the Block Device. @param This Indicates a pointer to the calling context. @retval EFI_SUCCESS All outstanding data was written to the device @retval EFI_DEVICE_ERROR The device reported an error while writting back the data @retval EFI_NO_MEDIA There is no media in the device. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_FLUSH)( IN EFI_BLOCK_IO_PROTOCOL *This ); /** Block IO read only mode data and updated only via members of BlockIO **/ typedef struct { /// /// The curent media Id. If the media changes, this value is changed. /// UINT32 MediaId; /// /// TRUE if the media is removable; otherwise, FALSE. /// BOOLEAN RemovableMedia; /// /// TRUE if there is a media currently present in the device; /// othersise, FALSE. THis field shows the media present status /// as of the most recent ReadBlocks() or WriteBlocks() call. /// BOOLEAN MediaPresent; /// /// TRUE if LBA 0 is the first block of a partition; otherwise /// FALSE. For media with only one partition this would be TRUE. /// BOOLEAN LogicalPartition; /// /// TRUE if the media is marked read-only otherwise, FALSE. /// This field shows the read-only status as of the most recent WriteBlocks () call. /// BOOLEAN ReadOnly; /// /// TRUE if the WriteBlock () function caches write data. /// BOOLEAN WriteCaching; /// /// The intrinsic block size of the device. If the media changes, then /// this field is updated. /// UINT32 BlockSize; /// /// Supplies the alignment requirement for any buffer to read or write block(s). /// UINT32 IoAlign; /// /// The last logical block address on the device. /// If the media changes, then this field is updated. /// EFI_LBA LastBlock; /// /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned to /// a physical block boundary. /// EFI_LBA LowestAlignedLba; /// /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical blocks /// per physical block. /// UINT32 LogicalBlocksPerPhysicalBlock; /// /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to /// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer length /// granularity as a number of logical blocks. /// UINT32 OptimalTransferLengthGranularity; } EFI_BLOCK_IO_MEDIA; #define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000 #define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 #define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x0002001F /// /// Revision defined in EFI1.1. /// #define EFI_BLOCK_IO_INTERFACE_REVISION EFI_BLOCK_IO_PROTOCOL_REVISION /// /// This protocol provides control over block devices. /// struct _EFI_BLOCK_IO_PROTOCOL { /// /// The revision to which the block IO interface adheres. All future /// revisions must be backwards compatible. If a future version is not /// back wards compatible, it is not the same GUID. /// UINT64 Revision; /// /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device. /// EFI_BLOCK_IO_MEDIA *Media; EFI_BLOCK_RESET Reset; EFI_BLOCK_READ ReadBlocks; EFI_BLOCK_WRITE WriteBlocks; EFI_BLOCK_FLUSH FlushBlocks; }; extern EFI_GUID gEfiBlockIoProtocolGuid; #endif /** @file Block IO2 protocol as defined in the UEFI 2.3.1 specification. The Block IO2 protocol defines an extension to the Block IO protocol which enables the ability to read and write data at a block level in a non-blocking manner. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __BLOCK_IO2_H__ #define __BLOCK_IO2_H__ #include #define EFI_BLOCK_IO2_PROTOCOL_GUID \ { \ 0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1} \ } typedef struct _EFI_BLOCK_IO2_PROTOCOL EFI_BLOCK_IO2_PROTOCOL; /** The struct of Block IO2 Token. **/ typedef struct { /// /// If Event is NULL, then blocking I/O is performed.If Event is not NULL and /// non-blocking I/O is supported, then non-blocking I/O is performed, and /// Event will be signaled when the read request is completed. /// EFI_EVENT Event; /// /// Defines whether or not the signaled event encountered an error. /// EFI_STATUS TransactionStatus; } EFI_BLOCK_IO2_TOKEN; /** Reset the block device hardware. @param[in] This Indicates a pointer to the calling context. @param[in] ExtendedVerification Indicates that the driver may perform a more exhausive verification operation of the device during reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_RESET_EX)( IN EFI_BLOCK_IO2_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Read BufferSize bytes from Lba into Buffer. This function reads the requested number of blocks from the device. All the blocks are read, or an error is returned. If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and non-blocking I/O is being used, the Event associated with this request will not be signaled. @param[in] This Indicates a pointer to the calling context. @param[in] MediaId Id of the media, changes every time the media is replaced. @param[in] Lba The starting Logical Block Address to read from. @param[in, out] Token A pointer to the token associated with the transaction. @param[in] BufferSize Size of Buffer, must be a multiple of device block size. @param[out] Buffer A pointer to the destination buffer for the data. The caller is responsible for either having implicit or explicit ownership of the buffer. @retval EFI_SUCCESS The read request was queued if Token->Event is not NULL.The data was read correctly from the device if the Token->Event is NULL. @retval EFI_DEVICE_ERROR The device reported an error while performing the read. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the intrinsic block size of the device. @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, or the buffer is not on proper alignment. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_READ_EX)( IN EFI_BLOCK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT EFI_BLOCK_IO2_TOKEN *Token, IN UINTN BufferSize, OUT VOID *Buffer ); /** Write BufferSize bytes from Lba into Buffer. This function writes the requested number of blocks to the device. All blocks are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA, EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is being used, the Event associated with this request will not be signaled. @param[in] This Indicates a pointer to the calling context. @param[in] MediaId The media ID that the write request is for. @param[in] Lba The starting logical block address to be written. The caller is responsible for writing to only legitimate locations. @param[in, out] Token A pointer to the token associated with the transaction. @param[in] BufferSize Size of Buffer, must be a multiple of device block size. @param[in] Buffer A pointer to the source buffer for the data. @retval EFI_SUCCESS The write request was queued if Event is not NULL. The data was written correctly to the device if the Event is NULL. @retval EFI_WRITE_PROTECTED The device can not be written to. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. @retval EFI_DEVICE_ERROR The device reported an error while performing the write. @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, or the buffer is not on proper alignment. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_WRITE_EX)( IN EFI_BLOCK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT EFI_BLOCK_IO2_TOKEN *Token, IN UINTN BufferSize, IN VOID *Buffer ); /** Flush the Block Device. If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is being used, the Event associated with this request will not be signaled. @param[in] This Indicates a pointer to the calling context. @param[in,out] Token A pointer to the token associated with the transaction @retval EFI_SUCCESS The flush request was queued if Event is not NULL. All outstanding data was written correctly to the device if the Event is NULL. @retval EFI_DEVICE_ERROR The device reported an error while writting back the data. @retval EFI_WRITE_PROTECTED The device cannot be written to. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_BLOCK_FLUSH_EX)( IN EFI_BLOCK_IO2_PROTOCOL *This, IN OUT EFI_BLOCK_IO2_TOKEN *Token ); /// /// The Block I/O2 protocol defines an extension to the Block I/O protocol which /// enables the ability to read and write data at a block level in a non-blocking // manner. /// struct _EFI_BLOCK_IO2_PROTOCOL { /// /// A pointer to the EFI_BLOCK_IO_MEDIA data for this device. /// Type EFI_BLOCK_IO_MEDIA is defined in BlockIo.h. /// EFI_BLOCK_IO_MEDIA *Media; EFI_BLOCK_RESET_EX Reset; EFI_BLOCK_READ_EX ReadBlocksEx; EFI_BLOCK_WRITE_EX WriteBlocksEx; EFI_BLOCK_FLUSH_EX FlushBlocksEx; }; extern EFI_GUID gEfiBlockIo2ProtocolGuid; #endif /** @file Bus Specific Driver Override protocol as defined in the UEFI 2.0 specification. Bus drivers that have a bus specific algorithm for matching drivers to controllers are required to produce this protocol for each controller. For example, a PCI Bus Driver will produce an instance of this protocol for every PCI controller that has a PCI option ROM that contains one or more UEFI drivers. The protocol instance is attached to the handle of the PCI controller. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_H_ #define _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_H_ /// /// Global ID for the Bus Specific Driver Override Protocol /// #define EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID \ { \ 0x3bc1b285, 0x8a15, 0x4a82, {0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65 } \ } typedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL; // // Prototypes for the Bus Specific Driver Override Protocol // /** Uses a bus specific algorithm to retrieve a driver image handle for a controller. @param This A pointer to the EFI_BUS_SPECIFIC_DRIVER_ OVERRIDE_PROTOCOL instance. @param DriverImageHandle On input, a pointer to the previous driver image handle returned by GetDriver(). On output, a pointer to the next driver image handle. Passing in a NULL, will return the first driver image handle. @retval EFI_SUCCESS A bus specific override driver is returned in DriverImageHandle. @retval EFI_NOT_FOUND The end of the list of override drivers was reached. A bus specific override driver is not returned in DriverImageHandle. @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a previous call to GetDriver(). **/ typedef EFI_STATUS (EFIAPI *EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER)( IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, IN OUT EFI_HANDLE *DriverImageHandle ); /// /// This protocol matches one or more drivers to a controller. This protocol is produced by a bus driver, /// and it is installed on the child handles of buses that require a bus specific algorithm for matching /// drivers to controllers. /// struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL { EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER GetDriver; }; extern EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid; #endif /** @file Capsule Architectural Protocol as defined in PI1.0a Specification VOLUME 2 DXE The DXE Driver that produces this protocol must be a runtime driver. The driver is responsible for initializing the CapsuleUpdate() and QueryCapsuleCapabilities() fields of the UEFI Runtime Services Table. After the two fields of the UEFI Runtime Services Table have been initialized, the driver must install the EFI_CAPSULE_ARCH_PROTOCOL_GUID on a new handle with a NULL interface pointer. The installation of this protocol informs the DXE Foundation that the Capsule related services are now available and that the DXE Foundation must update the 32-bit CRC of the UEFI Runtime Services Table. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_CAPSULE_ARCH_H__ #define __ARCH_PROTOCOL_CAPSULE_ARCH_H__ // // Global ID for the Capsule Architectural Protocol // #define EFI_CAPSULE_ARCH_PROTOCOL_GUID \ { 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54 }} extern EFI_GUID gEfiCapsuleArchProtocolGuid; #endif /** @file EFI Component Name Protocol as defined in the EFI 1.1 specification. This protocol is used to retrieve user readable names of EFI Drivers and controllers managed by EFI Drivers. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_COMPONENT_NAME_H__ #define __EFI_COMPONENT_NAME_H__ /// /// The global ID for the Component Name Protocol. /// #define EFI_COMPONENT_NAME_PROTOCOL_GUID \ { \ 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_COMPONENT_NAME_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL; /** Retrieves a Unicode string that is the user-readable name of the EFI Driver. @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. @param Language A pointer to a three-character ISO 639-2 language identifier. This is the language of the driver name that that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. @param DriverName A pointer to the Unicode string to return. This Unicode string is the name of the driver specified by This in the language specified by Language. @retval EFI_SUCCESS The Unicode string for the Driver specified by This and the language specified by Language was returned in DriverName. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER DriverName is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. **/ typedef EFI_STATUS (EFIAPI *EFI_COMPONENT_NAME_GET_DRIVER_NAME)( IN EFI_COMPONENT_NAME_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName ); /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by an EFI Driver. @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. @param ControllerHandle The handle of a controller that the driver specified by This is managing. This handle specifies the controller whose name is to be returned. @param ChildHandle The handle of the child controller to retrieve the name of. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for a bus drivers that wish to retrieve the name of the bus controller. It will not be NULL for a bus driver that wishes to retrieve the name of a child controller. @param Language A pointer to a three character ISO 639-2 language identifier. This is the language of the controller name that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. @param ControllerName A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle in the language specified by Language, from the point of view of the driver specified by This. @retval EFI_SUCCESS The Unicode string for the user-readable name in the language specified by Language for the driver specified by This was returned in DriverName. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER ControllerName is NULL. @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. **/ typedef EFI_STATUS (EFIAPI *EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)( IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName ); /// /// This protocol is used to retrieve user readable names of drivers /// and controllers managed by UEFI Drivers. /// struct _EFI_COMPONENT_NAME_PROTOCOL { EFI_COMPONENT_NAME_GET_DRIVER_NAME GetDriverName; EFI_COMPONENT_NAME_GET_CONTROLLER_NAME GetControllerName; /// /// A Null-terminated ASCII string that contains one or more /// ISO 639-2 language codes. This is the list of language codes /// that this protocol supports. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiComponentNameProtocolGuid; #endif /** @file UEFI Component Name 2 Protocol as defined in the UEFI 2.1 specification. This protocol is used to retrieve user readable names of drivers and controllers managed by UEFI Drivers. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_COMPONENT_NAME2_H__ #define __EFI_COMPONENT_NAME2_H__ /// /// Global ID for the Component Name Protocol /// #define EFI_COMPONENT_NAME2_PROTOCOL_GUID \ {0x6a7a5cff, 0xe8d9, 0x4f70, { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14 } } typedef struct _EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME2_PROTOCOL; /** Retrieves a string that is the user readable name of the EFI Driver. @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL instance. @param Language A pointer to a Null-terminated ASCII string array indicating the language. This is the language of the driver name that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. Language is specified in RFC 4646 language code format. @param DriverName A pointer to the string to return. This string is the name of the driver specified by This in the language specified by Language. @retval EFI_SUCCESS The string for the Driver specified by This and the language specified by Language was returned in DriverName. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER DriverName is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. **/ typedef EFI_STATUS (EFIAPI *EFI_COMPONENT_NAME2_GET_DRIVER_NAME)( IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName ); /** Retrieves a string that is the user readable name of the controller that is being managed by an EFI Driver. @param This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL instance. @param ControllerHandle The handle of a controller that the driver specified by This is managing. This handle specifies the controller whose name is to be returned. @param ChildHandle The handle of the child controller to retrieve the name of. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to retrieve the name of the bus controller. It will not be NULL for a bus driver that wishes to retrieve the name of a child controller. @param Language A pointer to a Null-terminated ASCII string array indicating the language. This is the language of the driver name that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. Language is specified in RFC 4646 language code format. @param ControllerName A pointer to the string to return. This string is the name of the controller specified by ControllerHandle and ChildHandle in the language specified by Language from the point of view of the driver specified by This. @retval EFI_SUCCESS The string for the user readable name in the language specified by Language for the driver specified by This was returned in DriverName. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER ControllerName is NULL. @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. **/ typedef EFI_STATUS (EFIAPI *EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)( IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName ); /// /// This protocol is used to retrieve user readable names of drivers /// and controllers managed by UEFI Drivers. /// struct _EFI_COMPONENT_NAME2_PROTOCOL { EFI_COMPONENT_NAME2_GET_DRIVER_NAME GetDriverName; EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME GetControllerName; /// /// A Null-terminated ASCII string array that contains one or more /// supported language codes. This is the list of language codes that /// this protocol supports. The number of languages supported by a /// driver is up to the driver writer. SupportedLanguages is /// specified in RFC 4646 format. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiComponentName2ProtocolGuid; #endif /** @file CPU Architectural Protocol as defined in PI spec Volume 2 DXE This code abstracts the DXE core from processor implementation details. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_CPU_H__ #define __ARCH_PROTOCOL_CPU_H__ #include #define EFI_CPU_ARCH_PROTOCOL_GUID \ { 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } typedef struct _EFI_CPU_ARCH_PROTOCOL EFI_CPU_ARCH_PROTOCOL; /// /// The type of flush operation /// typedef enum { EfiCpuFlushTypeWriteBackInvalidate, EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate, EfiCpuMaxFlushType } EFI_CPU_FLUSH_TYPE; /// /// The type of processor INIT. /// typedef enum { EfiCpuInit, EfiCpuMaxInitType } EFI_CPU_INIT_TYPE; /** EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. @param InterruptType Defines the type of interrupt or exception that occurred on the processor.This parameter is processor architecture specific. @param SystemContext A pointer to the processor context when the interrupt occurred on the processor. @return None **/ typedef VOID (EFIAPI *EFI_CPU_INTERRUPT_HANDLER)( IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext ); /** This function flushes the range of addresses from Start to Start+Length from the processor's data cache. If Start is not aligned to a cache line boundary, then the bytes before Start to the preceding cache line boundary are also flushed. If Start+Length is not aligned to a cache line boundary, then the bytes past Start+Length to the end of the next cache line boundary are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be supported. If the data cache is fully coherent with all DMA operations, then this function can just return EFI_SUCCESS. If the processor does not support flushing a range of the data cache, then the entire data cache can be flushed. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param Start The beginning physical address to flush from the processor's data cache. @param Length The number of bytes to flush from the processor's data cache. This function may flush more bytes than Length specifies depending upon the granularity of the flush operation that the processor supports. @param FlushType Specifies the type of flush operation to perform. @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from the processor's data cache. @retval EFI_UNSUPPORTED The processor does not support the cache flush type specified by FlushType. @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed from the processor's data cache. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_FLUSH_DATA_CACHE)( IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length, IN EFI_CPU_FLUSH_TYPE FlushType ); /** This function enables interrupt processing by the processor. @param This The EFI_CPU_ARCH_PROTOCOL instance. @retval EFI_SUCCESS Interrupts are enabled on the processor. @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_ENABLE_INTERRUPT)( IN EFI_CPU_ARCH_PROTOCOL *This ); /** This function disables interrupt processing by the processor. @param This The EFI_CPU_ARCH_PROTOCOL instance. @retval EFI_SUCCESS Interrupts are disabled on the processor. @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_DISABLE_INTERRUPT)( IN EFI_CPU_ARCH_PROTOCOL *This ); /** This function retrieves the processor's current interrupt state a returns it in State. If interrupts are currently enabled, then TRUE is returned. If interrupts are currently disabled, then FALSE is returned. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param State A pointer to the processor's current interrupt state. Set to TRUE if interrupts are enabled and FALSE if interrupts are disabled. @retval EFI_SUCCESS The processor's current interrupt state was returned in State. @retval EFI_INVALID_PARAMETER State is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_GET_INTERRUPT_STATE)( IN EFI_CPU_ARCH_PROTOCOL *This, OUT BOOLEAN *State ); /** This function generates an INIT on the processor. If this function succeeds, then the processor will be reset, and control will not be returned to the caller. If InitType is not supported by this processor, or the processor cannot programmatically generate an INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param InitType The type of processor INIT to perform. @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen. @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported by this processor. @retval EFI_DEVICE_ERROR The processor INIT failed. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_INIT)( IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_CPU_INIT_TYPE InitType ); /** This function registers and enables the handler specified by InterruptHandler for a processor interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the handler for the processor interrupt or exception type specified by InterruptType is uninstalled. The installed handler is called once for each processor interrupt or exception. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts are enabled and FALSE if interrupts are disabled. @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. If this parameter is NULL, then the handler will be uninstalled. @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed. @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed. @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_REGISTER_INTERRUPT_HANDLER)( IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler ); /** This function reads the processor timer specified by TimerIndex and returns it in TimerValue. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter must be between 0 and NumberOfTimers-1. @param TimerValue Pointer to the returned timer value. @param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment of TimerValue. If TimerValue does not increment at a predictable rate, then 0 is returned. This parameter is optional and may be NULL. @retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue. @retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers. @retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid. @retval EFI_UNSUPPORTED The processor does not have any readable timers. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_GET_TIMER_VALUE)( IN EFI_CPU_ARCH_PROTOCOL *This, IN UINT32 TimerIndex, OUT UINT64 *TimerValue, OUT UINT64 *TimerPeriod OPTIONAL ); /** This function modifies the attributes for the memory region specified by BaseAddress and Length from their current attributes to the attributes specified by Attributes. @param This The EFI_CPU_ARCH_PROTOCOL instance. @param BaseAddress The physical address that is the start address of a memory region. @param Length The size in bytes of the memory region. @param Attributes The bit mask of attributes to set for the memory region. @retval EFI_SUCCESS The attributes were set for the memory region. @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by BaseAddress and Length cannot be modified. @retval EFI_INVALID_PARAMETER Length is zero. Attributes specified an illegal combination of attributes that cannot be set together. @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of the memory resource range. @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory resource range specified by BaseAddress and Length. The bit mask of attributes is not support for the memory resource range specified by BaseAddress and Length. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_SET_MEMORY_ATTRIBUTES)( IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes ); /// /// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE /// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt /// vectors and exception vectors, reading internal processor timers, resetting the processor, and /// determining the processor frequency. /// struct _EFI_CPU_ARCH_PROTOCOL { EFI_CPU_FLUSH_DATA_CACHE FlushDataCache; EFI_CPU_ENABLE_INTERRUPT EnableInterrupt; EFI_CPU_DISABLE_INTERRUPT DisableInterrupt; EFI_CPU_GET_INTERRUPT_STATE GetInterruptState; EFI_CPU_INIT Init; EFI_CPU_REGISTER_INTERRUPT_HANDLER RegisterInterruptHandler; EFI_CPU_GET_TIMER_VALUE GetTimerValue; EFI_CPU_SET_MEMORY_ATTRIBUTES SetMemoryAttributes; /// /// The number of timers that are available in a processor. The value in this /// field is a constant that must not be modified after the CPU Architectural /// Protocol is installed. All consumers must treat this as a read-only field. /// UINT32 NumberOfTimers; /// /// The size, in bytes, of the alignment required for DMA buffer allocations. /// This is typically the size of the largest data cache line in the platform. /// The value in this field is a constant that must not be modified after the /// CPU Architectural Protocol is installed. All consumers must treat this as /// a read-only field. /// UINT32 DmaBufferAlignment; }; extern EFI_GUID gEfiCpuArchProtocolGuid; #endif /** @file This files describes the CPU I/O 2 Protocol. This protocol provides an I/O abstraction for a system processor. This protocol is used by a PCI root bridge I/O driver to perform memory-mapped I/O and I/O transactions. The I/O or memory primitives can be used by the consumer of the protocol to materialize bus-specific configuration cycles, such as the transitional configuration address and data ports for PCI. Only drivers that require direct access to the entire system should use this protocol. Note: This is a boot-services only protocol and it may not be used by runtime drivers after ExitBootServices(). It is different from the Framework CPU I/O Protocol, which is a runtime protocol and can be used by runtime drivers after ExitBootServices(). Copyright (c) 2007 - 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 __CPU_IO2_H__ #define __CPU_IO2_H__ #define EFI_CPU_IO2_PROTOCOL_GUID \ { \ 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} \ } typedef struct _EFI_CPU_IO2_PROTOCOL EFI_CPU_IO2_PROTOCOL; /// /// Enumeration that defines the width of the I/O operation. /// typedef enum { EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, EfiCpuIoWidthUint64, EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, EfiCpuIoWidthFifoUint32, EfiCpuIoWidthFifoUint64, EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, EfiCpuIoWidthFillUint32, EfiCpuIoWidthFillUint64, EfiCpuIoWidthMaximum } EFI_CPU_IO_PROTOCOL_WIDTH; /** Enables a driver to access registers in the PI CPU I/O space. The Io.Read() and Io.Write() functions enable a driver to access PCI controller registers in the PI CPU I/O space. The I/O operations are carried out exactly as requested. The caller is responsible for satisfying any alignment and I/O width restrictions that a PI System on a platform might require. For example on some platforms, width requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver. If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for each of the Count operations that is performed. If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address. If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer. @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. @param[in] Width Signifies the width of the I/O or Memory operation. @param[in] Address The base address of the I/O operation. @param[in] Count The number of I/O operations to perform. The number of bytes moved is Width size * Count, starting at Address. @param[in, out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data. @retval EFI_SUCCESS The data was read from or written to the PI system. @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this PI system. **/ typedef EFI_STATUS (EFIAPI *EFI_CPU_IO_PROTOCOL_IO_MEM)( IN EFI_CPU_IO2_PROTOCOL *This, IN EFI_CPU_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer ); /// /// Service for read and write accesses. /// typedef struct { /// /// This service provides the various modalities of memory and I/O read. /// EFI_CPU_IO_PROTOCOL_IO_MEM Read; /// /// This service provides the various modalities of memory and I/O write. /// EFI_CPU_IO_PROTOCOL_IO_MEM Write; } EFI_CPU_IO_PROTOCOL_ACCESS; /// /// Provides the basic memory and I/O interfaces that are used to abstract /// accesses to devices in a system. /// struct _EFI_CPU_IO2_PROTOCOL { /// /// Enables a driver to access memory-mapped registers in the EFI system memory space. /// EFI_CPU_IO_PROTOCOL_ACCESS Mem; /// /// Enables a driver to access registers in the EFI CPU I/O space. /// EFI_CPU_IO_PROTOCOL_ACCESS Io; }; extern EFI_GUID gEfiCpuIo2ProtocolGuid; #endif /** @file The data hub protocol is used both by agents wishing to log data and those wishing to be made aware of all information that has been logged. This protocol may only be called <= TPL_NOTIFY. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License that accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @par Revision Reference: The Data Hub Protocol is defined in Framework for EFI Data Hub Specification Version 0.9. **/ #ifndef __DATA_HUB_H__ #define __DATA_HUB_H__ #define EFI_DATA_HUB_PROTOCOL_GUID \ { \ 0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ } // // EFI generic Data Hub Header // // A Data Record is an EFI_DATA_RECORD_HEADER followed by RecordSize bytes of // data. The format of the data is defined by the DataRecordGuid. // // If EFI_DATA_RECORD_HEADER is extended in the future, the Version number and HeaderSize must // change. // // The logger is responcible for initializing: // Version, HeaderSize, RecordSize, DataRecordGuid, DataRecordClass // // The Data Hub driver is responcible for initializing: // LogTime and LogMonotonicCount. // #define EFI_DATA_RECORD_HEADER_VERSION 0x0100 typedef struct { UINT16 Version; UINT16 HeaderSize; UINT32 RecordSize; EFI_GUID DataRecordGuid; EFI_GUID ProducerName; UINT64 DataRecordClass; EFI_TIME LogTime; UINT64 LogMonotonicCount; } EFI_DATA_RECORD_HEADER; // // Definition of DataRecordClass. These are used to filter out class types // at a very high level. The DataRecordGuid still defines the format of // the data. See the Data Hub Specification for rules on what can and can not be a // new DataRecordClass // #define EFI_DATA_RECORD_CLASS_DEBUG 0x0000000000000001 #define EFI_DATA_RECORD_CLASS_ERROR 0x0000000000000002 #define EFI_DATA_RECORD_CLASS_DATA 0x0000000000000004 #define EFI_DATA_RECORD_CLASS_PROGRESS_CODE 0x0000000000000008 // // Forward reference for pure ANSI compatability // typedef struct _EFI_DATA_HUB_PROTOCOL EFI_DATA_HUB_PROTOCOL; /** Logs a data record to the system event log. @param This The EFI_DATA_HUB_PROTOCOL instance. @param DataRecordGuid A GUID that indicates the format of the data passed into RawData. @param ProducerName A GUID that indicates the identity of the caller to this API. @param DataRecordClass This class indicates the generic type of the data record. @param RawData The DataRecordGuid-defined data to be logged. @param RawDataSize The size in bytes of RawData. @retval EFI_SUCCESS Data was logged. @retval EFI_OUT_OF_RESOURCES Data was not logged due to lack of system resources. **/ typedef EFI_STATUS (EFIAPI *EFI_DATA_HUB_LOG_DATA)( IN EFI_DATA_HUB_PROTOCOL *This, IN EFI_GUID *DataRecordGuid, IN EFI_GUID *ProducerName, IN UINT64 DataRecordClass, IN VOID *RawData, IN UINT32 RawDataSize ); /** Allows the system data log to be searched. @param This The EFI_DATA_HUB_PROTOCOL instance. @param MonotonicCount On input, it specifies the Record to return. An input of zero means to return the first record, as does an input of one. @param FilterDriver If FilterDriver is not passed in a MonotonicCount of zero, it means to return the first data record. If FilterDriver is passed in, then a MonotonicCount of zero means to return the first data not yet read by FilterDriver. @param Record Returns a dynamically allocated memory buffer with a data record that matches MonotonicCount. @retval EFI_SUCCESS Data was returned in Record. @retval EFI_INVALID_PARAMETER FilterDriver was passed in but does not exist. @retval EFI_NOT_FOUND MonotonicCount does not match any data record in the system. If a MonotonicCount of zero was passed in, then no data records exist in the system. @retval EFI_OUT_OF_RESOURCES Record was not returned due to lack of system resources. @note Inconsistent with specification here: In Framework for EFI Data Hub Specification, Version 0.9, This definition is named as EFI_DATA_HUB_GET_NEXT_DATA_RECORD. The inconsistency is maintained for backward compatibility. **/ typedef EFI_STATUS (EFIAPI *EFI_DATA_HUB_GET_NEXT_RECORD)( IN EFI_DATA_HUB_PROTOCOL *This, IN OUT UINT64 *MonotonicCount, IN EFI_EVENT *FilterDriver OPTIONAL, OUT EFI_DATA_RECORD_HEADER **Record ); /** Registers an event to be signaled every time a data record is logged in the system. @param This The EFI_DATA_HUB_PROTOCOL instance. @param FilterEvent The EFI_EVENT to signal whenever data that matches FilterClass is logged in the system. @param FilterTpl The maximum EFI_TPL at which FilterEvent can be signaled. It is strongly recommended that you use the lowest EFI_TPL possible. @param FilterClass FilterEvent will be signaled whenever a bit in EFI_DATA_RECORD_HEADER.DataRecordClass is also set in FilterClass. If FilterClass is zero, no class-based filtering will be performed. @param FilterDataRecordGuid FilterEvent will be signaled whenever FilterDataRecordGuid matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If FilterDataRecordGuid is NULL, then no GUID-based filtering will be performed. @retval EFI_SUCCESS The filter driver event was registered @retval EFI_ALREADY_STARTED FilterEvent was previously registered and cannot be registered again. @retval EFI_OUT_OF_RESOURCES The filter driver event was not registered due to lack of system resources. @note Inconsistent with specification here: In Framework for EFI Data Hub Specification, Version 0.9, This definition is named as EFI_DATA_HUB_REGISTER_DATA_FILTER_DRIVER. The inconsistency is maintained for backward compatibility. **/ typedef EFI_STATUS (EFIAPI *EFI_DATA_HUB_REGISTER_FILTER_DRIVER)( IN EFI_DATA_HUB_PROTOCOL *This, IN EFI_EVENT FilterEvent, IN EFI_TPL FilterTpl, IN UINT64 FilterClass, IN EFI_GUID *FilterDataRecordGuid OPTIONAL ); /** Stops a filter driver from being notified when data records are logged. @param This The EFI_DATA_HUB_PROTOCOL instance. @param FilterEvent The EFI_EVENT to remove from the list of events to be signaled every time errors are logged. @retval EFI_SUCCESS The filter driver represented by FilterEvent was shut off. @retval EFI_NOT_FOUND FilterEvent did not exist. @note Inconsistent with specification here: In Framework for EFI Data Hub Specification, Version 0.9, This definition is named as EFI_DATA_HUB_UNREGISTER_DATA_FILTER_DRIVER. The inconsistency is maintained for backward compatibility. **/ typedef EFI_STATUS (EFIAPI *EFI_DATA_HUB_UNREGISTER_FILTER_DRIVER)( IN EFI_DATA_HUB_PROTOCOL *This, IN EFI_EVENT FilterEvent ); /** This protocol is used to log information and register filter drivers to receive data records. **/ struct _EFI_DATA_HUB_PROTOCOL { /// /// Logs a data record. /// EFI_DATA_HUB_LOG_DATA LogData; /// /// Gets a data record. Used both to view the memory-based log and to /// get information about which data records have been consumed by a filter driver. /// EFI_DATA_HUB_GET_NEXT_RECORD GetNextRecord; /// /// Allows the registration of an EFI event to act as a filter driver for all data records that are logged. /// EFI_DATA_HUB_REGISTER_FILTER_DRIVER RegisterFilterDriver; /// /// Used to remove a filter driver that was added with RegisterFilterDriver(). /// EFI_DATA_HUB_UNREGISTER_FILTER_DRIVER UnregisterFilterDriver; }; extern EFI_GUID gEfiDataHubProtocolGuid; #endif /** @file The file defines the EFI Debugport protocol. This protocol is used by debug agent to communicate with the remote debug host. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEBUG_PORT_H__ #define __DEBUG_PORT_H__ /// /// DebugPortIo protocol {EBA4E8D2-3858-41EC-A281-2647BA9660D0} /// #define EFI_DEBUGPORT_PROTOCOL_GUID \ { \ 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ } extern EFI_GUID gEfiDebugPortProtocolGuid; typedef struct _EFI_DEBUGPORT_PROTOCOL EFI_DEBUGPORT_PROTOCOL; // // DebugPort member functions // /** Resets the debugport. @param This A pointer to the EFI_DEBUGPORT_PROTOCOL instance. @retval EFI_SUCCESS The debugport device was reset and is in usable state. @retval EFI_DEVICE_ERROR The debugport device could not be reset and is unusable. **/ typedef EFI_STATUS (EFIAPI *EFI_DEBUGPORT_RESET)( IN EFI_DEBUGPORT_PROTOCOL *This ); /** Writes data to the debugport. @param This A pointer to the EFI_DEBUGPORT_PROTOCOL instance. @param Timeout The number of microseconds to wait before timing out a write operation. @param BufferSize On input, the requested number of bytes of data to write. On output, the number of bytes of data actually written. @param Buffer A pointer to a buffer containing the data to write. @retval EFI_SUCCESS The data was written. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The data write was stopped due to a timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_DEBUGPORT_WRITE)( IN EFI_DEBUGPORT_PROTOCOL *This, IN UINT32 Timeout, IN OUT UINTN *BufferSize, IN VOID *Buffer ); /** Reads data from the debugport. @param This A pointer to the EFI_DEBUGPORT_PROTOCOL instance. @param Timeout The number of microseconds to wait before timing out a read operation. @param BufferSize On input, the requested number of bytes of data to read. On output, the number of bytes of data actually number of bytes of data read and returned in Buffer. @param Buffer A pointer to a buffer into which the data read will be saved. @retval EFI_SUCCESS The data was read. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The operation was stopped due to a timeout or overrun. **/ typedef EFI_STATUS (EFIAPI *EFI_DEBUGPORT_READ)( IN EFI_DEBUGPORT_PROTOCOL *This, IN UINT32 Timeout, IN OUT UINTN *BufferSize, OUT VOID *Buffer ); /** Checks to see if any data is available to be read from the debugport device. @param This A pointer to the EFI_DEBUGPORT_PROTOCOL instance. @retval EFI_SUCCESS At least one byte of data is available to be read. @retval EFI_DEVICE_ERROR The debugport device is not functioning correctly. @retval EFI_NOT_READY No data is available to be read. **/ typedef EFI_STATUS (EFIAPI *EFI_DEBUGPORT_POLL)( IN EFI_DEBUGPORT_PROTOCOL *This ); /// /// This protocol provides the communication link between the debug agent and the remote host. /// struct _EFI_DEBUGPORT_PROTOCOL { EFI_DEBUGPORT_RESET Reset; EFI_DEBUGPORT_WRITE Write; EFI_DEBUGPORT_READ Read; EFI_DEBUGPORT_POLL Poll; }; // // DEBUGPORT variable definitions... // #define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT" #define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID extern EFI_GUID gEfiDebugPortVariableGuid; // // DebugPort device path definitions... // #define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID extern EFI_GUID gEfiDebugPortDevicePathGuid; typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; EFI_GUID Guid; } DEBUGPORT_DEVICE_PATH; #endif /** @file DebugSupport protocol and supporting definitions as defined in the UEFI2.4 specification. The DebugSupport protocol is used by source level debuggers to abstract the processor and handle context save and restore operations. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEBUG_SUPPORT_H__ #define __DEBUG_SUPPORT_H__ #include typedef struct _EFI_DEBUG_SUPPORT_PROTOCOL EFI_DEBUG_SUPPORT_PROTOCOL; /// /// Debug Support protocol {2755590C-6F3C-42FA-9EA4-A3BA543CDA25}. /// #define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ { \ 0x2755590C, 0x6F3C, 0x42FA, {0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ } /// /// Processor exception to be hooked. /// All exception types for IA32, X64, Itanium and EBC processors are defined. /// typedef INTN EFI_EXCEPTION_TYPE; /// /// IA-32 processor exception types. /// #define EXCEPT_IA32_DIVIDE_ERROR 0 #define EXCEPT_IA32_DEBUG 1 #define EXCEPT_IA32_NMI 2 #define EXCEPT_IA32_BREAKPOINT 3 #define EXCEPT_IA32_OVERFLOW 4 #define EXCEPT_IA32_BOUND 5 #define EXCEPT_IA32_INVALID_OPCODE 6 #define EXCEPT_IA32_DOUBLE_FAULT 8 #define EXCEPT_IA32_INVALID_TSS 10 #define EXCEPT_IA32_SEG_NOT_PRESENT 11 #define EXCEPT_IA32_STACK_FAULT 12 #define EXCEPT_IA32_GP_FAULT 13 #define EXCEPT_IA32_PAGE_FAULT 14 #define EXCEPT_IA32_FP_ERROR 16 #define EXCEPT_IA32_ALIGNMENT_CHECK 17 #define EXCEPT_IA32_MACHINE_CHECK 18 #define EXCEPT_IA32_SIMD 19 /// /// FXSAVE_STATE. /// FP / MMX / XMM registers (see fxrstor instruction definition). /// typedef struct { UINT16 Fcw; UINT16 Fsw; UINT16 Ftw; UINT16 Opcode; UINT32 Eip; UINT16 Cs; UINT16 Reserved1; UINT32 DataOffset; UINT16 Ds; UINT8 Reserved2[10]; UINT8 St0Mm0[10], Reserved3[6]; UINT8 St1Mm1[10], Reserved4[6]; UINT8 St2Mm2[10], Reserved5[6]; UINT8 St3Mm3[10], Reserved6[6]; UINT8 St4Mm4[10], Reserved7[6]; UINT8 St5Mm5[10], Reserved8[6]; UINT8 St6Mm6[10], Reserved9[6]; UINT8 St7Mm7[10], Reserved10[6]; UINT8 Xmm0[16]; UINT8 Xmm1[16]; UINT8 Xmm2[16]; UINT8 Xmm3[16]; UINT8 Xmm4[16]; UINT8 Xmm5[16]; UINT8 Xmm6[16]; UINT8 Xmm7[16]; UINT8 Reserved11[14 * 16]; } EFI_FX_SAVE_STATE_IA32; /// /// IA-32 processor context definition. /// typedef struct { UINT32 ExceptionData; EFI_FX_SAVE_STATE_IA32 FxSaveState; UINT32 Dr0; UINT32 Dr1; UINT32 Dr2; UINT32 Dr3; UINT32 Dr6; UINT32 Dr7; UINT32 Cr0; UINT32 Cr1; /* Reserved */ UINT32 Cr2; UINT32 Cr3; UINT32 Cr4; UINT32 Eflags; UINT32 Ldtr; UINT32 Tr; UINT32 Gdtr[2]; UINT32 Idtr[2]; UINT32 Eip; UINT32 Gs; UINT32 Fs; UINT32 Es; UINT32 Ds; UINT32 Cs; UINT32 Ss; UINT32 Edi; UINT32 Esi; UINT32 Ebp; UINT32 Esp; UINT32 Ebx; UINT32 Edx; UINT32 Ecx; UINT32 Eax; } EFI_SYSTEM_CONTEXT_IA32; /// /// x64 processor exception types. /// #define EXCEPT_X64_DIVIDE_ERROR 0 #define EXCEPT_X64_DEBUG 1 #define EXCEPT_X64_NMI 2 #define EXCEPT_X64_BREAKPOINT 3 #define EXCEPT_X64_OVERFLOW 4 #define EXCEPT_X64_BOUND 5 #define EXCEPT_X64_INVALID_OPCODE 6 #define EXCEPT_X64_DOUBLE_FAULT 8 #define EXCEPT_X64_INVALID_TSS 10 #define EXCEPT_X64_SEG_NOT_PRESENT 11 #define EXCEPT_X64_STACK_FAULT 12 #define EXCEPT_X64_GP_FAULT 13 #define EXCEPT_X64_PAGE_FAULT 14 #define EXCEPT_X64_FP_ERROR 16 #define EXCEPT_X64_ALIGNMENT_CHECK 17 #define EXCEPT_X64_MACHINE_CHECK 18 #define EXCEPT_X64_SIMD 19 /// /// FXSAVE_STATE. /// FP / MMX / XMM registers (see fxrstor instruction definition). /// typedef struct { UINT16 Fcw; UINT16 Fsw; UINT16 Ftw; UINT16 Opcode; UINT64 Rip; UINT64 DataOffset; UINT8 Reserved1[8]; UINT8 St0Mm0[10], Reserved2[6]; UINT8 St1Mm1[10], Reserved3[6]; UINT8 St2Mm2[10], Reserved4[6]; UINT8 St3Mm3[10], Reserved5[6]; UINT8 St4Mm4[10], Reserved6[6]; UINT8 St5Mm5[10], Reserved7[6]; UINT8 St6Mm6[10], Reserved8[6]; UINT8 St7Mm7[10], Reserved9[6]; UINT8 Xmm0[16]; UINT8 Xmm1[16]; UINT8 Xmm2[16]; UINT8 Xmm3[16]; UINT8 Xmm4[16]; UINT8 Xmm5[16]; UINT8 Xmm6[16]; UINT8 Xmm7[16]; // // NOTE: UEFI 2.0 spec definition as follows. // UINT8 Reserved11[14 * 16]; } EFI_FX_SAVE_STATE_X64; /// /// x64 processor context definition. /// typedef struct { UINT64 ExceptionData; EFI_FX_SAVE_STATE_X64 FxSaveState; UINT64 Dr0; UINT64 Dr1; UINT64 Dr2; UINT64 Dr3; UINT64 Dr6; UINT64 Dr7; UINT64 Cr0; UINT64 Cr1; /* Reserved */ UINT64 Cr2; UINT64 Cr3; UINT64 Cr4; UINT64 Cr8; UINT64 Rflags; UINT64 Ldtr; UINT64 Tr; UINT64 Gdtr[2]; UINT64 Idtr[2]; UINT64 Rip; UINT64 Gs; UINT64 Fs; UINT64 Es; UINT64 Ds; UINT64 Cs; UINT64 Ss; UINT64 Rdi; UINT64 Rsi; UINT64 Rbp; UINT64 Rsp; UINT64 Rbx; UINT64 Rdx; UINT64 Rcx; UINT64 Rax; UINT64 R8; UINT64 R9; UINT64 R10; UINT64 R11; UINT64 R12; UINT64 R13; UINT64 R14; UINT64 R15; } EFI_SYSTEM_CONTEXT_X64; /// /// Itanium Processor Family Exception types. /// #define EXCEPT_IPF_VHTP_TRANSLATION 0 #define EXCEPT_IPF_INSTRUCTION_TLB 1 #define EXCEPT_IPF_DATA_TLB 2 #define EXCEPT_IPF_ALT_INSTRUCTION_TLB 3 #define EXCEPT_IPF_ALT_DATA_TLB 4 #define EXCEPT_IPF_DATA_NESTED_TLB 5 #define EXCEPT_IPF_INSTRUCTION_KEY_MISSED 6 #define EXCEPT_IPF_DATA_KEY_MISSED 7 #define EXCEPT_IPF_DIRTY_BIT 8 #define EXCEPT_IPF_INSTRUCTION_ACCESS_BIT 9 #define EXCEPT_IPF_DATA_ACCESS_BIT 10 #define EXCEPT_IPF_BREAKPOINT 11 #define EXCEPT_IPF_EXTERNAL_INTERRUPT 12 // // 13 - 19 reserved // #define EXCEPT_IPF_PAGE_NOT_PRESENT 20 #define EXCEPT_IPF_KEY_PERMISSION 21 #define EXCEPT_IPF_INSTRUCTION_ACCESS_RIGHTS 22 #define EXCEPT_IPF_DATA_ACCESS_RIGHTS 23 #define EXCEPT_IPF_GENERAL_EXCEPTION 24 #define EXCEPT_IPF_DISABLED_FP_REGISTER 25 #define EXCEPT_IPF_NAT_CONSUMPTION 26 #define EXCEPT_IPF_SPECULATION 27 // // 28 reserved // #define EXCEPT_IPF_DEBUG 29 #define EXCEPT_IPF_UNALIGNED_REFERENCE 30 #define EXCEPT_IPF_UNSUPPORTED_DATA_REFERENCE 31 #define EXCEPT_IPF_FP_FAULT 32 #define EXCEPT_IPF_FP_TRAP 33 #define EXCEPT_IPF_LOWER_PRIVILEGE_TRANSFER_TRAP 34 #define EXCEPT_IPF_TAKEN_BRANCH 35 #define EXCEPT_IPF_SINGLE_STEP 36 // // 37 - 44 reserved // #define EXCEPT_IPF_IA32_EXCEPTION 45 #define EXCEPT_IPF_IA32_INTERCEPT 46 #define EXCEPT_IPF_IA32_INTERRUPT 47 /// /// IPF processor context definition. /// typedef struct { // // The first reserved field is necessary to preserve alignment for the correct // bits in UNAT and to insure F2 is 16 byte aligned. // UINT64 Reserved; UINT64 R1; UINT64 R2; UINT64 R3; UINT64 R4; UINT64 R5; UINT64 R6; UINT64 R7; UINT64 R8; UINT64 R9; UINT64 R10; UINT64 R11; UINT64 R12; UINT64 R13; UINT64 R14; UINT64 R15; UINT64 R16; UINT64 R17; UINT64 R18; UINT64 R19; UINT64 R20; UINT64 R21; UINT64 R22; UINT64 R23; UINT64 R24; UINT64 R25; UINT64 R26; UINT64 R27; UINT64 R28; UINT64 R29; UINT64 R30; UINT64 R31; UINT64 F2[2]; UINT64 F3[2]; UINT64 F4[2]; UINT64 F5[2]; UINT64 F6[2]; UINT64 F7[2]; UINT64 F8[2]; UINT64 F9[2]; UINT64 F10[2]; UINT64 F11[2]; UINT64 F12[2]; UINT64 F13[2]; UINT64 F14[2]; UINT64 F15[2]; UINT64 F16[2]; UINT64 F17[2]; UINT64 F18[2]; UINT64 F19[2]; UINT64 F20[2]; UINT64 F21[2]; UINT64 F22[2]; UINT64 F23[2]; UINT64 F24[2]; UINT64 F25[2]; UINT64 F26[2]; UINT64 F27[2]; UINT64 F28[2]; UINT64 F29[2]; UINT64 F30[2]; UINT64 F31[2]; UINT64 Pr; UINT64 B0; UINT64 B1; UINT64 B2; UINT64 B3; UINT64 B4; UINT64 B5; UINT64 B6; UINT64 B7; // // application registers // UINT64 ArRsc; UINT64 ArBsp; UINT64 ArBspstore; UINT64 ArRnat; UINT64 ArFcr; UINT64 ArEflag; UINT64 ArCsd; UINT64 ArSsd; UINT64 ArCflg; UINT64 ArFsr; UINT64 ArFir; UINT64 ArFdr; UINT64 ArCcv; UINT64 ArUnat; UINT64 ArFpsr; UINT64 ArPfs; UINT64 ArLc; UINT64 ArEc; // // control registers // UINT64 CrDcr; UINT64 CrItm; UINT64 CrIva; UINT64 CrPta; UINT64 CrIpsr; UINT64 CrIsr; UINT64 CrIip; UINT64 CrIfa; UINT64 CrItir; UINT64 CrIipa; UINT64 CrIfs; UINT64 CrIim; UINT64 CrIha; // // debug registers // UINT64 Dbr0; UINT64 Dbr1; UINT64 Dbr2; UINT64 Dbr3; UINT64 Dbr4; UINT64 Dbr5; UINT64 Dbr6; UINT64 Dbr7; UINT64 Ibr0; UINT64 Ibr1; UINT64 Ibr2; UINT64 Ibr3; UINT64 Ibr4; UINT64 Ibr5; UINT64 Ibr6; UINT64 Ibr7; // // virtual registers - nat bits for R1-R31 // UINT64 IntNat; } EFI_SYSTEM_CONTEXT_IPF; /// /// EBC processor exception types. /// #define EXCEPT_EBC_UNDEFINED 0 #define EXCEPT_EBC_DIVIDE_ERROR 1 #define EXCEPT_EBC_DEBUG 2 #define EXCEPT_EBC_BREAKPOINT 3 #define EXCEPT_EBC_OVERFLOW 4 #define EXCEPT_EBC_INVALID_OPCODE 5 ///< Opcode out of range. #define EXCEPT_EBC_STACK_FAULT 6 #define EXCEPT_EBC_ALIGNMENT_CHECK 7 #define EXCEPT_EBC_INSTRUCTION_ENCODING 8 ///< Malformed instruction. #define EXCEPT_EBC_BAD_BREAK 9 ///< BREAK 0 or undefined BREAK. #define EXCEPT_EBC_STEP 10 ///< To support debug stepping. /// /// For coding convenience, define the maximum valid EBC exception. /// #define MAX_EBC_EXCEPTION EXCEPT_EBC_STEP /// /// EBC processor context definition. /// typedef struct { UINT64 R0; UINT64 R1; UINT64 R2; UINT64 R3; UINT64 R4; UINT64 R5; UINT64 R6; UINT64 R7; UINT64 Flags; UINT64 ControlFlags; UINT64 Ip; } EFI_SYSTEM_CONTEXT_EBC; /// /// ARM processor exception types. /// #define EXCEPT_ARM_RESET 0 #define EXCEPT_ARM_UNDEFINED_INSTRUCTION 1 #define EXCEPT_ARM_SOFTWARE_INTERRUPT 2 #define EXCEPT_ARM_PREFETCH_ABORT 3 #define EXCEPT_ARM_DATA_ABORT 4 #define EXCEPT_ARM_RESERVED 5 #define EXCEPT_ARM_IRQ 6 #define EXCEPT_ARM_FIQ 7 /// /// For coding convenience, define the maximum valid ARM exception. /// #define MAX_ARM_EXCEPTION EXCEPT_ARM_FIQ /// /// ARM processor context definition. /// typedef struct { UINT32 R0; UINT32 R1; UINT32 R2; UINT32 R3; UINT32 R4; UINT32 R5; UINT32 R6; UINT32 R7; UINT32 R8; UINT32 R9; UINT32 R10; UINT32 R11; UINT32 R12; UINT32 SP; UINT32 LR; UINT32 PC; UINT32 CPSR; UINT32 DFSR; UINT32 DFAR; UINT32 IFSR; UINT32 IFAR; } EFI_SYSTEM_CONTEXT_ARM; /// /// AARCH64 processor exception types. /// #define EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS 0 #define EXCEPT_AARCH64_IRQ 1 #define EXCEPT_AARCH64_FIQ 2 #define EXCEPT_AARCH64_SERROR 3 /// /// For coding convenience, define the maximum valid ARM exception. /// #define MAX_AARCH64_EXCEPTION EXCEPT_AARCH64_SERROR typedef struct { // General Purpose Registers UINT64 X0; UINT64 X1; UINT64 X2; UINT64 X3; UINT64 X4; UINT64 X5; UINT64 X6; UINT64 X7; UINT64 X8; UINT64 X9; UINT64 X10; UINT64 X11; UINT64 X12; UINT64 X13; UINT64 X14; UINT64 X15; UINT64 X16; UINT64 X17; UINT64 X18; UINT64 X19; UINT64 X20; UINT64 X21; UINT64 X22; UINT64 X23; UINT64 X24; UINT64 X25; UINT64 X26; UINT64 X27; UINT64 X28; UINT64 FP; // x29 - Frame pointer UINT64 LR; // x30 - Link Register UINT64 SP; // x31 - Stack pointer // FP/SIMD Registers UINT64 V0[2]; UINT64 V1[2]; UINT64 V2[2]; UINT64 V3[2]; UINT64 V4[2]; UINT64 V5[2]; UINT64 V6[2]; UINT64 V7[2]; UINT64 V8[2]; UINT64 V9[2]; UINT64 V10[2]; UINT64 V11[2]; UINT64 V12[2]; UINT64 V13[2]; UINT64 V14[2]; UINT64 V15[2]; UINT64 V16[2]; UINT64 V17[2]; UINT64 V18[2]; UINT64 V19[2]; UINT64 V20[2]; UINT64 V21[2]; UINT64 V22[2]; UINT64 V23[2]; UINT64 V24[2]; UINT64 V25[2]; UINT64 V26[2]; UINT64 V27[2]; UINT64 V28[2]; UINT64 V29[2]; UINT64 V30[2]; UINT64 V31[2]; UINT64 ELR; // Exception Link Register UINT64 SPSR; // Saved Processor Status Register UINT64 FPSR; // Floating Point Status Register UINT64 ESR; // Exception syndrome register UINT64 FAR; // Fault Address Register } EFI_SYSTEM_CONTEXT_AARCH64; /// /// RISC-V processor exception types. /// #define EXCEPT_RISCV_INST_MISALIGNED 0 #define EXCEPT_RISCV_INST_ACCESS_FAULT 1 #define EXCEPT_RISCV_ILLEGAL_INST 2 #define EXCEPT_RISCV_BREAKPOINT 3 #define EXCEPT_RISCV_LOAD_ADDRESS_MISALIGNED 4 #define EXCEPT_RISCV_LOAD_ACCESS_FAULT 5 #define EXCEPT_RISCV_STORE_AMO_ADDRESS_MISALIGNED 6 #define EXCEPT_RISCV_STORE_AMO_ACCESS_FAULT 7 #define EXCEPT_RISCV_ENV_CALL_FROM_UMODE 8 #define EXCEPT_RISCV_ENV_CALL_FROM_SMODE 9 #define EXCEPT_RISCV_ENV_CALL_FROM_HMODE 10 #define EXCEPT_RISCV_ENV_CALL_FROM_MMODE 11 #define EXCEPT_RISCV_SOFTWARE_INT 0x0 #define EXCEPT_RISCV_TIMER_INT 0x1 typedef struct { UINT64 X0; UINT64 X1; UINT64 X2; UINT64 X3; UINT64 X4; UINT64 X5; UINT64 X6; UINT64 X7; UINT64 X8; UINT64 X9; UINT64 X10; UINT64 X11; UINT64 X12; UINT64 X13; UINT64 X14; UINT64 X15; UINT64 X16; UINT64 X17; UINT64 X18; UINT64 X19; UINT64 X20; UINT64 X21; UINT64 X22; UINT64 X23; UINT64 X24; UINT64 X25; UINT64 X26; UINT64 X27; UINT64 X28; UINT64 X29; UINT64 X30; UINT64 X31; } EFI_SYSTEM_CONTEXT_RISCV64; /// /// Universal EFI_SYSTEM_CONTEXT definition. /// typedef union { EFI_SYSTEM_CONTEXT_EBC *SystemContextEbc; EFI_SYSTEM_CONTEXT_IA32 *SystemContextIa32; EFI_SYSTEM_CONTEXT_X64 *SystemContextX64; EFI_SYSTEM_CONTEXT_IPF *SystemContextIpf; EFI_SYSTEM_CONTEXT_ARM *SystemContextArm; EFI_SYSTEM_CONTEXT_AARCH64 *SystemContextAArch64; EFI_SYSTEM_CONTEXT_RISCV64 *SystemContextRiscV64; } EFI_SYSTEM_CONTEXT; // // DebugSupport callback function prototypes // /** Registers and enables an exception callback function for the specified exception. @param ExceptionType Exception types in EBC, IA-32, x64, or IPF. @param SystemContext Exception content. **/ typedef VOID (EFIAPI *EFI_EXCEPTION_CALLBACK)( IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext ); /** Registers and enables the on-target debug agent's periodic entry point. @param SystemContext Exception content. **/ typedef VOID (EFIAPI *EFI_PERIODIC_CALLBACK)( IN OUT EFI_SYSTEM_CONTEXT SystemContext ); /// /// Machine type definition /// typedef enum { IsaIa32 = IMAGE_FILE_MACHINE_I386, ///< 0x014C IsaX64 = IMAGE_FILE_MACHINE_X64, ///< 0x8664 IsaIpf = IMAGE_FILE_MACHINE_IA64, ///< 0x0200 IsaEbc = IMAGE_FILE_MACHINE_EBC, ///< 0x0EBC IsaArm = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED, ///< 0x01c2 IsaAArch64 = IMAGE_FILE_MACHINE_ARM64 ///< 0xAA64 } EFI_INSTRUCTION_SET_ARCHITECTURE; // // DebugSupport member function definitions // /** Returns the maximum value that may be used for the ProcessorIndex parameter in RegisterPeriodicCallback() and RegisterExceptionCallback(). @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported processor index is returned. @retval EFI_SUCCESS The function completed successfully. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_MAXIMUM_PROCESSOR_INDEX)( IN EFI_DEBUG_SUPPORT_PROTOCOL *This, OUT UINTN *MaxProcessorIndex ); /** Registers a function to be called back periodically in interrupt context. @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. @param ProcessorIndex Specifies which processor the callback function applies to. @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main periodic entry point of the debug agent. @retval EFI_SUCCESS The function completed successfully. @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback function was previously registered. @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback function. **/ typedef EFI_STATUS (EFIAPI *EFI_REGISTER_PERIODIC_CALLBACK)( IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN EFI_PERIODIC_CALLBACK PeriodicCallback ); /** Registers a function to be called when a given processor exception occurs. @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. @param ProcessorIndex Specifies which processor the callback function applies to. @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called when the processor exception specified by ExceptionType occurs. @param ExceptionType Specifies which processor exception to hook. @retval EFI_SUCCESS The function completed successfully. @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback function was previously registered. @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback function. **/ typedef EFI_STATUS (EFIAPI *EFI_REGISTER_EXCEPTION_CALLBACK)( IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN EFI_EXCEPTION_CALLBACK ExceptionCallback, IN EFI_EXCEPTION_TYPE ExceptionType ); /** Invalidates processor instruction cache for a memory range. Subsequent execution in this range causes a fresh memory fetch to retrieve code to be executed. @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. @param Start Specifies the physical base of the memory range to be invalidated. @param Length Specifies the minimum number of bytes in the processor's instruction cache to invalidate. @retval EFI_SUCCESS The function completed successfully. **/ typedef EFI_STATUS (EFIAPI *EFI_INVALIDATE_INSTRUCTION_CACHE)( IN EFI_DEBUG_SUPPORT_PROTOCOL *This, IN UINTN ProcessorIndex, IN VOID *Start, IN UINT64 Length ); /// /// This protocol provides the services to allow the debug agent to register /// callback functions that are called either periodically or when specific /// processor exceptions occur. /// struct _EFI_DEBUG_SUPPORT_PROTOCOL { /// /// Declares the processor architecture for this instance of the EFI Debug Support protocol. /// EFI_INSTRUCTION_SET_ARCHITECTURE Isa; EFI_GET_MAXIMUM_PROCESSOR_INDEX GetMaximumProcessorIndex; EFI_REGISTER_PERIODIC_CALLBACK RegisterPeriodicCallback; EFI_REGISTER_EXCEPTION_CALLBACK RegisterExceptionCallback; EFI_INVALIDATE_INSTRUCTION_CACHE InvalidateInstructionCache; }; extern EFI_GUID gEfiDebugSupportProtocolGuid; #endif /** @file The Decompress Protocol Interface as defined in UEFI spec Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DECOMPRESS_H__ #define __DECOMPRESS_H__ #define EFI_DECOMPRESS_PROTOCOL_GUID \ { \ 0xd8117cfe, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_DECOMPRESS_PROTOCOL EFI_DECOMPRESS_PROTOCOL; /** The GetInfo() function retrieves the size of the uncompressed buffer and the temporary scratch buffer required to decompress the buffer specified by Source and SourceSize. If the size of the uncompressed buffer or the size of the scratch buffer cannot be determined from the compressed data specified by Source and SourceData, then EFI_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed buffer is returned in DestinationSize, the size of the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned. The GetInfo() function does not have a scratch buffer available to perform a thorough checking of the validity of the source data. It just retrieves the 'Original Size' field from the beginning bytes of the source data and output it as DestinationSize. And ScratchSize is specific to the decompression implementation. @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. @param Source The source buffer containing the compressed data. @param SourceSize The size, in bytes, of source buffer. @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer that will be generated when the compressed buffer specified by Source and SourceSize is decompressed. @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that is required to decompress the compressed buffer specified by Source and SourceSize. @retval EFI_SUCCESS The size of the uncompressed data was returned in DestinationSize and the size of the scratch buffer was returned in ScratchSize. @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of the scratch buffer cannot be determined from the compressed data specified by Source and SourceData. **/ typedef EFI_STATUS (EFIAPI *EFI_DECOMPRESS_GET_INFO)( IN EFI_DECOMPRESS_PROTOCOL *This, IN VOID *Source, IN UINT32 SourceSize, OUT UINT32 *DestinationSize, OUT UINT32 *ScratchSize ); /** The Decompress() function extracts decompressed data to its original form. This protocol is designed so that the decompression algorithm can be implemented without using any memory services. As a result, the Decompress() function is not allowed to call AllocatePool() or AllocatePages() in its implementation. It is the caller's responsibility to allocate and free the Destination and Scratch buffers. If the compressed source data specified by Source and SourceSize is successfully decompressed into Destination, then EFI_SUCCESS is returned. If the compressed source data specified by Source and SourceSize is not in a valid compressed data format, then EFI_INVALID_PARAMETER is returned. @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. @param Source The source buffer containing the compressed data. @param SourceSize The size of source data. @param Destination On output, the destination buffer that contains the uncompressed data. @param DestinationSize The size of destination buffer. The size of destination buffer needed is obtained from GetInfo(). @param Scratch A temporary scratch buffer that is used to perform the decompression. @param ScratchSize The size of scratch buffer. The size of scratch buffer needed is obtained from GetInfo(). @retval EFI_SUCCESS Decompression completed successfully, and the uncompressed buffer is returned in Destination. @retval EFI_INVALID_PARAMETER The source buffer specified by Source and SourceSize is corrupted (not in a valid compressed format). **/ typedef EFI_STATUS (EFIAPI *EFI_DECOMPRESS_DECOMPRESS)( IN EFI_DECOMPRESS_PROTOCOL *This, IN VOID *Source, IN UINT32 SourceSize, IN OUT VOID *Destination, IN UINT32 DestinationSize, IN OUT VOID *Scratch, IN UINT32 ScratchSize ); /// /// Provides a decompression service. /// struct _EFI_DECOMPRESS_PROTOCOL { EFI_DECOMPRESS_GET_INFO GetInfo; EFI_DECOMPRESS_DECOMPRESS Decompress; }; extern EFI_GUID gEfiDecompressProtocolGuid; #endif /** @file Device IO protocol as defined in the EFI 1.10 specification. Device IO is used to abstract hardware access to devices. It includes memory mapped IO, IO, PCI Config space, and DMA. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEVICE_IO_H__ #define __DEVICE_IO_H__ #define EFI_DEVICE_IO_PROTOCOL_GUID \ { \ 0xaf6ac311, 0x84c3, 0x11d2, {0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } typedef struct _EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL; /// /// Protocol GUID name defined in EFI1.1. /// #define DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL_GUID /// /// Protocol defined in EFI1.1. /// typedef EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_INTERFACE; /// /// Device IO Access Width /// typedef enum { IO_UINT8 = 0, IO_UINT16 = 1, IO_UINT32 = 2, IO_UINT64 = 3, // // Below enumerations are added in "Extensible Firmware Interface Specification, // Version 1.10, Specification Update, Version 001". // MMIO_COPY_UINT8 = 4, MMIO_COPY_UINT16 = 5, MMIO_COPY_UINT32 = 6, MMIO_COPY_UINT64 = 7 } EFI_IO_WIDTH; /** Enables a driver to access device registers in the appropriate memory or I/O space. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param Width Signifies the width of the I/O operations. @param Address The base address of the I/O operations. @param Count The number of I/O operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. If Width is MMIO_COPY_UINT8, MMIO_COPY_UINT16, MMIO_COPY_UINT32, or MMIO_COPY_UINT64, then Buffer is interpreted as a base address of an I/O operation such as Address. @retval EFI_SUCCESS The data was read from or written to the device. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER Width is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_DEVICE_IO)( IN EFI_DEVICE_IO_PROTOCOL *This, IN EFI_IO_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer ); typedef struct { EFI_DEVICE_IO Read; EFI_DEVICE_IO Write; } EFI_IO_ACCESS; /** Provides an EFI Device Path for a PCI device with the given PCI configuration space address. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param PciAddress The PCI configuration space address of the device whose Device Path is going to be returned. @param PciDevicePath A pointer to the pointer for the EFI Device Path for PciAddress. Memory for the Device Path is allocated from the pool. @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI Device Path. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device Path. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_DEVICE_PATH)( IN EFI_DEVICE_IO_PROTOCOL *This, IN UINT64 PciAddress, IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath ); typedef enum { /// /// A read operation from system memory by a bus master. /// EfiBusMasterRead, /// /// A write operation to system memory by a bus master. /// EfiBusMasterWrite, /// /// Provides both read and write access to system memory /// by both the processor and a bus master. The buffer is /// coherent from both the processor's and the bus master's /// point of view. /// EfiBusMasterCommonBuffer } EFI_IO_OPERATION_TYPE; /** Provides the device-specific addresses needed to access system memory. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the device. @param NumberOfBytes On input, the number of bytes to map. On output, the number of bytes that were mapped. @param DeviceAddress The resulting map address for the bus master device to use to access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ typedef EFI_STATUS (EFIAPI *EFI_IO_MAP)( IN EFI_DEVICE_IO_PROTOCOL *This, IN EFI_IO_OPERATION_TYPE Operation, IN EFI_PHYSICAL_ADDRESS *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ); /** Completes the Map() operation and releases any corresponding resources. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ typedef EFI_STATUS (EFIAPI *EFI_IO_UNMAP)( IN EFI_DEVICE_IO_PROTOCOL *This, IN VOID *Mapping ); /** Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param Type The type allocation to perform. @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData. @param Pages The number of pages to allocate. @param HostAddress A pointer to store the base address of the allocated range. @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. @retval EFI_INVALID_PARAMETER The requested memory type is invalid. @retval EFI_UNSUPPORTED The requested HostAddress is not supported on this platform. **/ typedef EFI_STATUS (EFIAPI *EFI_IO_ALLOCATE_BUFFER)( IN EFI_DEVICE_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *HostAddress ); /** Flushes any posted write data to the device. @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @retval EFI_SUCCESS The buffers were flushed. @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_IO_FLUSH)( IN EFI_DEVICE_IO_PROTOCOL *This ); /** Frees pages that were allocated with AllocateBuffer(). @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. @param Pages The number of pages to free. @param HostAddress The base address of the range to free. @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_NOT_FOUND The requested memory pages were not allocated with AllocateBuffer(). @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_IO_FREE_BUFFER)( IN EFI_DEVICE_IO_PROTOCOL *This, IN UINTN Pages, IN EFI_PHYSICAL_ADDRESS HostAddress ); /// /// This protocol provides the basic Memory, I/O, and PCI interfaces that /// are used to abstract accesses to devices. /// struct _EFI_DEVICE_IO_PROTOCOL { /// /// Allows reads and writes to memory mapped I/O space. /// EFI_IO_ACCESS Mem; /// /// Allows reads and writes to I/O space. /// EFI_IO_ACCESS Io; /// /// Allows reads and writes to PCI configuration space. /// EFI_IO_ACCESS Pci; EFI_IO_MAP Map; EFI_PCI_DEVICE_PATH PciDevicePath; EFI_IO_UNMAP Unmap; EFI_IO_ALLOCATE_BUFFER AllocateBuffer; EFI_IO_FLUSH Flush; EFI_IO_FREE_BUFFER FreeBuffer; }; extern EFI_GUID gEfiDeviceIoProtocolGuid; #endif /** @file The device path protocol as defined in UEFI 2.0. The device path represents a programmatic path to a device, from a software point of view. The path must persist from boot to boot, so it can not contain things like PCI bus numbers that change from boot to boot. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DEVICE_PATH_PROTOCOL_H__ #define __EFI_DEVICE_PATH_PROTOCOL_H__ #include #include #include /// /// Device Path protocol. /// #define EFI_DEVICE_PATH_PROTOCOL_GUID \ { \ 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } /// /// Device Path guid definition for backward-compatible with EFI1.1. /// #define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID #pragma pack(1) /** This protocol can be used on any device handle to obtain generic path/location information concerning the physical device or logical device. If the handle does not logically map to a physical device, the handle may not necessarily support the device path protocol. The device path describes the location of the device the handle is for. The size of the Device Path can be determined from the structures that make up the Device Path. **/ typedef struct { UINT8 Type; ///< 0x01 Hardware Device Path. ///< 0x02 ACPI Device Path. ///< 0x03 Messaging Device Path. ///< 0x04 Media Device Path. ///< 0x05 BIOS Boot Specification Device Path. ///< 0x7F End of Hardware Device Path. UINT8 SubType; ///< Varies by Type ///< 0xFF End Entire Device Path, or ///< 0x01 End This Instance of a Device Path and start a new ///< Device Path. UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define ///< type of data. Size of data is included in Length. } EFI_DEVICE_PATH_PROTOCOL; /// /// Device Path protocol definition for backward-compatible with EFI1.1. /// typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; /// /// Hardware Device Paths. /// #define HARDWARE_DEVICE_PATH 0x01 /// /// PCI Device Path SubType. /// #define HW_PCI_DP 0x01 /// /// PCI Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// PCI Function Number. /// UINT8 Function; /// /// PCI Device Number. /// UINT8 Device; } PCI_DEVICE_PATH; /// /// PCCARD Device Path SubType. /// #define HW_PCCARD_DP 0x02 /// /// PCCARD Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Function Number (0 = First Function). /// UINT8 FunctionNumber; } PCCARD_DEVICE_PATH; /// /// Memory Mapped Device Path SubType. /// #define HW_MEMMAP_DP 0x03 /// /// Memory Mapped Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// EFI_MEMORY_TYPE /// UINT32 MemoryType; /// /// Starting Memory Address. /// EFI_PHYSICAL_ADDRESS StartingAddress; /// /// Ending Memory Address. /// EFI_PHYSICAL_ADDRESS EndingAddress; } MEMMAP_DEVICE_PATH; /// /// Hardware Vendor Device Path SubType. /// #define HW_VENDOR_DP 0x04 /// /// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must /// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the /// contents on the n bytes that follow in the Vendor Device Path node. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Vendor-assigned GUID that defines the data that follows. /// EFI_GUID Guid; /// /// Vendor-defined variable size data. /// } VENDOR_DEVICE_PATH; /// /// Controller Device Path SubType. /// #define HW_CONTROLLER_DP 0x05 /// /// Controller Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Controller number. /// UINT32 ControllerNumber; } CONTROLLER_DEVICE_PATH; /// /// BMC Device Path SubType. /// #define HW_BMC_DP 0x06 /// /// BMC Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Interface Type. /// UINT8 InterfaceType; /// /// Base Address. /// UINT8 BaseAddress[8]; } BMC_DEVICE_PATH; /// /// ACPI Device Paths. /// #define ACPI_DEVICE_PATH 0x02 /// /// ACPI Device Path SubType. /// #define ACPI_DP 0x01 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Device's PnP hardware ID stored in a numeric 32-bit /// compressed EISA-type ID. This value must match the /// corresponding _HID in the ACPI name space. /// UINT32 HID; /// /// Unique ID that is required by ACPI if two devices have the /// same _HID. This value must also match the corresponding /// _UID/_HID pair in the ACPI name space. Only the 32-bit /// numeric value type of _UID is supported. Thus, strings must /// not be used for the _UID in the ACPI name space. /// UINT32 UID; } ACPI_HID_DEVICE_PATH; /// /// Expanded ACPI Device Path SubType. /// #define ACPI_EXTENDED_DP 0x02 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Device's PnP hardware ID stored in a numeric 32-bit /// compressed EISA-type ID. This value must match the /// corresponding _HID in the ACPI name space. /// UINT32 HID; /// /// Unique ID that is required by ACPI if two devices have the /// same _HID. This value must also match the corresponding /// _UID/_HID pair in the ACPI name space. /// UINT32 UID; /// /// Device's compatible PnP hardware ID stored in a numeric /// 32-bit compressed EISA-type ID. This value must match at /// least one of the compatible device IDs returned by the /// corresponding _CID in the ACPI name space. /// UINT32 CID; /// /// Optional variable length _HIDSTR. /// Optional variable length _UIDSTR. /// Optional variable length _CIDSTR. /// } ACPI_EXTENDED_HID_DEVICE_PATH; // // EISA ID Macro // EISA ID Definition 32-bits // bits[15:0] - three character compressed ASCII EISA ID. // bits[31:16] - binary number // Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' // #define PNP_EISA_ID_CONST 0x41d0 #define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16)) #define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) #define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) #define PNP_EISA_ID_MASK 0xffff #define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) /// /// ACPI _ADR Device Path SubType. /// #define ACPI_ADR_DP 0x03 /// /// The _ADR device path is used to contain video output device attributes to support the Graphics /// Output Protocol. The device path can contain multiple _ADR entries if multiple video output /// devices are displaying the same output. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// _ADR value. For video output devices the value of this /// field comes from Table B-2 of the ACPI 3.0 specification. At /// least one _ADR value is required. /// UINT32 ADR; // // This device path may optionally contain more than one _ADR entry. // } ACPI_ADR_DEVICE_PATH; /// /// ACPI NVDIMM Device Path SubType. /// #define ACPI_NVDIMM_DP 0x04 /// /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// NFIT Device Handle, the _ADR of the NVDIMM device. /// The value of this field comes from Section 9.20.3 of the ACPI 6.2A specification. /// UINT32 NFITDeviceHandle; } ACPI_NVDIMM_DEVICE_PATH; #define ACPI_ADR_DISPLAY_TYPE_OTHER 0 #define ACPI_ADR_DISPLAY_TYPE_VGA 1 #define ACPI_ADR_DISPLAY_TYPE_TV 2 #define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3 #define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4 #define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \ ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \ (((_HeadId) & 0x7) << 18) | \ (((_NonVgaOutput) & 0x1) << 17) | \ (((_BiosCanDetect) & 0x1) << 16) | \ (((_VendorInfo) & 0xf) << 12) | \ (((_Type) & 0xf) << 8) | \ (((_Port) & 0xf) << 4) | \ ((_Index) & 0xf) )) /// /// Messaging Device Paths. /// This Device Path is used to describe the connection of devices outside the resource domain of the /// system. This Device Path can describe physical messaging information like SCSI ID, or abstract /// information like networking protocol IP addresses. /// #define MESSAGING_DEVICE_PATH 0x03 /// /// ATAPI Device Path SubType /// #define MSG_ATAPI_DP 0x01 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Set to zero for primary, or one for secondary. /// UINT8 PrimarySecondary; /// /// Set to zero for master, or one for slave mode. /// UINT8 SlaveMaster; /// /// Logical Unit Number. /// UINT16 Lun; } ATAPI_DEVICE_PATH; /// /// SCSI Device Path SubType. /// #define MSG_SCSI_DP 0x02 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Target ID on the SCSI bus (PUN). /// UINT16 Pun; /// /// Logical Unit Number (LUN). /// UINT16 Lun; } SCSI_DEVICE_PATH; /// /// Fibre Channel SubType. /// #define MSG_FIBRECHANNEL_DP 0x03 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Reserved for the future. /// UINT32 Reserved; /// /// Fibre Channel World Wide Number. /// UINT64 WWN; /// /// Fibre Channel Logical Unit Number. /// UINT64 Lun; } FIBRECHANNEL_DEVICE_PATH; /// /// Fibre Channel Ex SubType. /// #define MSG_FIBRECHANNELEX_DP 0x15 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Reserved for the future. /// UINT32 Reserved; /// /// 8 byte array containing Fibre Channel End Device Port Name. /// UINT8 WWN[8]; /// /// 8 byte array containing Fibre Channel Logical Unit Number. /// UINT8 Lun[8]; } FIBRECHANNELEX_DEVICE_PATH; /// /// 1394 Device Path SubType /// #define MSG_1394_DP 0x04 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Reserved for the future. /// UINT32 Reserved; /// /// 1394 Global Unique ID (GUID). /// UINT64 Guid; } F1394_DEVICE_PATH; /// /// USB Device Path SubType. /// #define MSG_USB_DP 0x05 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// USB Parent Port Number. /// UINT8 ParentPortNumber; /// /// USB Interface Number. /// UINT8 InterfaceNumber; } USB_DEVICE_PATH; /// /// USB Class Device Path SubType. /// #define MSG_USB_CLASS_DP 0x0f typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Vendor ID assigned by USB-IF. A value of 0xFFFF will /// match any Vendor ID. /// UINT16 VendorId; /// /// Product ID assigned by USB-IF. A value of 0xFFFF will /// match any Product ID. /// UINT16 ProductId; /// /// The class code assigned by the USB-IF. A value of 0xFF /// will match any class code. /// UINT8 DeviceClass; /// /// The subclass code assigned by the USB-IF. A value of /// 0xFF will match any subclass code. /// UINT8 DeviceSubClass; /// /// The protocol code assigned by the USB-IF. A value of /// 0xFF will match any protocol code. /// UINT8 DeviceProtocol; } USB_CLASS_DEVICE_PATH; /// /// USB WWID Device Path SubType. /// #define MSG_USB_WWID_DP 0x10 /// /// This device path describes a USB device using its serial number. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// USB interface number. /// UINT16 InterfaceNumber; /// /// USB vendor id of the device. /// UINT16 VendorId; /// /// USB product id of the device. /// UINT16 ProductId; /// /// Last 64-or-fewer UTF-16 characters of the USB /// serial number. The length of the string is /// determined by the Length field less the offset of the /// Serial Number field (10) /// /// CHAR16 SerialNumber[...]; } USB_WWID_DEVICE_PATH; /// /// Device Logical Unit SubType. /// #define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Logical Unit Number for the interface. /// UINT8 Lun; } DEVICE_LOGICAL_UNIT_DEVICE_PATH; /// /// SATA Device Path SubType. /// #define MSG_SATA_DP 0x12 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// The HBA port number that facilitates the connection to the /// device or a port multiplier. The value 0xFFFF is reserved. /// UINT16 HBAPortNumber; /// /// The Port multiplier port number that facilitates the connection /// to the device. Must be set to 0xFFFF if the device is directly /// connected to the HBA. /// UINT16 PortMultiplierPortNumber; /// /// Logical Unit Number. /// UINT16 Lun; } SATA_DEVICE_PATH; /// /// Flag for if the device is directly connected to the HBA. /// #define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000 /// /// I2O Device Path SubType. /// #define MSG_I2O_DP 0x06 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Target ID (TID) for a device. /// UINT32 Tid; } I2O_DEVICE_PATH; /// /// MAC Address Device Path SubType. /// #define MSG_MAC_ADDR_DP 0x0b typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// The MAC address for a network interface padded with 0s. /// EFI_MAC_ADDRESS MacAddress; /// /// Network interface type(i.e. 802.3, FDDI). /// UINT8 IfType; } MAC_ADDR_DEVICE_PATH; /// /// IPv4 Device Path SubType /// #define MSG_IPv4_DP 0x0c typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// The local IPv4 address. /// EFI_IPv4_ADDRESS LocalIpAddress; /// /// The remote IPv4 address. /// EFI_IPv4_ADDRESS RemoteIpAddress; /// /// The local port number. /// UINT16 LocalPort; /// /// The remote port number. /// UINT16 RemotePort; /// /// The network protocol(i.e. UDP, TCP). /// UINT16 Protocol; /// /// 0x00 - The Source IP Address was assigned though DHCP. /// 0x01 - The Source IP Address is statically bound. /// BOOLEAN StaticIpAddress; /// /// The gateway IP address /// EFI_IPv4_ADDRESS GatewayIpAddress; /// /// The subnet mask /// EFI_IPv4_ADDRESS SubnetMask; } IPv4_DEVICE_PATH; /// /// IPv6 Device Path SubType. /// #define MSG_IPv6_DP 0x0d typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// The local IPv6 address. /// EFI_IPv6_ADDRESS LocalIpAddress; /// /// The remote IPv6 address. /// EFI_IPv6_ADDRESS RemoteIpAddress; /// /// The local port number. /// UINT16 LocalPort; /// /// The remote port number. /// UINT16 RemotePort; /// /// The network protocol(i.e. UDP, TCP). /// UINT16 Protocol; /// /// 0x00 - The Local IP Address was manually configured. /// 0x01 - The Local IP Address is assigned through IPv6 /// stateless auto-configuration. /// 0x02 - The Local IP Address is assigned through IPv6 /// stateful configuration. /// UINT8 IpAddressOrigin; /// /// The prefix length /// UINT8 PrefixLength; /// /// The gateway IP address /// EFI_IPv6_ADDRESS GatewayIpAddress; } IPv6_DEVICE_PATH; /// /// InfiniBand Device Path SubType. /// #define MSG_INFINIBAND_DP 0x09 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Flags to help identify/manage InfiniBand device path elements: /// Bit 0 - IOC/Service (0b = IOC, 1b = Service). /// Bit 1 - Extend Boot Environment. /// Bit 2 - Console Protocol. /// Bit 3 - Storage Protocol. /// Bit 4 - Network Protocol. /// All other bits are reserved. /// UINT32 ResourceFlags; /// /// 128-bit Global Identifier for remote fabric port. /// UINT8 PortGid[16]; /// /// 64-bit unique identifier to remote IOC or server process. /// Interpretation of field specified by Resource Flags (bit 0). /// UINT64 ServiceId; /// /// 64-bit persistent ID of remote IOC port. /// UINT64 TargetPortId; /// /// 64-bit persistent ID of remote device. /// UINT64 DeviceId; } INFINIBAND_DEVICE_PATH; #define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 #define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02 #define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 #define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 #define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 /// /// UART Device Path SubType. /// #define MSG_UART_DP 0x0e typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Reserved. /// UINT32 Reserved; /// /// The baud rate setting for the UART style device. A value of 0 /// means that the device's default baud rate will be used. /// UINT64 BaudRate; /// /// The number of data bits for the UART style device. A value /// of 0 means that the device's default number of data bits will be used. /// UINT8 DataBits; /// /// The parity setting for the UART style device. /// Parity 0x00 - Default Parity. /// Parity 0x01 - No Parity. /// Parity 0x02 - Even Parity. /// Parity 0x03 - Odd Parity. /// Parity 0x04 - Mark Parity. /// Parity 0x05 - Space Parity. /// UINT8 Parity; /// /// The number of stop bits for the UART style device. /// Stop Bits 0x00 - Default Stop Bits. /// Stop Bits 0x01 - 1 Stop Bit. /// Stop Bits 0x02 - 1.5 Stop Bits. /// Stop Bits 0x03 - 2 Stop Bits. /// UINT8 StopBits; } UART_DEVICE_PATH; /// /// NVDIMM Namespace Device Path SubType. /// #define NVDIMM_NAMESPACE_DP 0x20 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Namespace unique label identifier UUID. /// EFI_GUID Uuid; } NVDIMM_NAMESPACE_DEVICE_PATH; // // Use VENDOR_DEVICE_PATH struct // #define MSG_VENDOR_DP 0x0a typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH; #define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID #define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID #define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID #define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID /// /// A new device path node is defined to declare flow control characteristics. /// UART Flow Control Messaging Device Path /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID. /// EFI_GUID Guid; /// /// Bitmap of supported flow control types. /// Bit 0 set indicates hardware flow control. /// Bit 1 set indicates Xon/Xoff flow control. /// All other bits are reserved and are clear. /// UINT32 FlowControlMap; } UART_FLOW_CONTROL_DEVICE_PATH; #define UART_FLOW_CONTROL_HARDWARE 0x00000001 #define UART_FLOW_CONTROL_XON_XOFF 0x00000010 #define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID /// /// Serial Attached SCSI (SAS) Device Path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// DEVICE_PATH_MESSAGING_SAS GUID. /// EFI_GUID Guid; /// /// Reserved for future use. /// UINT32 Reserved; /// /// SAS Address for Serial Attached SCSI Target. /// UINT64 SasAddress; /// /// SAS Logical Unit Number. /// UINT64 Lun; /// /// More Information about the device and its interconnect. /// UINT16 DeviceTopology; /// /// Relative Target Port (RTP). /// UINT16 RelativeTargetPort; } SAS_DEVICE_PATH; /// /// Serial Attached SCSI (SAS) Ex Device Path SubType /// #define MSG_SASEX_DP 0x16 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port. /// UINT8 SasAddress[8]; /// /// 8-byte array of the SAS Logical Unit Number. /// UINT8 Lun[8]; /// /// More Information about the device and its interconnect. /// UINT16 DeviceTopology; /// /// Relative Target Port (RTP). /// UINT16 RelativeTargetPort; } SASEX_DEVICE_PATH; /// /// NvmExpress Namespace Device Path SubType. /// #define MSG_NVME_NAMESPACE_DP 0x17 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; UINT32 NamespaceId; UINT64 NamespaceUuid; } NVME_NAMESPACE_DEVICE_PATH; /// /// DNS Device Path SubType /// #define MSG_DNS_DP 0x1F typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Indicates the DNS server address is IPv4 or IPv6 address. /// UINT8 IsIPv6; /// /// Instance of the DNS server address. /// EFI_IP_ADDRESS DnsServerIp[]; } DNS_DEVICE_PATH; /// /// Uniform Resource Identifiers (URI) Device Path SubType /// #define MSG_URI_DP 0x18 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Instance of the URI pursuant to RFC 3986. /// CHAR8 Uri[]; } URI_DEVICE_PATH; /// /// Universal Flash Storage (UFS) Device Path SubType. /// #define MSG_UFS_DP 0x19 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Target ID on the UFS bus (PUN). /// UINT8 Pun; /// /// Logical Unit Number (LUN). /// UINT8 Lun; } UFS_DEVICE_PATH; /// /// SD (Secure Digital) Device Path SubType. /// #define MSG_SD_DP 0x1A typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; UINT8 SlotNumber; } SD_DEVICE_PATH; /// /// EMMC (Embedded MMC) Device Path SubType. /// #define MSG_EMMC_DP 0x1D typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; UINT8 SlotNumber; } EMMC_DEVICE_PATH; /// /// iSCSI Device Path SubType /// #define MSG_ISCSI_DP 0x13 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Network Protocol (0 = TCP, 1+ = reserved). /// UINT16 NetworkProtocol; /// /// iSCSI Login Options. /// UINT16 LoginOption; /// /// iSCSI Logical Unit Number. /// UINT64 Lun; /// /// iSCSI Target Portal group tag the initiator intends /// to establish a session with. /// UINT16 TargetPortalGroupTag; /// /// iSCSI NodeTarget Name. The length of the name /// is determined by subtracting the offset of this field from Length. /// /// CHAR8 iSCSI Target Name. } ISCSI_DEVICE_PATH; #define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000 #define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002 #define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000 #define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008 #define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000 #define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000 #define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000 #define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000 /// /// VLAN Device Path SubType. /// #define MSG_VLAN_DP 0x14 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// VLAN identifier (0-4094). /// UINT16 VlanId; } VLAN_DEVICE_PATH; /// /// Bluetooth Device Path SubType. /// #define MSG_BLUETOOTH_DP 0x1b typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// 48bit Bluetooth device address. /// BLUETOOTH_ADDRESS BD_ADDR; } BLUETOOTH_DEVICE_PATH; /// /// Wi-Fi Device Path SubType. /// #define MSG_WIFI_DP 0x1C typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Service set identifier. A 32-byte octets string. /// UINT8 SSId[32]; } WIFI_DEVICE_PATH; /// /// Bluetooth LE Device Path SubType. /// #define MSG_BLUETOOTH_LE_DP 0x1E typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; BLUETOOTH_LE_ADDRESS Address; } BLUETOOTH_LE_DEVICE_PATH; // // Media Device Path // #define MEDIA_DEVICE_PATH 0x04 /// /// Hard Drive Media Device Path SubType. /// #define MEDIA_HARDDRIVE_DP 0x01 /// /// The Hard Drive Media Device Path is used to represent a partition on a hard drive. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Describes the entry in a partition table, starting with entry 1. /// Partition number zero represents the entire device. Valid /// partition numbers for a MBR partition are [1, 4]. Valid /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries]. /// UINT32 PartitionNumber; /// /// Starting LBA of the partition on the hard drive. /// UINT64 PartitionStart; /// /// Size of the partition in units of Logical Blocks. /// UINT64 PartitionSize; /// /// Signature unique to this partition: /// If SignatureType is 0, this field has to be initialized with 16 zeros. /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field. /// The other 12 bytes are initialized with zeros. /// If SignatureType is 2, this field contains a 16 byte signature. /// UINT8 Signature[16]; /// /// Partition Format: (Unused values reserved). /// 0x01 - PC-AT compatible legacy MBR. /// 0x02 - GUID Partition Table. /// UINT8 MBRType; /// /// Type of Disk Signature: (Unused values reserved). /// 0x00 - No Disk Signature. /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR. /// 0x02 - GUID signature. /// UINT8 SignatureType; } HARDDRIVE_DEVICE_PATH; #define MBR_TYPE_PCAT 0x01 #define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 #define NO_DISK_SIGNATURE 0x00 #define SIGNATURE_TYPE_MBR 0x01 #define SIGNATURE_TYPE_GUID 0x02 /// /// CD-ROM Media Device Path SubType. /// #define MEDIA_CDROM_DP 0x02 /// /// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero. /// UINT32 BootEntry; /// /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing. /// UINT64 PartitionStart; /// /// Size of the partition in units of Blocks, also called Sectors. /// UINT64 PartitionSize; } CDROM_DEVICE_PATH; // // Use VENDOR_DEVICE_PATH struct // #define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path subtype. /// /// File Path Media Device Path SubType /// #define MEDIA_FILEPATH_DP 0x04 typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// A NULL-terminated Path string including directory and file names. /// CHAR16 PathName[1]; } FILEPATH_DEVICE_PATH; #define SIZE_OF_FILEPATH_DEVICE_PATH OFFSET_OF(FILEPATH_DEVICE_PATH,PathName) /// /// Media Protocol Device Path SubType. /// #define MEDIA_PROTOCOL_DP 0x05 /// /// The Media Protocol Device Path is used to denote the protocol that is being /// used in a device path at the location of the path specified. /// Many protocols are inherent to the style of device path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// The ID of the protocol. /// EFI_GUID Protocol; } MEDIA_PROTOCOL_DEVICE_PATH; /// /// PIWG Firmware File SubType. /// #define MEDIA_PIWG_FW_FILE_DP 0x06 /// /// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Firmware file name /// EFI_GUID FvFileName; } MEDIA_FW_VOL_FILEPATH_DEVICE_PATH; /// /// PIWG Firmware Volume Device Path SubType. /// #define MEDIA_PIWG_FW_VOL_DP 0x07 /// /// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Firmware volume name. /// EFI_GUID FvName; } MEDIA_FW_VOL_DEVICE_PATH; /// /// Media relative offset range device path. /// #define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08 /// /// Used to describe the offset range of media relative. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; UINT32 Reserved; UINT64 StartingOffset; UINT64 EndingOffset; } MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH; /// /// This GUID defines a RAM Disk supporting a raw disk format in volatile memory. /// #define EFI_VIRTUAL_DISK_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE extern EFI_GUID gEfiVirtualDiskGuid; /// /// This GUID defines a RAM Disk supporting an ISO image in volatile memory. /// #define EFI_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE extern EFI_GUID gEfiVirtualCdGuid; /// /// This GUID defines a RAM Disk supporting a raw disk format in persistent memory. /// #define EFI_PERSISTENT_VIRTUAL_DISK_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT extern EFI_GUID gEfiPersistentVirtualDiskGuid; /// /// This GUID defines a RAM Disk supporting an ISO image in persistent memory. /// #define EFI_PERSISTENT_VIRTUAL_CD_GUID EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT extern EFI_GUID gEfiPersistentVirtualCdGuid; /// /// Media ram disk device path. /// #define MEDIA_RAM_DISK_DP 0x09 /// /// Used to describe the ram disk device path. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Starting Memory Address. /// UINT32 StartingAddr[2]; /// /// Ending Memory Address. /// UINT32 EndingAddr[2]; /// /// GUID that defines the type of the RAM Disk. /// EFI_GUID TypeGuid; /// /// RAM Diskinstance number, if supported. The default value is zero. /// UINT16 Instance; } MEDIA_RAM_DISK_DEVICE_PATH; /// /// BIOS Boot Specification Device Path. /// #define BBS_DEVICE_PATH 0x05 /// /// BIOS Boot Specification Device Path SubType. /// #define BBS_BBS_DP 0x01 /// /// This Device Path is used to describe the booting of non-EFI-aware operating systems. /// typedef struct { EFI_DEVICE_PATH_PROTOCOL Header; /// /// Device Type as defined by the BIOS Boot Specification. /// UINT16 DeviceType; /// /// Status Flags as defined by the BIOS Boot Specification. /// UINT16 StatusFlag; /// /// Null-terminated ASCII string that describes the boot device to a user. /// CHAR8 String[1]; } BBS_BBS_DEVICE_PATH; // // DeviceType definitions - from BBS specification // #define BBS_TYPE_FLOPPY 0x01 #define BBS_TYPE_HARDDRIVE 0x02 #define BBS_TYPE_CDROM 0x03 #define BBS_TYPE_PCMCIA 0x04 #define BBS_TYPE_USB 0x05 #define BBS_TYPE_EMBEDDED_NETWORK 0x06 #define BBS_TYPE_BEV 0x80 #define BBS_TYPE_UNKNOWN 0xFF /// /// Union of all possible Device Paths and pointers to Device Paths. /// typedef union { EFI_DEVICE_PATH_PROTOCOL DevPath; PCI_DEVICE_PATH Pci; PCCARD_DEVICE_PATH PcCard; MEMMAP_DEVICE_PATH MemMap; VENDOR_DEVICE_PATH Vendor; CONTROLLER_DEVICE_PATH Controller; BMC_DEVICE_PATH Bmc; ACPI_HID_DEVICE_PATH Acpi; ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi; ACPI_ADR_DEVICE_PATH AcpiAdr; ATAPI_DEVICE_PATH Atapi; SCSI_DEVICE_PATH Scsi; ISCSI_DEVICE_PATH Iscsi; FIBRECHANNEL_DEVICE_PATH FibreChannel; FIBRECHANNELEX_DEVICE_PATH FibreChannelEx; F1394_DEVICE_PATH F1394; USB_DEVICE_PATH Usb; SATA_DEVICE_PATH Sata; USB_CLASS_DEVICE_PATH UsbClass; USB_WWID_DEVICE_PATH UsbWwid; DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit; I2O_DEVICE_PATH I2O; MAC_ADDR_DEVICE_PATH MacAddr; IPv4_DEVICE_PATH Ipv4; IPv6_DEVICE_PATH Ipv6; VLAN_DEVICE_PATH Vlan; INFINIBAND_DEVICE_PATH InfiniBand; UART_DEVICE_PATH Uart; UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl; SAS_DEVICE_PATH Sas; SASEX_DEVICE_PATH SasEx; NVME_NAMESPACE_DEVICE_PATH NvmeNamespace; DNS_DEVICE_PATH Dns; URI_DEVICE_PATH Uri; BLUETOOTH_DEVICE_PATH Bluetooth; WIFI_DEVICE_PATH WiFi; UFS_DEVICE_PATH Ufs; SD_DEVICE_PATH Sd; EMMC_DEVICE_PATH Emmc; HARDDRIVE_DEVICE_PATH HardDrive; CDROM_DEVICE_PATH CD; FILEPATH_DEVICE_PATH FilePath; MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile; MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset; MEDIA_RAM_DISK_DEVICE_PATH RamDisk; BBS_BBS_DEVICE_PATH Bbs; } EFI_DEV_PATH; typedef union { EFI_DEVICE_PATH_PROTOCOL *DevPath; PCI_DEVICE_PATH *Pci; PCCARD_DEVICE_PATH *PcCard; MEMMAP_DEVICE_PATH *MemMap; VENDOR_DEVICE_PATH *Vendor; CONTROLLER_DEVICE_PATH *Controller; BMC_DEVICE_PATH *Bmc; ACPI_HID_DEVICE_PATH *Acpi; ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; ACPI_ADR_DEVICE_PATH *AcpiAdr; ATAPI_DEVICE_PATH *Atapi; SCSI_DEVICE_PATH *Scsi; ISCSI_DEVICE_PATH *Iscsi; FIBRECHANNEL_DEVICE_PATH *FibreChannel; FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx; F1394_DEVICE_PATH *F1394; USB_DEVICE_PATH *Usb; SATA_DEVICE_PATH *Sata; USB_CLASS_DEVICE_PATH *UsbClass; USB_WWID_DEVICE_PATH *UsbWwid; DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit; I2O_DEVICE_PATH *I2O; MAC_ADDR_DEVICE_PATH *MacAddr; IPv4_DEVICE_PATH *Ipv4; IPv6_DEVICE_PATH *Ipv6; VLAN_DEVICE_PATH *Vlan; INFINIBAND_DEVICE_PATH *InfiniBand; UART_DEVICE_PATH *Uart; UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; SAS_DEVICE_PATH *Sas; SASEX_DEVICE_PATH *SasEx; NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace; DNS_DEVICE_PATH *Dns; URI_DEVICE_PATH *Uri; BLUETOOTH_DEVICE_PATH *Bluetooth; WIFI_DEVICE_PATH *WiFi; UFS_DEVICE_PATH *Ufs; SD_DEVICE_PATH *Sd; EMMC_DEVICE_PATH *Emmc; HARDDRIVE_DEVICE_PATH *HardDrive; CDROM_DEVICE_PATH *CD; FILEPATH_DEVICE_PATH *FilePath; MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile; MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; BBS_BBS_DEVICE_PATH *Bbs; UINT8 *Raw; } EFI_DEV_PATH_PTR; #pragma pack() #define END_DEVICE_PATH_TYPE 0x7f #define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF #define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 extern EFI_GUID gEfiDevicePathProtocolGuid; #endif /** @file EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0. This protocol provides service to convert text to device paths and device nodes. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__ #define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__ /// /// Device Path From Text protocol /// #define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ { \ 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \ } /** Convert text to the binary representation of a device node. @param TextDeviceNode TextDeviceNode points to the text representation of a device node. Conversion starts with the first character and continues until the first non-device node character. @retval a_pointer Pointer to the EFI device node. @retval NULL if TextDeviceNode is NULL or there was insufficient memory. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE)( IN CONST CHAR16 *TextDeviceNode ); /** Convert text to the binary representation of a device node. @param TextDeviceNode TextDevicePath points to the text representation of a device path. Conversion starts with the first character and continues until the first non-device path character. @retval a_pointer Pointer to the allocated device path. @retval NULL if TextDeviceNode is NULL or there was insufficient memory. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH)( IN CONST CHAR16 *TextDevicePath ); /// /// This protocol converts text to device paths and device nodes. /// typedef struct { EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode; EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath; } EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL; extern EFI_GUID gEfiDevicePathFromTextProtocolGuid; #endif /** @file EFI_DEVICE_PATH_TO_TEXT_PROTOCOL as defined in UEFI 2.0. This protocol provides service to convert device nodes and paths to text. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEVICE_PATH_TO_TEXT_PROTOCOL_H__ #define __DEVICE_PATH_TO_TEXT_PROTOCOL_H__ /// /// Device Path To Text protocol /// #define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ { \ 0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ } /** Convert a device node to its text representation. @param DeviceNode Points to the device node to be converted. @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation of the display node is used, where applicable. If DisplayOnly is FALSE, then the longer text representation of the display node is used. @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text representation for a device node can be used, where applicable. @retval a_pointer a pointer to the allocated text representation of the device node data @retval NULL if DeviceNode is NULL or there was insufficient memory. **/ typedef CHAR16 * (EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts ); /** Convert a device path to its text representation. @param DevicePath Points to the device path to be converted. @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation of the display node is used, where applicable. If DisplayOnly is FALSE, then the longer text representation of the display node is used. @param AllowShortcuts The AllowShortcuts is FALSE, then the shortcut forms of text representation for a device node cannot be used. @retval a_pointer a pointer to the allocated text representation of the device node. @retval NULL if DevicePath is NULL or there was insufficient memory. **/ typedef CHAR16 * (EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts ); /// /// This protocol converts device paths and device nodes to text. /// typedef struct { EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText; EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; } EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; extern EFI_GUID gEfiDevicePathToTextProtocolGuid; #endif /** @file EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0. Use to create and manipulate device paths and device nodes. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DEVICE_PATH_UTILITIES_PROTOCOL_H__ #define __DEVICE_PATH_UTILITIES_PROTOCOL_H__ /// /// Device Path Utilities protocol /// #define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ { \ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ } /** Returns the size of the device path, in bytes. @param DevicePath Points to the start of the EFI device path. @return Size Size of the specified device path, in bytes, including the end-of-path tag. @retval 0 DevicePath is NULL **/ typedef UINTN (EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ); /** Create a duplicate of the specified path. @param DevicePath Points to the source EFI device path. @retval Pointer A pointer to the duplicate device path. @retval NULL insufficient memory or DevicePath is NULL **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ); /** Create a new path by appending the second device path to the first. If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned. If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned. If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned. @param Src1 Points to the first device path. @param Src2 Points to the second device path. @retval Pointer A pointer to the newly created device path. @retval NULL Memory could not be allocated **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH)( IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1, IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2 ); /** Creates a new path by appending the device node to the device path. If DeviceNode is NULL then a copy of DevicePath is returned. If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned. If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned. @param DevicePath Points to the device path. @param DeviceNode Points to the device node. @retval Pointer A pointer to the allocated device node. @retval NULL There was insufficient memory. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode ); /** Creates a new path by appending the specified device path instance to the specified device path. @param DevicePath Points to the device path. If NULL, then ignored. @param DevicePathInstance Points to the device path instance. @retval Pointer A pointer to the newly created device path @retval NULL Memory could not be allocated or DevicePathInstance is NULL. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance ); /** Creates a copy of the current device path instance and returns a pointer to the next device path instance. @param DevicePathInstance On input, this holds the pointer to the current device path instance. On output, this holds the pointer to the next device path instance or NULL if there are no more device path instances in the device path. @param DevicePathInstanceSize On output, this holds the size of the device path instance, in bytes or zero, if DevicePathInstance is NULL. If NULL, then the instance size is not output. @retval Pointer A pointer to the copy of the current device path instance. @retval NULL DevicePathInstace was NULL on entry or there was insufficient memory. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance, OUT UINTN *DevicePathInstanceSize ); /** Creates a device node @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for the new device node. @param NodeSubType NodeSubType is the device node sub-type EFI_DEVICE_PATH.SubType) for the new device node. @param NodeLength NodeLength is the length of the device node (EFI_DEVICE_PATH.Length) for the new device node. @retval Pointer A pointer to the newly created device node. @retval NULL NodeLength is less than the size of the header or there was insufficient memory. **/ typedef EFI_DEVICE_PATH_PROTOCOL * (EFIAPI *EFI_DEVICE_PATH_UTILS_CREATE_NODE)( IN UINT8 NodeType, IN UINT8 NodeSubType, IN UINT16 NodeLength ); /** Returns whether a device path is multi-instance. @param DevicePath Points to the device path. If NULL, then ignored. @retval TRUE The device path has more than one instance @retval FALSE The device path is empty or contains only a single instance. **/ typedef BOOLEAN (EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ); /// /// This protocol is used to creates and manipulates device paths and device nodes. /// typedef struct { EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize; EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath; EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath; EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode; EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance; EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance; EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance; EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode; } EFI_DEVICE_PATH_UTILITIES_PROTOCOL; extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; #endif /** @file EFI_DHCP4_PROTOCOL as defined in UEFI 2.0. EFI_DHCP4_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0. These protocols are used to collect configuration information for the EFI IPv4 Protocol drivers and to provide DHCPv4 server and PXE boot server discovery services. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.0. **/ #ifndef __EFI_DHCP4_PROTOCOL_H__ #define __EFI_DHCP4_PROTOCOL_H__ #define EFI_DHCP4_PROTOCOL_GUID \ { \ 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56 } \ } #define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80 } \ } typedef struct _EFI_DHCP4_PROTOCOL EFI_DHCP4_PROTOCOL; #pragma pack(1) typedef struct { /// /// DHCP option code. /// UINT8 OpCode; /// /// Length of the DHCP option data. Not present if OpCode is 0 or 255. /// UINT8 Length; /// /// Start of the DHCP option data. Not present if OpCode is 0 or 255 or if Length is zero. /// UINT8 Data[1]; } EFI_DHCP4_PACKET_OPTION; #pragma pack() #pragma pack(1) /// /// EFI_DHCP4_PACKET defines the format of DHCPv4 packets. See RFC 2131 for more information. /// typedef struct { UINT8 OpCode; UINT8 HwType; UINT8 HwAddrLen; UINT8 Hops; UINT32 Xid; UINT16 Seconds; UINT16 Reserved; EFI_IPv4_ADDRESS ClientAddr; ///< Client IP address from client. EFI_IPv4_ADDRESS YourAddr; ///< Client IP address from server. EFI_IPv4_ADDRESS ServerAddr; ///< IP address of next server in bootstrap. EFI_IPv4_ADDRESS GatewayAddr; ///< Relay agent IP address. UINT8 ClientHwAddr[16]; ///< Client hardware address. CHAR8 ServerName[64]; CHAR8 BootFileName[128]; } EFI_DHCP4_HEADER; #pragma pack() #pragma pack(1) typedef struct { /// /// Size of the EFI_DHCP4_PACKET buffer. /// UINT32 Size; /// /// Length of the EFI_DHCP4_PACKET from the first byte of the Header field /// to the last byte of the Option[] field. /// UINT32 Length; struct { /// /// DHCP packet header. /// EFI_DHCP4_HEADER Header; /// /// DHCP magik cookie in network byte order. /// UINT32 Magik; /// /// Start of the DHCP packed option data. /// UINT8 Option[1]; } Dhcp4; } EFI_DHCP4_PACKET; #pragma pack() typedef enum { /// /// The EFI DHCPv4 Protocol driver is stopped. /// Dhcp4Stopped = 0x0, /// /// The EFI DHCPv4 Protocol driver is inactive. /// Dhcp4Init = 0x1, /// /// The EFI DHCPv4 Protocol driver is collecting DHCP offer packets from DHCP servers. /// Dhcp4Selecting = 0x2, /// /// The EFI DHCPv4 Protocol driver has sent the request to the DHCP server and is waiting for a response. /// Dhcp4Requesting = 0x3, /// /// The DHCP configuration has completed. /// Dhcp4Bound = 0x4, /// /// The DHCP configuration is being renewed and another request has /// been sent out, but it has not received a response from the server yet. /// Dhcp4Renewing = 0x5, /// /// The DHCP configuration has timed out and the EFI DHCPv4 /// Protocol driver is trying to extend the lease time. /// Dhcp4Rebinding = 0x6, /// /// The EFI DHCPv4 Protocol driver was initialized with a previously /// allocated or known IP address. /// Dhcp4InitReboot = 0x7, /// /// The EFI DHCPv4 Protocol driver is seeking to reuse the previously /// allocated IP address by sending a request to the DHCP server. /// Dhcp4Rebooting = 0x8 } EFI_DHCP4_STATE; typedef enum { /// /// The packet to start the configuration sequence is about to be sent. /// Dhcp4SendDiscover = 0x01, /// /// A reply packet was just received. /// Dhcp4RcvdOffer = 0x02, /// /// It is time for Dhcp4Callback to select an offer. /// Dhcp4SelectOffer = 0x03, /// /// A request packet is about to be sent. /// Dhcp4SendRequest = 0x04, /// /// A DHCPACK packet was received and will be passed to Dhcp4Callback. /// Dhcp4RcvdAck = 0x05, /// /// A DHCPNAK packet was received and will be passed to Dhcp4Callback. /// Dhcp4RcvdNak = 0x06, /// /// A decline packet is about to be sent. /// Dhcp4SendDecline = 0x07, /// /// The DHCP configuration process has completed. No packet is associated with this event. /// Dhcp4BoundCompleted = 0x08, /// /// It is time to enter the Dhcp4Renewing state and to contact the server /// that originally issued the network address. No packet is associated with this event. /// Dhcp4EnterRenewing = 0x09, /// /// It is time to enter the Dhcp4Rebinding state and to contact any server. /// No packet is associated with this event. /// Dhcp4EnterRebinding = 0x0a, /// /// The configured IP address was lost either because the lease has expired, /// the user released the configuration, or a DHCPNAK packet was received in /// the Dhcp4Renewing or Dhcp4Rebinding state. No packet is associated with this event. /// Dhcp4AddressLost = 0x0b, /// /// The DHCP process failed because a DHCPNAK packet was received or the user /// aborted the DHCP process at a time when the configuration was not available yet. /// No packet is associated with this event. /// Dhcp4Fail = 0x0c } EFI_DHCP4_EVENT; /** Callback routine. EFI_DHCP4_CALLBACK is provided by the consumer of the EFI DHCPv4 Protocol driver to intercept events that occurred in the configuration process. This structure provides advanced control of each state transition of the DHCP process. The returned status code determines the behavior of the EFI DHCPv4 Protocol driver. There are three possible returned values, which are described in the following table. @param This The pointer to the EFI DHCPv4 Protocol instance that is used to configure this callback function. @param Context The pointer to the context that is initialized by EFI_DHCP4_PROTOCOL.Configure(). @param CurrentState The current operational state of the EFI DHCPv4 Protocol driver. @param Dhcp4Event The event that occurs in the current state, which usually means a state transition. @param Packet The DHCP packet that is going to be sent or already received. @param NewPacket The packet that is used to replace the above Packet. @retval EFI_SUCCESS Tells the EFI DHCPv4 Protocol driver to continue the DHCP process. When it is in the Dhcp4Selecting state, it tells the EFI DHCPv4 Protocol driver to stop collecting additional packets. The driver will exit the Dhcp4Selecting state and enter the Dhcp4Requesting state. @retval EFI_NOT_READY Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol driver will continue to wait for more packets until the retry timeout expires. @retval EFI_ABORTED Tells the EFI DHCPv4 Protocol driver to abort the current process and return to the Dhcp4Init or Dhcp4InitReboot state. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_CALLBACK)( IN EFI_DHCP4_PROTOCOL *This, IN VOID *Context, IN EFI_DHCP4_STATE CurrentState, IN EFI_DHCP4_EVENT Dhcp4Event, IN EFI_DHCP4_PACKET *Packet OPTIONAL, OUT EFI_DHCP4_PACKET **NewPacket OPTIONAL ); typedef struct { /// /// The number of times to try sending a packet during the Dhcp4SendDiscover /// event and waiting for a response during the Dhcp4RcvdOffer event. /// Set to zero to use the default try counts and timeout values. /// UINT32 DiscoverTryCount; /// /// The maximum amount of time (in seconds) to wait for returned packets in each /// of the retries. Timeout values of zero will default to a timeout value /// of one second. Set to NULL to use default timeout values. /// UINT32 *DiscoverTimeout; /// /// The number of times to try sending a packet during the Dhcp4SendRequest event /// and waiting for a response during the Dhcp4RcvdAck event before accepting /// failure. Set to zero to use the default try counts and timeout values. /// UINT32 RequestTryCount; /// /// The maximum amount of time (in seconds) to wait for return packets in each of the retries. /// Timeout values of zero will default to a timeout value of one second. /// Set to NULL to use default timeout values. /// UINT32 *RequestTimeout; /// /// For a DHCPDISCOVER, setting this parameter to the previously allocated IP /// address will cause the EFI DHCPv4 Protocol driver to enter the Dhcp4InitReboot state. /// And set this field to 0.0.0.0 to enter the Dhcp4Init state. /// For a DHCPINFORM this parameter should be set to the client network address /// which was assigned to the client during a DHCPDISCOVER. /// EFI_IPv4_ADDRESS ClientAddress; /// /// The callback function to intercept various events that occurred in /// the DHCP configuration process. Set to NULL to ignore all those events. /// EFI_DHCP4_CALLBACK Dhcp4Callback; /// /// The pointer to the context that will be passed to Dhcp4Callback when it is called. /// VOID *CallbackContext; /// /// Number of DHCP options in the OptionList. /// UINT32 OptionCount; /// /// List of DHCP options to be included in every packet that is sent during the /// Dhcp4SendDiscover event. Pad options are appended automatically by DHCP driver /// in outgoing DHCP packets. If OptionList itself contains pad option, they are /// ignored by the driver. OptionList can be freed after EFI_DHCP4_PROTOCOL.Configure() /// returns. Ignored if OptionCount is zero. /// EFI_DHCP4_PACKET_OPTION **OptionList; } EFI_DHCP4_CONFIG_DATA; typedef struct { /// /// The EFI DHCPv4 Protocol driver operating state. /// EFI_DHCP4_STATE State; /// /// The configuration data of the current EFI DHCPv4 Protocol driver instance. /// EFI_DHCP4_CONFIG_DATA ConfigData; /// /// The client IP address that was acquired from the DHCP server. If it is zero, /// the DHCP acquisition has not completed yet and the following fields in this structure are undefined. /// EFI_IPv4_ADDRESS ClientAddress; /// /// The local hardware address. /// EFI_MAC_ADDRESS ClientMacAddress; /// /// The server IP address that is providing the DHCP service to this client. /// EFI_IPv4_ADDRESS ServerAddress; /// /// The router IP address that was acquired from the DHCP server. /// May be zero if the server does not offer this address. /// EFI_IPv4_ADDRESS RouterAddress; /// /// The subnet mask of the connected network that was acquired from the DHCP server. /// EFI_IPv4_ADDRESS SubnetMask; /// /// The lease time (in 1-second units) of the configured IP address. /// The value 0xFFFFFFFF means that the lease time is infinite. /// A default lease of 7 days is used if the DHCP server does not provide a value. /// UINT32 LeaseTime; /// /// The cached latest DHCPACK or DHCPNAK or BOOTP REPLY packet. May be NULL if no packet is cached. /// EFI_DHCP4_PACKET *ReplyPacket; } EFI_DHCP4_MODE_DATA; typedef struct { /// /// Alternate listening address. It can be a unicast, multicast, or broadcast address. /// EFI_IPv4_ADDRESS ListenAddress; /// /// The subnet mask of above listening unicast/broadcast IP address. /// Ignored if ListenAddress is a multicast address. /// EFI_IPv4_ADDRESS SubnetMask; /// /// Alternate station source (or listening) port number. /// If zero, then the default station port number (68) will be used. /// UINT16 ListenPort; } EFI_DHCP4_LISTEN_POINT; typedef struct { /// /// The completion status of transmitting and receiving. /// EFI_STATUS Status; /// /// If not NULL, the event that will be signaled when the collection process /// completes. If NULL, this function will busy-wait until the collection process competes. /// EFI_EVENT CompletionEvent; /// /// The pointer to the server IP address. This address may be a unicast, multicast, or broadcast address. /// EFI_IPv4_ADDRESS RemoteAddress; /// /// The server listening port number. If zero, the default server listening port number (67) will be used. /// UINT16 RemotePort; /// /// The pointer to the gateway address to override the existing setting. /// EFI_IPv4_ADDRESS GatewayAddress; /// /// The number of entries in ListenPoints. If zero, the default station address and port number 68 are used. /// UINT32 ListenPointCount; /// /// An array of station address and port number pairs that are used as receiving filters. /// The first entry is also used as the source address and source port of the outgoing packet. /// EFI_DHCP4_LISTEN_POINT *ListenPoints; /// /// The number of seconds to collect responses. Zero is invalid. /// UINT32 TimeoutValue; /// /// The pointer to the packet to be transmitted. /// EFI_DHCP4_PACKET *Packet; /// /// Number of received packets. /// UINT32 ResponseCount; /// /// The pointer to the allocated list of received packets. /// EFI_DHCP4_PACKET *ResponseList; } EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN; /** Returns the current operating mode and cached data packet for the EFI DHCPv4 Protocol driver. The GetModeData() function returns the current operating mode and cached data packet for the EFI DHCPv4 Protocol driver. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param Dhcp4ModeData The pointer to storage for the EFI_DHCP4_MODE_DATA structure. @retval EFI_SUCCESS The mode data was returned. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_GET_MODE_DATA)( IN EFI_DHCP4_PROTOCOL *This, OUT EFI_DHCP4_MODE_DATA *Dhcp4ModeData ); /** Initializes, changes, or resets the operational settings for the EFI DHCPv4 Protocol driver. The Configure() function is used to initialize, change, or reset the operational settings of the EFI DHCPv4 Protocol driver for the communication device on which the EFI DHCPv4 Service Binding Protocol is installed. This function can be successfully called only if both of the following are true: * This instance of the EFI DHCPv4 Protocol driver is in the Dhcp4Stopped, Dhcp4Init, Dhcp4InitReboot, or Dhcp4Bound states. * No other EFI DHCPv4 Protocol driver instance that is controlled by this EFI DHCPv4 Service Binding Protocol driver instance has configured this EFI DHCPv4 Protocol driver. When this driver is in the Dhcp4Stopped state, it can transfer into one of the following two possible initial states: * Dhcp4Init * Dhcp4InitReboot. The driver can transfer into these states by calling Configure() with a non-NULL Dhcp4CfgData. The driver will transfer into the appropriate state based on the supplied client network address in the ClientAddress parameter and DHCP options in the OptionList parameter as described in RFC 2131. When Configure() is called successfully while Dhcp4CfgData is set to NULL, the default configuring data will be reset in the EFI DHCPv4 Protocol driver and the state of the EFI DHCPv4 Protocol driver will not be changed. If one instance wants to make it possible for another instance to configure the EFI DHCPv4 Protocol driver, it must call this function with Dhcp4CfgData set to NULL. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param Dhcp4CfgData The pointer to the EFI_DHCP4_CONFIG_DATA. @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Init or Dhcp4InitReboot state, if the original state of this driver was Dhcp4Stopped, Dhcp4Init,Dhcp4InitReboot, or Dhcp4Bound and the value of Dhcp4CfgData was not NULL. Otherwise, the state was left unchanged. @retval EFI_ACCESS_DENIED This instance of the EFI DHCPv4 Protocol driver was not in the Dhcp4Stopped, Dhcp4Init, Dhcp4InitReboot, or Dhcp4Bound state; Or onother instance of this EFI DHCPv4 Protocol driver is already in a valid configured state. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: This is NULL. DiscoverTryCount > 0 and DiscoverTimeout is NULL RequestTryCount > 0 and RequestTimeout is NULL. OptionCount >0 and OptionList is NULL. ClientAddress is not a valid unicast address. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_CONFIGURE)( IN EFI_DHCP4_PROTOCOL *This, IN EFI_DHCP4_CONFIG_DATA *Dhcp4CfgData OPTIONAL ); /** Starts the DHCP configuration process. The Start() function starts the DHCP configuration process. This function can be called only when the EFI DHCPv4 Protocol driver is in the Dhcp4Init or Dhcp4InitReboot state. If the DHCP process completes successfully, the state of the EFI DHCPv4 Protocol driver will be transferred through Dhcp4Selecting and Dhcp4Requesting to the Dhcp4Bound state. The CompletionEvent will then be signaled if it is not NULL. If the process aborts, either by the user or by some unexpected network error, the state is restored to the Dhcp4Init state. The Start() function can be called again to restart the process. Refer to RFC 2131 for precise state transitions during this process. At the time when each event occurs in this process, the callback function that was set by EFI_DHCP4_PROTOCOL.Configure() will be called and the user can take this opportunity to control the process. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param CompletionEvent If not NULL, it indicates the event that will be signaled when the EFI DHCPv4 Protocol driver is transferred into the Dhcp4Bound state or when the DHCP process is aborted. EFI_DHCP4_PROTOCOL.GetModeData() can be called to check the completion status. If NULL, EFI_DHCP4_PROTOCOL.Start() will wait until the driver is transferred into the Dhcp4Bound state or the process fails. @retval EFI_SUCCESS The DHCP configuration process has started, or it has completed when CompletionEvent is NULL. @retval EFI_NOT_STARTED The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped state. EFI_DHCP4_PROTOCOL. Configure() needs to be called. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_TIMEOUT The DHCP configuration process failed because no response was received from the server within the specified timeout value. @retval EFI_ABORTED The user aborted the DHCP process. @retval EFI_ALREADY_STARTED Some other EFI DHCPv4 Protocol instance already started the DHCP process. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_START)( IN EFI_DHCP4_PROTOCOL *This, IN EFI_EVENT CompletionEvent OPTIONAL ); /** Extends the lease time by sending a request packet. The RenewRebind() function is used to manually extend the lease time when the EFI DHCPv4 Protocol driver is in the Dhcp4Bound state, and the lease time has not expired yet. This function will send a request packet to the previously found server (or to any server when RebindRequest is TRUE) and transfer the state into the Dhcp4Renewing state (or Dhcp4Rebinding when RebindingRequest is TRUE). When a response is received, the state is returned to Dhcp4Bound. If no response is received before the try count is exceeded (the RequestTryCount field that is specified in EFI_DHCP4_CONFIG_DATA) but before the lease time that was issued by the previous server expires, the driver will return to the Dhcp4Bound state, and the previous configuration is restored. The outgoing and incoming packets can be captured by the EFI_DHCP4_CALLBACK function. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param RebindRequest If TRUE, this function broadcasts the request packets and enters the Dhcp4Rebinding state. Otherwise, it sends a unicast request packet and enters the Dhcp4Renewing state. @param CompletionEvent If not NULL, this event is signaled when the renew/rebind phase completes or some error occurs. EFI_DHCP4_PROTOCOL.GetModeData() can be called to check the completion status. If NULL, EFI_DHCP4_PROTOCOL.RenewRebind() will busy-wait until the DHCP process finishes. @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Renewing state or is back to the Dhcp4Bound state. @retval EFI_NOT_STARTED The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped state. EFI_DHCP4_PROTOCOL.Configure() needs to be called. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_TIMEOUT There was no response from the server when the try count was exceeded. @retval EFI_ACCESS_DENIED The driver is not in the Dhcp4Bound state. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_RENEW_REBIND)( IN EFI_DHCP4_PROTOCOL *This, IN BOOLEAN RebindRequest, IN EFI_EVENT CompletionEvent OPTIONAL ); /** Releases the current address configuration. The Release() function releases the current configured IP address by doing either of the following: * Sending a DHCPRELEASE packet when the EFI DHCPv4 Protocol driver is in the Dhcp4Bound state * Setting the previously assigned IP address that was provided with the EFI_DHCP4_PROTOCOL.Configure() function to 0.0.0.0 when the driver is in Dhcp4InitReboot state After a successful call to this function, the EFI DHCPv4 Protocol driver returns to the Dhcp4Init state, and any subsequent incoming packets will be discarded silently. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Init phase. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_ACCESS_DENIED The EFI DHCPv4 Protocol driver is not Dhcp4InitReboot state. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_RELEASE)( IN EFI_DHCP4_PROTOCOL *This ); /** Stops the current address configuration. The Stop() function is used to stop the DHCP configuration process. After this function is called successfully, the EFI DHCPv4 Protocol driver is transferred into the Dhcp4Stopped state. EFI_DHCP4_PROTOCOL.Configure() needs to be called before DHCP configuration process can be started again. This function can be called when the EFI DHCPv4 Protocol driver is in any state. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Stopped phase. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_STOP)( IN EFI_DHCP4_PROTOCOL *This ); /** Builds a DHCP packet, given the options to be appended or deleted or replaced. The Build() function is used to assemble a new packet from the original packet by replacing or deleting existing options or appending new options. This function does not change any state of the EFI DHCPv4 Protocol driver and can be used at any time. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param SeedPacket Initial packet to be used as a base for building new packet. @param DeleteCount Number of opcodes in the DeleteList. @param DeleteList List of opcodes to be deleted from the seed packet. Ignored if DeleteCount is zero. @param AppendCount Number of entries in the OptionList. @param AppendList The pointer to a DHCP option list to be appended to SeedPacket. If SeedPacket also contains options in this list, they are replaced by new options (except pad option). Ignored if AppendCount is zero. Type EFI_DHCP4_PACKET_OPTION @param NewPacket The pointer to storage for the pointer to the new allocated packet. Use the EFI Boot Service FreePool() on the resulting pointer when done with the packet. @retval EFI_SUCCESS The new packet was built. @retval EFI_OUT_OF_RESOURCES Storage for the new packet could not be allocated. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. SeedPacket is NULL. SeedPacket is not a well-formed DHCP packet. AppendCount is not zero and AppendList is NULL. DeleteCount is not zero and DeleteList is NULL. NewPacket is NULL Both DeleteCount and AppendCount are zero and NewPacket is not NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_BUILD)( IN EFI_DHCP4_PROTOCOL *This, IN EFI_DHCP4_PACKET *SeedPacket, IN UINT32 DeleteCount, IN UINT8 *DeleteList OPTIONAL, IN UINT32 AppendCount, IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL, OUT EFI_DHCP4_PACKET **NewPacket ); /** Transmits a DHCP formatted packet and optionally waits for responses. The TransmitReceive() function is used to transmit a DHCP packet and optionally wait for the response from servers. This function does not change the state of the EFI DHCPv4 Protocol driver. It can be used at any time because of this. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param Token The pointer to the EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN structure. @retval EFI_SUCCESS The packet was successfully queued for transmission. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token.RemoteAddress is zero. Token.Packet is NULL. Token.Packet is not a well-formed DHCP packet. The transaction ID in Token.Packet is in use by another DHCP process. @retval EFI_NOT_READY The previous call to this function has not finished yet. Try to call this function after collection process completes. @retval EFI_NO_MAPPING The default station address is not available yet. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_UNSUPPORTED The implementation doesn't support this function @retval Others Some other unexpected error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_TRANSMIT_RECEIVE)( IN EFI_DHCP4_PROTOCOL *This, IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token ); /** Parses the packed DHCP option data. The Parse() function is used to retrieve the option list from a DHCP packet. If *OptionCount isn't zero, and there is enough space for all the DHCP options in the Packet, each element of PacketOptionList is set to point to somewhere in the Packet->Dhcp4.Option where a new DHCP option begins. If RFC3396 is supported, the caller should reassemble the parsed DHCP options to get the final result. If *OptionCount is zero or there isn't enough space for all of them, the number of DHCP options in the Packet is returned in OptionCount. @param This The pointer to the EFI_DHCP4_PROTOCOL instance. @param Packet The pointer to packet to be parsed. @param OptionCount On input, the number of entries in the PacketOptionList. On output, the number of entries that were written into the PacketOptionList. @param PacketOptionList A list of packet option entries to be filled in. End option or pad options are not included. @retval EFI_SUCCESS The packet was successfully parsed. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. The packet is NULL. The packet is not a well-formed DHCP packet. OptionCount is NULL. @retval EFI_BUFFER_TOO_SMALL One or more of the following conditions is TRUE: 1) *OptionCount is smaller than the number of options that were found in the Packet. 2) PacketOptionList is NULL. @retval EFI_OUT_OF_RESOURCE The packet failed to parse because of a resource shortage. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP4_PARSE)( IN EFI_DHCP4_PROTOCOL *This, IN EFI_DHCP4_PACKET *Packet, IN OUT UINT32 *OptionCount, OUT EFI_DHCP4_PACKET_OPTION *PacketOptionList[] OPTIONAL ); /// /// This protocol is used to collect configuration information for the EFI IPv4 Protocol drivers /// and to provide DHCPv4 server and PXE boot server discovery services. /// struct _EFI_DHCP4_PROTOCOL { EFI_DHCP4_GET_MODE_DATA GetModeData; EFI_DHCP4_CONFIGURE Configure; EFI_DHCP4_START Start; EFI_DHCP4_RENEW_REBIND RenewRebind; EFI_DHCP4_RELEASE Release; EFI_DHCP4_STOP Stop; EFI_DHCP4_BUILD Build; EFI_DHCP4_TRANSMIT_RECEIVE TransmitReceive; EFI_DHCP4_PARSE Parse; }; extern EFI_GUID gEfiDhcp4ProtocolGuid; extern EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid; #endif /** @file UEFI Dynamic Host Configuration Protocol 6 Definition, which is used to get IPv6 addresses and other configuration parameters from DHCPv6 servers. Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_DHCP6_PROTOCOL_H__ #define __EFI_DHCP6_PROTOCOL_H__ #define EFI_DHCP6_PROTOCOL_GUID \ { \ 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b } \ } #define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5 } \ } typedef struct _EFI_DHCP6_PROTOCOL EFI_DHCP6_PROTOCOL; typedef enum { /// /// The EFI DHCPv6 Protocol instance is configured, and start() needs /// to be called /// Dhcp6Init = 0x0, /// /// A Solicit packet is sent out to discover DHCPv6 server, and the EFI /// DHCPv6 Protocol instance is collecting Advertise packets. /// Dhcp6Selecting = 0x1, /// /// A Request is sent out to the DHCPv6 server, and the EFI DHCPv6 /// Protocol instance is waiting for Reply packet. /// Dhcp6Requesting = 0x2, /// /// A Decline packet is sent out to indicate one or more addresses of the /// configured IA are in use by another node, and the EFI DHCPv6. /// Protocol instance is waiting for Reply packet. /// Dhcp6Declining = 0x3, /// /// A Confirm packet is sent out to confirm the IPv6 addresses of the /// configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. /// Dhcp6Confirming = 0x4, /// /// A Release packet is sent out to release one or more IPv6 addresses of /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. /// Dhcp6Releasing = 0x5, /// /// The DHCPv6 S.A.R.R process is completed for the configured IA. /// Dhcp6Bound = 0x6, /// /// A Renew packet is sent out to extend lifetime for the IPv6 addresses of /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. /// Dhcp6Renewing = 0x7, /// /// A Rebind packet is sent out to extend lifetime for the IPv6 addresses of /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. /// Dhcp6Rebinding = 0x8 } EFI_DHCP6_STATE; typedef enum { /// /// A Solicit packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6SendSolicit = 0x0, /// /// An Advertise packet is received and will be passed to Dhcp6Callback. /// Dhcp6RcvdAdvertise = 0x1, /// /// It is time for Dhcp6Callback to determine whether select the default Advertise /// packet by RFC 3315 policy, or overwrite it by specific user policy. /// Dhcp6SelectAdvertise = 0x2, /// /// A Request packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6SendRequest = 0x3, /// /// A Reply packet is received and will be passed to Dhcp6Callback. /// Dhcp6RcvdReply = 0x4, /// /// A Reconfigure packet is received and will be passed to Dhcp6Callback. /// Dhcp6RcvdReconfigure = 0x5, /// /// A Decline packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6SendDecline = 0x6, /// /// A Confirm packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6SendConfirm = 0x7, /// /// A Release packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6SendRelease = 0x8, /// /// A Renew packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6EnterRenewing = 0x9, /// /// A Rebind packet is about to be sent. The packet is passed to Dhcp6Callback and /// can be modified or replaced in Dhcp6Callback. /// Dhcp6EnterRebinding = 0xa } EFI_DHCP6_EVENT; /// /// An IA which carries assigned not temporary address. /// #define EFI_DHCP6_IA_TYPE_NA 3 /// /// An IA which carries assigned temporary address. /// #define EFI_DHCP6_IA_TYPE_TA 4 #pragma pack(1) /// /// EFI_DHCP6_PACKET_OPTION /// defines the format of the DHCPv6 option, See RFC 3315 for more information. /// This data structure is used to reference option data that is packed in the DHCPv6 packet. /// typedef struct { /// /// The DHCPv6 option code, stored in network order. /// UINT16 OpCode; /// /// Length of the DHCPv6 option data, stored in network order. /// From the first byte to the last byte of the Data field. /// UINT16 OpLen; /// /// The data for the DHCPv6 option, stored in network order. /// UINT8 Data[1]; } EFI_DHCP6_PACKET_OPTION; /// /// EFI_DHCP6_HEADER /// defines the format of the DHCPv6 header. See RFC 3315 for more information. /// typedef struct { /// /// The DHCPv6 transaction ID. /// UINT32 MessageType : 8; /// /// The DHCPv6 message type. /// UINT32 TransactionId : 24; } EFI_DHCP6_HEADER; /// /// EFI_DHCP6_PACKET /// defines the format of the DHCPv6 packet. See RFC 3315 for more information. /// typedef struct { /// /// Size of the EFI_DHCP6_PACKET buffer. /// UINT32 Size; /// /// Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last /// byte of the Option[] field. /// UINT32 Length; struct { /// /// The DHCPv6 packet header. /// EFI_DHCP6_HEADER Header; /// /// Start of the DHCPv6 packed option data. /// UINT8 Option[1]; } Dhcp6; } EFI_DHCP6_PACKET; #pragma pack() typedef struct { /// /// Length of DUID in octects. /// UINT16 Length; /// /// Array of DUID octects. /// UINT8 Duid[1]; } EFI_DHCP6_DUID; typedef struct { /// /// Initial retransmission timeout. /// UINT32 Irt; /// /// Maximum retransmission count for one packet. If Mrc is zero, there's no upper limit /// for retransmission count. /// UINT32 Mrc; /// /// Maximum retransmission timeout for each retry. It's the upper bound of the number of /// retransmission timeout. If Mrt is zero, there is no upper limit for retransmission /// timeout. /// UINT32 Mrt; /// /// Maximum retransmission duration for one packet. It's the upper bound of the numbers /// the client may retransmit a message. If Mrd is zero, there's no upper limit for /// retransmission duration. /// UINT32 Mrd; } EFI_DHCP6_RETRANSMISSION; typedef struct { /// /// The IPv6 address. /// EFI_IPv6_ADDRESS IpAddress; /// /// The preferred lifetime in unit of seconds for the IPv6 address. /// UINT32 PreferredLifetime; /// /// The valid lifetime in unit of seconds for the IPv6 address. /// UINT32 ValidLifetime; } EFI_DHCP6_IA_ADDRESS; typedef struct { UINT16 Type; ///< Type for an IA. UINT32 IaId; ///< The identifier for an IA. } EFI_DHCP6_IA_DESCRIPTOR; typedef struct { /// /// The descriptor for IA. /// EFI_DHCP6_IA_DESCRIPTOR Descriptor; /// /// The state of the configured IA. /// EFI_DHCP6_STATE State; /// /// Pointer to the cached latest Reply packet. May be NULL if no packet is cached. /// EFI_DHCP6_PACKET *ReplyPacket; /// /// Number of IPv6 addresses of the configured IA. /// UINT32 IaAddressCount; /// /// List of the IPv6 addresses of the configured IA. When the state of the configured IA is /// in Dhcp6Bound, Dhcp6Renewing and Dhcp6Rebinding, the IPv6 addresses are usable. /// EFI_DHCP6_IA_ADDRESS IaAddress[1]; } EFI_DHCP6_IA; typedef struct { /// /// Pointer to the DHCPv6 unique identifier. The caller is responsible for freeing this buffer. /// EFI_DHCP6_DUID *ClientId; /// /// Pointer to the configured IA of current instance. The caller can free this buffer after /// using it. /// EFI_DHCP6_IA *Ia; } EFI_DHCP6_MODE_DATA; /** EFI_DHCP6_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol instance to intercept events that occurs in the DHCPv6 S.A.R.R process. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this callback function. @param[in] Context Pointer to the context that is initialized by EFI_DHCP6_PROTOCOL.Configure(). @param[in] CurrentState The current state of the configured IA. @param[in] Dhcp6Event The event that occurs in the current state, which usually means a state transition. @param[in] Packet Pointer to the DHCPv6 packet that is about to be sent or has been received. The EFI DHCPv6 Protocol instance is responsible for freeing the buffer. @param[out] NewPacket Pointer to the new DHCPv6 packet to overwrite the Packet. NewPacket can not share the buffer with Packet. If *NewPacket is not NULL, the EFI DHCPv6 Protocol instance is responsible for freeing the buffer. @retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to continue the DHCPv6 S.A.R.R process. @retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort the DHCPv6 S.A.R.R process, and the state of the configured IA will be transferred to Dhcp6Init. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_CALLBACK)( IN EFI_DHCP6_PROTOCOL *This, IN VOID *Context, IN EFI_DHCP6_STATE CurrentState, IN EFI_DHCP6_EVENT Dhcp6Event, IN EFI_DHCP6_PACKET *Packet, OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL ); typedef struct { /// /// The callback function is to intercept various events that occur in the DHCPv6 S.A.R.R /// process. Set to NULL to ignore all those events. /// EFI_DHCP6_CALLBACK Dhcp6Callback; /// /// Pointer to the context that will be passed to Dhcp6Callback. /// VOID *CallbackContext; /// /// Number of the DHCPv6 options in the OptionList. /// UINT32 OptionCount; /// /// List of the DHCPv6 options to be included in Solicit and Request packet. The buffer /// can be freed after EFI_DHCP6_PROTOCOL.Configure() returns. Ignored if /// OptionCount is zero. OptionList should not contain Client Identifier option /// and any IA option, which will be appended by EFI DHCPv6 Protocol instance /// automatically. /// EFI_DHCP6_PACKET_OPTION **OptionList; /// /// The descriptor for the IA of the EFI DHCPv6 Protocol instance. /// EFI_DHCP6_IA_DESCRIPTOR IaDescriptor; /// /// If not NULL, the event will be signaled when any IPv6 address information of the /// configured IA is updated, including IPv6 address, preferred lifetime and valid /// lifetime, or the DHCPv6 S.A.R.R process fails. Otherwise, Start(), /// renewrebind(), decline(), release() and stop() will be blocking /// operations, and they will wait for the exchange process completion or failure. /// EFI_EVENT IaInfoEvent; /// /// If TRUE, the EFI DHCPv6 Protocol instance is willing to accept Reconfigure packet. /// Otherwise, it will ignore it. Reconfigure Accept option can not be specified through /// OptionList parameter. /// BOOLEAN ReconfigureAccept; /// /// If TRUE, the EFI DHCPv6 Protocol instance will send Solicit packet with Rapid /// Commit option. Otherwise, Rapid Commit option will not be included in Solicit /// packet. Rapid Commit option can not be specified through OptionList parameter. /// BOOLEAN RapidCommit; /// /// Parameter to control Solicit packet retransmission behavior. The /// buffer can be freed after EFI_DHCP6_PROTOCOL.Configure() returns. /// EFI_DHCP6_RETRANSMISSION *SolicitRetransmission; } EFI_DHCP6_CONFIG_DATA; /** EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol instance to intercept events that occurs in the DHCPv6 Information Request exchange process. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this callback function. @param[in] Context Pointer to the context that is initialized in the EFI_DHCP6_PROTOCOL.InfoRequest(). @param[in] Packet Pointer to Reply packet that has been received. The EFI DHCPv6 Protocol instance is responsible for freeing the buffer. @retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to finish Information Request exchange process. @retval EFI_NOT_READY Tell the EFI DHCPv6 Protocol instance to continue Information Request exchange process. @retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort the Information Request exchange process. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_INFO_CALLBACK)( IN EFI_DHCP6_PROTOCOL *This, IN VOID *Context, IN EFI_DHCP6_PACKET *Packet ); /** Retrieve the current operating mode data and configuration data for the EFI DHCPv6 Protocol instance. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @param[out] Dhcp6ModeData Pointer to the DHCPv6 mode data structure. The caller is responsible for freeing this structure and each reference buffer. @param[out] Dhcp6ConfigData Pointer to the DHCPv6 configuration data structure. The caller is responsible for freeing this structure and each reference buffer. @retval EFI_SUCCESS The mode data was returned. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Protocol instance has not been configured when Dhcp6ConfigData is not NULL. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: - This is NULL. - Both Dhcp6ConfigData and Dhcp6ModeData are NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_GET_MODE_DATA)( IN EFI_DHCP6_PROTOCOL *This, OUT EFI_DHCP6_MODE_DATA *Dhcp6ModeData OPTIONAL, OUT EFI_DHCP6_CONFIG_DATA *Dhcp6ConfigData OPTIONAL ); /** Initialize or clean up the configuration data for the EFI DHCPv6 Protocol instance. The Configure() function is used to initialize or clean up the configuration data of the EFI DHCPv6 Protocol instance. - When Dhcp6CfgData is not NULL and Configure() is called successfully, the configuration data will be initialized in the EFI DHCPv6 Protocol instance and the state of the configured IA will be transferred into Dhcp6Init. - When Dhcp6CfgData is NULL and Configure() is called successfully, the configuration data will be cleaned up and no IA will be associated with the EFI DHCPv6 Protocol instance. To update the configuration data for an EFI DCHPv6 Protocol instance, the original data must be cleaned up before setting the new configuration data. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @param[in] Dhcp6CfgData Pointer to the DHCPv6 configuration data structure. @retval EFI_SUCCESS The mode data was returned. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE - This is NULL. - OptionCount > 0 and OptionList is NULL. - OptionList is not NULL, and Client Id option, Reconfigure Accept option, Rapid Commit option or any IA option is specified in the OptionList. - IaDescriptor.Type is neither EFI_DHCP6_IA_TYPE_NA nor EFI_DHCP6_IA_TYPE_NA. - IaDescriptor is not unique. - Both IaInfoEvent and SolicitRetransimssion are NULL. - SolicitRetransmission is not NULL, and both SolicitRetransimssion->Mrc and SolicitRetransmission->Mrd are zero. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Protocol instance has been already configured when Dhcp6CfgData is not NULL. The EFI DHCPv6 Protocol instance has already started the DHCPv6 S.A.R.R when Dhcp6CfgData is NULL. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_CONFIGURE)( IN EFI_DHCP6_PROTOCOL *This, IN EFI_DHCP6_CONFIG_DATA *Dhcp6CfgData OPTIONAL ); /** Start the DHCPv6 S.A.R.R process. The Start() function starts the DHCPv6 S.A.R.R process. This function can be called only when the state of the configured IA is in the Dhcp6Init state. If the DHCPv6 S.A.R.R process completes successfully, the state of the configured IA will be transferred through Dhcp6Selecting and Dhcp6Requesting to Dhcp6Bound state. The update of the IPv6 addresses will be notified through EFI_DHCP6_CONFIG_DATA.IaInfoEvent. At the time when each event occurs in this process, the callback function set by EFI_DHCP6_PROTOCOL.Configure() will be called and the user can take this opportunity to control the process. If EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the Start() function call is a blocking operation. It will return after the DHCPv6 S.A.R.R process completes or aborted by users. If the process is aborted by system or network error, the state of the configured IA will be transferred to Dhcp6Init. The Start() function can be called again to restart the process. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @retval EFI_SUCCESS The DHCPv6 S.A.R.R process is completed and at least one IPv6 address has been bound to the configured IA when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. The DHCPv6 S.A.R.R process is started when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ALREADY_STARTED The DHCPv6 S.A.R.R process has already started. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_NO_RESPONSE The DHCPv6 S.A.R.R process failed because of no response. @retval EFI_NO_MAPPING No IPv6 address has been bound to the configured IA after the DHCPv6 S.A.R.R process. @retval EFI_ABORTED The DHCPv6 S.A.R.R process aborted by user. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_START)( IN EFI_DHCP6_PROTOCOL *This ); /** Request configuration information without the assignment of any IA addresses of the client. The InfoRequest() function is used to request configuration information without the assignment of any IPv6 address of the client. Client sends out Information Request packet to obtain the required configuration information, and DHCPv6 server responds with Reply packet containing the information for the client. The received Reply packet will be passed to the user by ReplyCallback function. If user returns EFI_NOT_READY from ReplyCallback, the EFI DHCPv6 Protocol instance will continue to receive other Reply packets unless timeout according to the Retransmission parameter. Otherwise, the Information Request exchange process will be finished successfully if user returns EFI_SUCCESS from ReplyCallback. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @param[in] SendClientId If TRUE, the EFI DHCPv6 Protocol instance will build Client Identifier option and include it into Information Request packet. If FALSE, Client Identifier option will not be included. Client Identifier option can not be specified through OptionList parameter. @param[in] OptionRequest Pointer to the Option Request option in the Information Request packet. Option Request option can not be specified through OptionList parameter. @param[in] OptionCount Number of options in OptionList. @param[in] OptionList List of other DHCPv6 options. These options will be appended to the Option Request option. The caller is responsible for freeing this buffer. Type is defined in EFI_DHCP6_PROTOCOL.GetModeData(). @param[in] Retransmission Parameter to control Information Request packet retransmission behavior. The buffer can be freed after EFI_DHCP6_PROTOCOL.InfoRequest() returns. @param[in] TimeoutEvent If not NULL, this event is signaled when the information request exchange aborted because of no response. If NULL, the function call is a blocking operation; and it will return after the information-request exchange process finish or aborted by users. @param[in] ReplyCallback The callback function is to intercept various events that occur in the Information Request exchange process. It should not be set to NULL. @param[in] CallbackContext Pointer to the context that will be passed to ReplyCallback. @retval EFI_SUCCESS The DHCPv6 S.A.R.R process is completed and at least one IPv6 @retval EFI_SUCCESS The DHCPv6 information request exchange process completed when TimeoutEvent is NULL. Information Request packet has been sent to DHCPv6 server when TimeoutEvent is not NULL. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: - This is NULL. - OptionRequest is NULL or OptionRequest->OpCode is invalid. - OptionCount > 0 and OptionList is NULL. - OptionList is not NULL, and Client Identify option or Option Request option is specified in the OptionList. - Retransimssion is NULL. - Both Retransimssion->Mrc and Retransmission->Mrd are zero. - ReplyCallback is NULL. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_NO_RESPONSE The DHCPv6 information request exchange process failed because of no response, or not all requested-options are responded by DHCPv6 servers when Timeout happened. @retval EFI_ABORTED The DHCPv6 information request exchange process aborted by user. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_INFO_REQUEST)( IN EFI_DHCP6_PROTOCOL *This, IN BOOLEAN SendClientId, IN EFI_DHCP6_PACKET_OPTION *OptionRequest, IN UINT32 OptionCount, IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL, IN EFI_DHCP6_RETRANSMISSION *Retransmission, IN EFI_EVENT TimeoutEvent OPTIONAL, IN EFI_DHCP6_INFO_CALLBACK ReplyCallback, IN VOID *CallbackContext OPTIONAL ); /** Manually extend the valid and preferred lifetimes for the IPv6 addresses of the configured IA and update other configuration parameters by sending Renew or Rebind packet. The RenewRebind() function is used to manually extend the valid and preferred lifetimes for the IPv6 addresses of the configured IA and update other configuration parameters by sending Renew or Rebind packet. - When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound, it will send Renew packet to the previously DHCPv6 server and transfer the state of the configured IA to Dhcp6Renewing. If valid Reply packet received, the state transfers to Dhcp6Bound and the valid and preferred timer restarts. If fails, the state transfers to Dhcp6Bound but the timer continues. - When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound, it will send Rebind packet. If valid Reply packet received, the state transfers to Dhcp6Bound and the valid and preferred timer restarts. If fails, the state transfers to Dhcp6Init and the IA can't be used. @param[in] This Pointer to the EFI_DHCP4_PROTOCOL instance. @param[in] RebindRequest If TRUE, it will send Rebind packet and enter the Dhcp6Rebinding state. Otherwise, it will send Renew packet and enter the Dhcp6Renewing state. @retval EFI_SUCCESS The DHCPv6 renew/rebind exchange process has completed and at least one IPv6 address of the configured IA has been bound again when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. The EFI DHCPv6 Protocol instance has sent Renew or Rebind packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the state of the configured IA is not in Dhcp6Bound. @retval EFI_ALREADY_STARTED The state of the configured IA has already entered Dhcp6Renewing when RebindRequest is FALSE. The state of the configured IA has already entered Dhcp6Rebinding when RebindRequest is TRUE. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or system error occurred. @retval EFI_NO_RESPONSE The DHCPv6 renew/rebind exchange process failed because of no response. @retval EFI_NO_MAPPING No IPv6 address has been bound to the configured IA after the DHCPv6 renew/rebind exchange process. @retval EFI_ABORTED The DHCPv6 renew/rebind exchange process aborted by user. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_RENEW_REBIND)( IN EFI_DHCP6_PROTOCOL *This, IN BOOLEAN RebindRequest ); /** Inform that one or more IPv6 addresses assigned by a server are already in use by another node. The Decline() function is used to manually decline the assignment of IPv6 addresses, which have been already used by another node. If all IPv6 addresses of the configured IA are declined through this function, the state of the IA will switch through Dhcp6Declining to Dhcp6Init, otherwise, the state of the IA will restore to Dhcp6Bound after the declining process. The Decline() can only be called when the IA is in Dhcp6Bound state. If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, this function is a blocking operation. It will return after the declining process finishes, or aborted by user. @param[in] This Pointer to the EFI_DHCP4_PROTOCOL instance. @param[in] AddressCount Number of declining IPv6 addresses. @param[in] Addresses Pointer to the buffer stored all the declining IPv6 addresses. @retval EFI_SUCCESS The DHCPv6 decline exchange process has completed when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. The EFI DHCPv6 Protocol instance has sent Decline packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE - This is NULL. - AddressCount is zero or Addresses is NULL. @retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with the configured IA for this instance. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the state of the configured IA is not in Dhcp6Bound. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_ABORTED The DHCPv6 decline exchange process aborted by user. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_DECLINE)( IN EFI_DHCP6_PROTOCOL *This, IN UINT32 AddressCount, IN EFI_IPv6_ADDRESS *Addresses ); /** Release one or more IPv6 addresses associated with the configured IA for current instance. The Release() function is used to manually release the one or more IPv6 address. If AddressCount is zero, it will release all IPv6 addresses of the configured IA. If all IPv6 addresses of the IA are released through this function, the state of the IA will switch through Dhcp6Releasing to Dhcp6Init, otherwise, the state of the IA will restore to Dhcp6Bound after the releasing process. The Release() can only be called when the IA is in Dhcp6Bound state. If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is a blocking operation. It will return after the releasing process finishes, or aborted by user. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @param[in] AddressCount Number of releasing IPv6 addresses. @param[in] Addresses Pointer to the buffer stored all the releasing IPv6 addresses. Ignored if AddressCount is zero. @retval EFI_SUCCESS The DHCPv6 release exchange process has completed when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. The EFI DHCPv6 Protocol instance has sent Release packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE - This is NULL. - AddressCount is not zero or Addresses is NULL. @retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with the configured IA for this instance. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the state of the configured IA is not in Dhcp6Bound. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_ABORTED The DHCPv6 release exchange process aborted by user. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_RELEASE)( IN EFI_DHCP6_PROTOCOL *This, IN UINT32 AddressCount, IN EFI_IPv6_ADDRESS *Addresses ); /** Stop the DHCPv6 S.A.R.R process. The Stop() function is used to stop the DHCPv6 S.A.R.R process. If this function is called successfully, all the IPv6 addresses of the configured IA will be released and the state of the configured IA will be transferred to Dhcp6Init. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @retval EFI_SUCCESS The DHCPv6 S.A.R.R process has been stopped when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. The EFI DHCPv6 Protocol instance has sent Release packet if need release or has been stopped if needn't, when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_STOP)( IN EFI_DHCP6_PROTOCOL *This ); /** Parse the option data in the DHCPv6 packet. The Parse() function is used to retrieve the option list in the DHCPv6 packet. @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. @param[in] Packet Pointer to packet to be parsed. @param[in] OptionCount On input, the number of entries in the PacketOptionList. On output, the number of DHCPv6 options in the Packet. @param[in] PacketOptionList List of pointers to the DHCPv6 options in the Packet. The OpCode and OpLen in EFI_DHCP6_PACKET_OPTION are both stored in network byte order. @retval EFI_SUCCESS The packet was successfully parsed. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE - This is NULL. - Packet is NULL. - Packet is not a well-formed DHCPv6 packet. - OptionCount is NULL. - *OptionCount is not zero and PacketOptionList is NULL. @retval EFI_BUFFER_TOO_SMALL *OptionCount is smaller than the number of options that were found in the Packet. **/ typedef EFI_STATUS (EFIAPI *EFI_DHCP6_PARSE)( IN EFI_DHCP6_PROTOCOL *This, IN EFI_DHCP6_PACKET *Packet, IN OUT UINT32 *OptionCount, OUT EFI_DHCP6_PACKET_OPTION *PacketOptionList[] OPTIONAL ); /// /// The EFI DHCPv6 Protocol is used to get IPv6 addresses and other configuration parameters /// from DHCPv6 servers. /// struct _EFI_DHCP6_PROTOCOL { EFI_DHCP6_GET_MODE_DATA GetModeData; EFI_DHCP6_CONFIGURE Configure; EFI_DHCP6_START Start; EFI_DHCP6_INFO_REQUEST InfoRequest; EFI_DHCP6_RENEW_REBIND RenewRebind; EFI_DHCP6_DECLINE Decline; EFI_DHCP6_RELEASE Release; EFI_DHCP6_STOP Stop; EFI_DHCP6_PARSE Parse; }; extern EFI_GUID gEfiDhcp6ProtocolGuid; extern EFI_GUID gEfiDhcp6ServiceBindingProtocolGuid; #endif /** @file Provides the basic interfaces to abstract platform information regarding an IDE controller. Copyright (c) 2006 - 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.6 Volume 5: Standards **/ #ifndef __DISK_INFO_H__ #define __DISK_INFO_H__ /// /// Global ID for EFI_DISK_INFO_PROTOCOL /// #define EFI_DISK_INFO_PROTOCOL_GUID \ { \ 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27 } \ } /// /// Forward declaration for EFI_DISK_INFO_PROTOCOL /// typedef struct _EFI_DISK_INFO_PROTOCOL EFI_DISK_INFO_PROTOCOL; /// /// Global ID for an IDE interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_IDE_INTERFACE_GUID \ { \ 0x5e948fe3, 0x26d3, 0x42b5, {0xaf, 0x17, 0x61, 0x2, 0x87, 0x18, 0x8d, 0xec } \ } /// /// Global ID for a SCSI interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_SCSI_INTERFACE_GUID \ { \ 0x8f74baa, 0xea36, 0x41d9, {0x95, 0x21, 0x21, 0xa7, 0xf, 0x87, 0x80, 0xbc } \ } /// /// Global ID for a USB interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_USB_INTERFACE_GUID \ { \ 0xcb871572, 0xc11a, 0x47b5, {0xb4, 0x92, 0x67, 0x5e, 0xaf, 0xa7, 0x77, 0x27 } \ } /// /// Global ID for an AHCI interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_AHCI_INTERFACE_GUID \ { \ 0x9e498932, 0x4abc, 0x45af, {0xa3, 0x4d, 0x2, 0x47, 0x78, 0x7b, 0xe7, 0xc6 } \ } /// /// Global ID for a NVME interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_NVME_INTERFACE_GUID \ { \ 0x3ab14680, 0x5d3f, 0x4a4d, {0xbc, 0xdc, 0xcc, 0x38, 0x0, 0x18, 0xc7, 0xf7 } \ } /// /// Global ID for a UFS interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_UFS_INTERFACE_GUID \ { \ 0x4b3029cc, 0x6b98, 0x47fb, { 0xbc, 0x96, 0x76, 0xdc, 0xb8, 0x4, 0x41, 0xf0 } \ } /// /// Global ID for an SD/MMC interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface /// #define EFI_DISK_INFO_SD_MMC_INTERFACE_GUID \ { \ 0x8deec992, 0xd39c, 0x4a5c, { 0xab, 0x6b, 0x98, 0x6e, 0x14, 0x24, 0x2b, 0x9d } \ } /** Provides inquiry information for the controller type. This function is used by the IDE bus driver to get inquiry data. Data format of Identify data is defined by the Interface GUID. @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. @param[in,out] InquiryData Pointer to a buffer for the inquiry data. @param[in,out] InquiryDataSize Pointer to the value for the inquiry data size. @retval EFI_SUCCESS The command was accepted without any errors. @retval EFI_NOT_FOUND Device does not support this data class @retval EFI_DEVICE_ERROR Error reading InquiryData from device @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_INFO_INQUIRY)( IN EFI_DISK_INFO_PROTOCOL *This, IN OUT VOID *InquiryData, IN OUT UINT32 *InquiryDataSize ); /** Provides identify information for the controller type. This function is used by the IDE bus driver to get identify data. Data format of Identify data is defined by the Interface GUID. @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. @param[in,out] IdentifyData Pointer to a buffer for the identify data. @param[in,out] IdentifyDataSize Pointer to the value for the identify data size. @retval EFI_SUCCESS The command was accepted without any errors. @retval EFI_NOT_FOUND Device does not support this data class @retval EFI_DEVICE_ERROR Error reading IdentifyData from device @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_INFO_IDENTIFY)( IN EFI_DISK_INFO_PROTOCOL *This, IN OUT VOID *IdentifyData, IN OUT UINT32 *IdentifyDataSize ); /** Provides sense data information for the controller type. This function is used by the IDE bus driver to get sense data. Data format of Sense data is defined by the Interface GUID. @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. @param[in,out] SenseData Pointer to the SenseData. @param[in,out] SenseDataSize Size of SenseData in bytes. @param[out] SenseDataNumber Pointer to the value for the sense data size. @retval EFI_SUCCESS The command was accepted without any errors. @retval EFI_NOT_FOUND Device does not support this data class. @retval EFI_DEVICE_ERROR Error reading SenseData from device. @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_INFO_SENSE_DATA)( IN EFI_DISK_INFO_PROTOCOL *This, IN OUT VOID *SenseData, IN OUT UINT32 *SenseDataSize, OUT UINT8 *SenseDataNumber ); /** This function is used by the IDE bus driver to get controller information. @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. @retval EFI_UNSUPPORTED This is not an IDE device. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_INFO_WHICH_IDE)( IN EFI_DISK_INFO_PROTOCOL *This, OUT UINT32 *IdeChannel, OUT UINT32 *IdeDevice ); /// /// The EFI_DISK_INFO_PROTOCOL provides controller specific information. /// struct _EFI_DISK_INFO_PROTOCOL { /// /// A GUID that defines the format of buffers for the other member functions /// of this protocol. /// EFI_GUID Interface; /// /// Return the results of the Inquiry command to a drive in InquiryData. Data /// format of Inquiry data is defined by the Interface GUID. /// EFI_DISK_INFO_INQUIRY Inquiry; /// /// Return the results of the Identify command to a drive in IdentifyData. Data /// format of Identify data is defined by the Interface GUID. /// EFI_DISK_INFO_IDENTIFY Identify; /// /// Return the results of the Request Sense command to a drive in SenseData. Data /// format of Sense data is defined by the Interface GUID. /// EFI_DISK_INFO_SENSE_DATA SenseData; /// /// Specific controller. /// EFI_DISK_INFO_WHICH_IDE WhichIde; }; extern EFI_GUID gEfiDiskInfoProtocolGuid; extern EFI_GUID gEfiDiskInfoIdeInterfaceGuid; extern EFI_GUID gEfiDiskInfoScsiInterfaceGuid; extern EFI_GUID gEfiDiskInfoUsbInterfaceGuid; extern EFI_GUID gEfiDiskInfoAhciInterfaceGuid; extern EFI_GUID gEfiDiskInfoNvmeInterfaceGuid; extern EFI_GUID gEfiDiskInfoUfsInterfaceGuid; extern EFI_GUID gEfiDiskInfoSdMmcInterfaceGuid; #endif /** @file Disk IO protocol as defined in the UEFI 2.0 specification. The Disk IO protocol is used to convert block oriented devices into byte oriented devices. The Disk IO protocol is intended to layer on top of the Block IO protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DISK_IO_H__ #define __DISK_IO_H__ #define EFI_DISK_IO_PROTOCOL_GUID \ { \ 0xce345171, 0xba0b, 0x11d2, {0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } /// /// Protocol GUID name defined in EFI1.1. /// #define DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL_GUID typedef struct _EFI_DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL; /// /// Protocol defined in EFI1.1. /// typedef EFI_DISK_IO_PROTOCOL EFI_DISK_IO; /** Read BufferSize bytes from Offset into Buffer. @param This Protocol instance pointer. @param MediaId Id of the media, changes every time the media is replaced. @param Offset The starting byte offset to read from @param BufferSize Size of Buffer @param Buffer Buffer containing read data @retval EFI_SUCCESS The data was read correctly from the device. @retval EFI_DEVICE_ERROR The device reported an error while performing the read. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_READ)( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN UINTN BufferSize, OUT VOID *Buffer ); /** Writes a specified number of bytes to a device. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to be written. @param Offset The starting byte offset on the logical block I/O device to write. @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. @param Buffer A pointer to the buffer containing the data to be written. @retval EFI_SUCCESS The data was written correctly to the device. @retval EFI_WRITE_PROTECTED The device can not be written to. @retval EFI_DEVICE_ERROR The device reported an error while performing the write. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_WRITE)( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN UINTN BufferSize, IN VOID *Buffer ); #define EFI_DISK_IO_PROTOCOL_REVISION 0x00010000 /// /// Revision defined in EFI1.1 /// #define EFI_DISK_IO_INTERFACE_REVISION EFI_DISK_IO_PROTOCOL_REVISION /// /// This protocol is used to abstract Block I/O interfaces. /// struct _EFI_DISK_IO_PROTOCOL { /// /// The revision to which the disk I/O interface adheres. All future /// revisions must be backwards compatible. If a future version is not /// backwards compatible, it is not the same GUID. /// UINT64 Revision; EFI_DISK_READ ReadDisk; EFI_DISK_WRITE WriteDisk; }; extern EFI_GUID gEfiDiskIoProtocolGuid; #endif /** @file Disk I/O 2 protocol as defined in the UEFI 2.4 specification. The Disk I/O 2 protocol defines an extension to the Disk I/O protocol to enable non-blocking / asynchronous byte-oriented disk operation. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DISK_IO2_H__ #define __DISK_IO2_H__ #define EFI_DISK_IO2_PROTOCOL_GUID \ { \ 0x151c8eae, 0x7f2c, 0x472c, \ {0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88} \ } typedef struct _EFI_DISK_IO2_PROTOCOL EFI_DISK_IO2_PROTOCOL; /** The struct of Disk IO2 Token. **/ typedef struct { // // If Event is NULL, then blocking I/O is performed. // If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed, // and Event will be signaled when the I/O request is completed. // The caller must be prepared to handle the case where the callback associated with Event occurs // before the original asynchronous I/O request call returns. // EFI_EVENT Event; // // Defines whether or not the signaled event encountered an error. // EFI_STATUS TransactionStatus; } EFI_DISK_IO2_TOKEN; /** Terminate outstanding asynchronous requests to a device. @param This Indicates a pointer to the calling context. @retval EFI_SUCCESS All outstanding requests were successfully terminated. @retval EFI_DEVICE_ERROR The device reported an error while performing the cancel operation. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_CANCEL_EX)( IN EFI_DISK_IO2_PROTOCOL *This ); /** Reads a specified number of bytes from a device. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to be read. @param Offset The starting byte offset on the logical block I/O device to read from. @param Token A pointer to the token associated with the transaction. If this field is NULL, synchronous/blocking IO is performed. @param BufferSize The size in bytes of Buffer. The number of bytes to read from the device. @param Buffer A pointer to the destination buffer for the data. The caller is responsible either having implicit or explicit ownership of the buffer. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read correctly from the device. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. Event will be signaled upon completion. @retval EFI_DEVICE_ERROR The device reported an error while performing the write. @retval EFI_NO_MEDIA There is no medium in the device. @retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium. @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_READ_EX)( IN EFI_DISK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN OUT EFI_DISK_IO2_TOKEN *Token, IN UINTN BufferSize, OUT VOID *Buffer ); /** Writes a specified number of bytes to a device. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to be written. @param Offset The starting byte offset on the logical block I/O device to write to. @param Token A pointer to the token associated with the transaction. If this field is NULL, synchronous/blocking IO is performed. @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. @param Buffer A pointer to the buffer containing the data to be written. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was written correctly to the device. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. Event will be signaled upon completion. @retval EFI_WRITE_PROTECTED The device cannot be written to. @retval EFI_DEVICE_ERROR The device reported an error while performing the write operation. @retval EFI_NO_MEDIA There is no medium in the device. @retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium. @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_WRITE_EX)( IN EFI_DISK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN OUT EFI_DISK_IO2_TOKEN *Token, IN UINTN BufferSize, IN VOID *Buffer ); /** Flushes all modified data to the physical device. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to be written. @param Token A pointer to the token associated with the transaction. If this field is NULL, synchronous/blocking IO is performed. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was flushed successfully to the device. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. Event will be signaled upon completion. @retval EFI_WRITE_PROTECTED The device cannot be written to. @retval EFI_DEVICE_ERROR The device reported an error while performing the write operation. @retval EFI_NO_MEDIA There is no medium in the device. @retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_DISK_FLUSH_EX)( IN EFI_DISK_IO2_PROTOCOL *This, IN OUT EFI_DISK_IO2_TOKEN *Token ); #define EFI_DISK_IO2_PROTOCOL_REVISION 0x00020000 /// /// This protocol is used to abstract Block I/O interfaces. /// struct _EFI_DISK_IO2_PROTOCOL { /// /// The revision to which the disk I/O interface adheres. All future /// revisions must be backwards compatible. If a future version is not /// backwards compatible, it is not the same GUID. /// UINT64 Revision; EFI_DISK_CANCEL_EX Cancel; EFI_DISK_READ_EX ReadDiskEx; EFI_DISK_WRITE_EX WriteDiskEx; EFI_DISK_FLUSH_EX FlushDiskEx; }; extern EFI_GUID gEfiDiskIo2ProtocolGuid; #endif /** @file EFI Deferred Procedure Call Protocol. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DPC_H__ #define __DPC_H__ // // DPC Protocol GUID value // #define EFI_DPC_PROTOCOL_GUID \ { \ 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6 } \ } // // Forward reference for pure ANSI compatibility // typedef struct _EFI_DPC_PROTOCOL EFI_DPC_PROTOCOL; /** Invoke a Deferred Procedure Call. @param DpcContext The pointer to the Deferred Procedure Call's context, which is implementation dependent. **/ typedef VOID (EFIAPI *EFI_DPC_PROCEDURE)( IN VOID *DpcContext ); /** Add a Deferred Procedure Call to the end of the DPC queue. @param This The protocol instance pointer. @param DpcTpl The EFI_TPL that the DPC should invoke. @param DpcProcedure The pointer to the DPC's function. @param DpcContext The pointer to the DPC's context. Passed to DpcProcedure when DpcProcedure is invoked. @retval EFI_SUCCESS The DPC was queued. @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to add the DPC to the queue. **/ typedef EFI_STATUS (EFIAPI *EFI_DPC_QUEUE_DPC)( IN EFI_DPC_PROTOCOL *This, IN EFI_TPL DpcTpl, IN EFI_DPC_PROCEDURE DpcProcedure, IN VOID *DpcContext OPTIONAL ); /** Dispatch the queue of DPCs. DPCs with DpcTpl value greater than the current TPL value are queued, and then DPCs with DpcTpl value lower than the current TPL value are queued. All DPCs in the first group (higher DpcTpl values) are invoked before DPCs in the second group (lower DpcTpl values). @param This Protocol instance pointer. @retval EFI_SUCCESS One or more DPCs were invoked. @retval EFI_NOT_FOUND No DPCs were invoked. **/ typedef EFI_STATUS (EFIAPI *EFI_DPC_DISPATCH_DPC)( IN EFI_DPC_PROTOCOL *This ); /// /// DPC Protocol structure. /// struct _EFI_DPC_PROTOCOL { EFI_DPC_QUEUE_DPC QueueDpc; EFI_DPC_DISPATCH_DPC DispatchDpc; }; /// /// DPC Protocol GUID variable. /// extern EFI_GUID gEfiDpcProtocolGuid; #endif /** @file UEFI DriverBinding Protocol is defined in UEFI specification. This protocol is produced by every driver that follows the UEFI Driver Model, and it is the central component that allows drivers and controllers to be managed. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_BINDING_H__ #define __EFI_DRIVER_BINDING_H__ /// /// The global ID for the ControllerHandle Driver Protocol. /// #define EFI_DRIVER_BINDING_PROTOCOL_GUID \ { \ 0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0xc, 0x9, 0x26, 0x1e, 0x9f, 0x71 } \ } typedef struct _EFI_DRIVER_BINDING_PROTOCOL EFI_DRIVER_BINDING_PROTOCOL; /** Tests to see if this driver supports a given controller. If a child device is provided, it further tests to see if this driver supports creating a handle for the specified child device. This function checks to see if the driver specified by This supports the device specified by ControllerHandle. Drivers will typically use the device path attached to ControllerHandle and/or the services from the bus I/O abstraction attached to ControllerHandle to determine if the driver supports ControllerHandle. This function may be called many times during platform initialization. In order to reduce boot times, the tests performed by this function must be very small, and take as little time as possible to execute. This function must not change the state of any hardware devices, and this function must be aware that the device specified by ControllerHandle may already be managed by the same driver or a different driver. This function must match its calls to AllocatePages() with FreePages(), AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). Because ControllerHandle may have been previously started by the same driver, if a protocol is already in the opened state, then it must not be closed with CloseProtocol(). This is required to guarantee the state of ControllerHandle is not modified by this function. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle The handle of the controller to test. This handle must support a protocol interface that supplies an I/O abstraction to the driver. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This parameter is ignored by device drivers, and is optional for bus drivers. For bus drivers, if this parameter is not NULL, then the bus driver must determine if the bus controller specified by ControllerHandle and the child controller specified by RemainingDevicePath are both supported by this bus driver. @retval EFI_SUCCESS The device specified by ControllerHandle and RemainingDevicePath is supported by the driver specified by This. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and RemainingDevicePath is already being managed by the driver specified by This. @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and RemainingDevicePath is already being managed by a different driver or an application that requires exclusive access. Currently not implemented. @retval EFI_UNSUPPORTED The device specified by ControllerHandle and RemainingDevicePath is not supported by the driver specified by This. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_BINDING_SUPPORTED)( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ); /** Starts a device controller or a bus controller. The Start() function is designed to be invoked from the EFI boot service ConnectController(). As a result, much of the error checking on the parameters to Start() has been moved into this common boot service. It is legal to call Start() from other locations, but the following calling restrictions must be followed, or the system behavior will not be deterministic. 1. ControllerHandle must be a valid EFI_HANDLE. 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned EFI_DEVICE_PATH_PROTOCOL. 3. Prior to calling Start(), the Supported() function for the driver specified by This must have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle The handle of the controller to start. This handle must support a protocol interface that supplies an I/O abstraction to the driver. @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This parameter is ignored by device drivers, and is optional for bus drivers. For a bus driver, if this parameter is NULL, then handles for all the children of Controller are created by this driver. If this parameter is not NULL and the first Device Path Node is not the End of Device Path Node, then only the handle for the child device specified by the first Device Path Node of RemainingDevicePath is created by this driver. If the first Device Path Node of RemainingDevicePath is the End of Device Path Node, no child handle is created by this driver. @retval EFI_SUCCESS The device was started. @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval Others The driver failded to start the device. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_BINDING_START)( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ); /** Stops a device controller or a bus controller. The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). As a result, much of the error checking on the parameters to Stop() has been moved into this common boot service. It is legal to call Stop() from other locations, but the following calling restrictions must be followed, or the system behavior will not be deterministic. 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this same driver's Start() function. 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid EFI_HANDLE. In addition, all of these handles must have been created in this driver's Start() function, and the Start() function must have called OpenProtocol() on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle A handle to the device being stopped. The handle must support a bus specific I/O protocol for the driver to use to stop the device. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL if NumberOfChildren is 0. @retval EFI_SUCCESS The device was stopped. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_BINDING_STOP)( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ); /// /// This protocol provides the services required to determine if a driver supports a given controller. /// If a controller is supported, then it also provides routines to start and stop the controller. /// struct _EFI_DRIVER_BINDING_PROTOCOL { EFI_DRIVER_BINDING_SUPPORTED Supported; EFI_DRIVER_BINDING_START Start; EFI_DRIVER_BINDING_STOP Stop; /// /// The version number of the UEFI driver that produced the /// EFI_DRIVER_BINDING_PROTOCOL. This field is used by /// the EFI boot service ConnectController() to determine /// the order that driver's Supported() service will be used when /// a controller needs to be started. EFI Driver Binding Protocol /// instances with higher Version values will be used before ones /// with lower Version values. The Version values of 0x0- /// 0x0f and 0xfffffff0-0xffffffff are reserved for /// platform/OEM specific drivers. The Version values of 0x10- /// 0xffffffef are reserved for IHV-developed drivers. /// UINT32 Version; /// /// The image handle of the UEFI driver that produced this instance /// of the EFI_DRIVER_BINDING_PROTOCOL. /// EFI_HANDLE ImageHandle; /// /// The handle on which this instance of the /// EFI_DRIVER_BINDING_PROTOCOL is installed. In most /// cases, this is the same handle as ImageHandle. However, for /// UEFI drivers that produce more than one instance of the /// EFI_DRIVER_BINDING_PROTOCOL, this value may not be /// the same as ImageHandle. /// EFI_HANDLE DriverBindingHandle; }; extern EFI_GUID gEfiDriverBindingProtocolGuid; #endif /** @file EFI Driver Configuration Protocol Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_CONFIGURATION_H__ #define __EFI_DRIVER_CONFIGURATION_H__ #include /// /// Global ID for the Driver Configuration Protocol defined in EFI 1.1 /// #define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \ { \ 0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_DRIVER_CONFIGURATION_PROTOCOL EFI_DRIVER_CONFIGURATION_PROTOCOL; /** Allows the user to set controller specific options for a controller that a driver is currently managing. @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance. @param ControllerHandle The handle of the controller to set options on. @param ChildHandle The handle of the child controller to set options on. This is an optional parameter that may be NULL. It will be NULL for device drivers, and for bus drivers that wish to set options for the bus controller. It will not be NULL for a bus driver that wishes to set options for one of its child controllers. @param Language A pointer to a three character ISO 639-2 language identifier. This is the language of the user interface that should be presented to the user, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. @param ActionRequired A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again. @retval EFI_SUCCESS The driver specified by This successfully set the configuration options for the controller specified by ControllerHandle.. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ActionRequired is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support setting configuration options for the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. @retval EFI_DEVICE_ERROR A device error occurred while attempt to set the configuration options for the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_RESOURCES There are not enough resources available to set the configuration options for the controller specified by ControllerHandle and ChildHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION_SET_OPTIONS)( IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired ); /** Tests to see if a controller's current configuration options are valid. @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance. @param ControllerHandle The handle of the controller to test if it's current configuration options are valid. @param ChildHandle The handle of the child controller to test if it's current configuration options are valid. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to test the configuration options for the bus controller. It will not be NULL for a bus driver that wishes to test configuration options for one of its child controllers. @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle that is being managed by the driver specified by This has a valid set of configuration options. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle that is being managed by the driver specified by This has an invalid set of configuration options. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION_OPTIONS_VALID)( IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL ); /** Forces a driver to set the default configuration options for a controller. @param This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance. @param ControllerHandle The handle of the controller to force default configuration options on. @param ChildHandle The handle of the child controller to force default configuration options on This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to force default configuration options for the bus controller. It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers. @param DefaultType The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle. See Table 9-1 for legal values. A DefaultType of 0x00000000 must be supported by this protocol. @param ActionRequired A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" in Section 9.1 for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again. @retval EFI_SUCCESS The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ActionRequired is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the configuration type specified by DefaultType. @retval EFI_DEVICE_ERROR A device error occurred while attempt to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_RESOURCES There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION_FORCE_DEFAULTS)( IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN UINT32 DefaultType, OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired ); /// /// Used to set configuration options for a controller that an EFI Driver is managing. /// struct _EFI_DRIVER_CONFIGURATION_PROTOCOL { EFI_DRIVER_CONFIGURATION_SET_OPTIONS SetOptions; EFI_DRIVER_CONFIGURATION_OPTIONS_VALID OptionsValid; EFI_DRIVER_CONFIGURATION_FORCE_DEFAULTS ForceDefaults; /// /// A Null-terminated ASCII string that contains one or more /// ISO 639-2 language codes. This is the list of language /// codes that this protocol supports. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiDriverConfigurationProtocolGuid; #endif /** @file UEFI Driver Configuration2 Protocol Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_CONFIGURATION2_H__ #define __EFI_DRIVER_CONFIGURATION2_H__ /// /// Global ID for the Driver Configuration Protocol defined in UEFI 2.0 /// #define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \ { \ 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe } \ } typedef struct _EFI_DRIVER_CONFIGURATION2_PROTOCOL EFI_DRIVER_CONFIGURATION2_PROTOCOL; typedef enum { /// /// The controller is still in a usable state. No actions /// are required before this controller can be used again. /// EfiDriverConfigurationActionNone = 0, /// /// The driver has detected that the controller is not in a /// usable state, and it needs to be stopped. /// EfiDriverConfigurationActionStopController = 1, /// /// This controller needs to be stopped and restarted /// before it can be used again. /// EfiDriverConfigurationActionRestartController = 2, /// /// A configuration change has been made that requires the platform to be restarted before /// the controller can be used again. /// EfiDriverConfigurationActionRestartPlatform = 3, EfiDriverConfigurationActionMaximum } EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED; #define EFI_DRIVER_CONFIGURATION_SAFE_DEFAULTS 0x00000000 #define EFI_DRIVER_CONFIGURATION_MANUFACTURING_DEFAULTS 0x00000001 #define EFI_DRIVER_CONFIGURATION_CUSTOM_DEFAULTS 0x00000002 #define EFI_DRIVER_CONFIGURATION_PERORMANCE_DEFAULTS 0x00000003 /** Allows the user to set controller specific options for a controller that a driver is currently managing. @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. @param ControllerHandle The handle of the controller to set options on. @param ChildHandle The handle of the child controller to set options on. This is an optional parameter that may be NULL. It will be NULL for device drivers, and for bus drivers that wish to set options for the bus controller. It will not be NULL for a bus driver that wishes to set options for one of its child controllers. @param Language A Null-terminated ASCII string that contains one or more RFC 4646 language codes. This is the list of language codes that this protocol supports. The number of languages supported by a driver is up to the driver writer. @param ActionRequired A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again. @retval EFI_SUCCESS The driver specified by This successfully set the configuration options for the controller specified by ControllerHandle. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ActionRequired is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support setting configuration options for the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. @retval EFI_DEVICE_ERROR A device error occurred while attempting to set the configuration options for the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_RESOURCES There are not enough resources available to set the configuration options for the controller specified by ControllerHandle and ChildHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION2_SET_OPTIONS)( IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired ); /** Tests to see if a controller's current configuration options are valid. @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. @param ControllerHandle The handle of the controller to test if it's current configuration options are valid. @param ChildHandle The handle of the child controller to test if it's current configuration options are valid. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to test the configuration options for the bus controller. It will not be NULL for a bus driver that wishes to test configuration options for one of its child controllers. @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle that is being managed by the driver specified by This has a valid set of configuration options. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle that is being managed by the driver specified by This has an invalid set of configuration options. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION2_OPTIONS_VALID)( IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL ); /** Forces a driver to set the default configuration options for a controller. @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. @param ControllerHandle The handle of the controller to force default configuration options on. @param ChildHandle The handle of the child controller to force default configuration options on This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to force default configuration options for the bus controller. It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers. @param DefaultType The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle. See Table 9-1 for legal values. A DefaultType of 0x00000000 must be supported by this protocol. @param ActionRequired A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" in Section 9.1 for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again. @retval EFI_SUCCESS The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ActionRequired is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the configuration type specified by DefaultType. @retval EFI_DEVICE_ERROR A device error occurred while attempt to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_RESOURCES There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_CONFIGURATION2_FORCE_DEFAULTS)( IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN UINT32 DefaultType, OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired ); /// /// Used to set configuration options for a controller that an EFI Driver is managing. /// struct _EFI_DRIVER_CONFIGURATION2_PROTOCOL { EFI_DRIVER_CONFIGURATION2_SET_OPTIONS SetOptions; EFI_DRIVER_CONFIGURATION2_OPTIONS_VALID OptionsValid; EFI_DRIVER_CONFIGURATION2_FORCE_DEFAULTS ForceDefaults; /// /// A Null-terminated ASCII string that contains one or more RFC 4646 /// language codes. This is the list of language codes that this protocol supports. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiDriverConfiguration2ProtocolGuid; #endif /** @file EFI Driver Diagnostics Protocol Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_DIAGNOSTICS_H__ #define __EFI_DRIVER_DIAGNOSTICS_H__ /// /// The global ID for the Driver Diagnostics Protocol as defined in EFI 1.1. /// #define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \ { \ 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL EFI_DRIVER_DIAGNOSTICS_PROTOCOL; typedef enum { /// /// Performs standard diagnostics on the controller. /// EfiDriverDiagnosticTypeStandard = 0, /// /// This is an optional diagnostic type that performs diagnostics on the controller that may /// take an extended amount of time to execute. /// EfiDriverDiagnosticTypeExtended = 1, /// /// This is an optional diagnostic type that performs diagnostics on the controller that are /// suitable for a manufacturing and test environment. /// EfiDriverDiagnosticTypeManufacturing = 2, /// /// This is an optional diagnostic type that would only be used in the situation where an /// EFI_NOT_READY had been returned by a previous call to RunDiagnostics() /// and there is a desire to cancel the current running diagnostics operation. /// EfiDriverDiagnosticTypeCancel = 3, EfiDriverDiagnosticTypeMaximum } EFI_DRIVER_DIAGNOSTIC_TYPE; /** Runs diagnostics on a controller. @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance. @param ControllerHandle The handle of the controller to run diagnostics on. @param ChildHandle The handle of the child controller to run diagnostics on This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for a bus drivers that wish to run diagnostics on the bus controller. It will not be NULL for a bus driver that wishes to run diagnostics on one of its child controllers. @param DiagnosticType Indicates type of diagnostics to perform on the controller specified by ControllerHandle and ChildHandle. See "Related Definitions" for the list of supported types. @param Language A pointer to a three character ISO 639-2 language identifier. This is the language in which the optional error message should be returned in Buffer, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. @param ErrorType A GUID that defines the format of the data returned in Buffer. @param BufferSize The size, in bytes, of the data returned in Buffer. @param Buffer A buffer that contains a Null-terminated string plus some additional data whose format is defined by ErrorType. Buffer is allocated by this function with AllocatePool(), and it is the caller's responsibility to free it with a call to FreePool(). @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle passed the diagnostic. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER ErrorType is NULL. @retval EFI_INVALID_PARAMETER BufferType is NULL. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support running diagnostics for the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the type of diagnostic specified by DiagnosticType. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete the diagnostics. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return the status information in ErrorType, BufferSize, and Buffer. @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle did not pass the diagnostic. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS)( IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, IN CHAR8 *Language, OUT EFI_GUID **ErrorType, OUT UINTN *BufferSize, OUT CHAR16 **Buffer ); /// /// Used to perform diagnostics on a controller that an EFI Driver is managing. /// struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL { EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS RunDiagnostics; /// /// A Null-terminated ASCII string that contains one or more ISO 639-2 /// language codes. This is the list of language codes that this protocol supports. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiDriverDiagnosticsProtocolGuid; #endif /** @file UEFI Driver Diagnostics2 Protocol Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_DIAGNOSTICS2_H__ #define __EFI_DRIVER_DIAGNOSTICS2_H__ #include #define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \ { \ 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63 } \ } typedef struct _EFI_DRIVER_DIAGNOSTICS2_PROTOCOL EFI_DRIVER_DIAGNOSTICS2_PROTOCOL; /** Runs diagnostics on a controller. @param This A pointer to the EFI_DRIVER_DIAGNOSTICS2_PROTOCOL instance. @param ControllerHandle The handle of the controller to run diagnostics on. @param ChildHandle The handle of the child controller to run diagnostics on This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to run diagnostics on the bus controller. It will not be NULL for a bus driver that wishes to run diagnostics on one of its child controllers. @param DiagnosticType Indicates the type of diagnostics to perform on the controller specified by ControllerHandle and ChildHandle. See "Related Definitions" for the list of supported types. @param Language A pointer to a Null-terminated ASCII string array indicating the language. This is the language of the driver name that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. Language is specified in RFC 4646 language code format. @param ErrorType A GUID that defines the format of the data returned in Buffer. @param BufferSize The size, in bytes, of the data returned in Buffer. @param Buffer A buffer that contains a Null-terminated Unicode string plus some additional data whose format is defined by ErrorType. Buffer is allocated by this function with AllocatePool(), and it is the caller's responsibility to free it with a call to FreePool(). @retval EFI_SUCCESS The controller specified by ControllerHandle and ChildHandle passed the diagnostic. @retval EFI_ACCESS_DENIED The request for initiating diagnostics was unable to be complete due to some underlying hardware or software state. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER ErrorType is NULL. @retval EFI_INVALID_PARAMETER BufferType is NULL. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The driver specified by This does not support running diagnostics for the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the type of diagnostic specified by DiagnosticType. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete the diagnostics. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return the status information in ErrorType, BufferSize, and Buffer. @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and ChildHandle did not pass the diagnostic. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS)( IN EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, IN CHAR8 *Language, OUT EFI_GUID **ErrorType, OUT UINTN *BufferSize, OUT CHAR16 **Buffer ); /// /// Used to perform diagnostics on a controller that an EFI Driver is managing. /// struct _EFI_DRIVER_DIAGNOSTICS2_PROTOCOL { EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS RunDiagnostics; /// /// A Null-terminated ASCII string that contains one or more RFC 4646 /// language codes. This is the list of language codes that this protocol supports. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiDriverDiagnostics2ProtocolGuid; #endif /** @file UEFI Driver Family Protocol Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_DRIVER_FAMILY_OVERRIDE_H__ #define __EFI_DRIVER_FAMILY_OVERRIDE_H__ #define EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID \ { \ 0xb1ee129e, 0xda36, 0x4181, { 0x91, 0xf8, 0x4, 0xa4, 0x92, 0x37, 0x66, 0xa7 } \ } typedef struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL; // // Prototypes for the Driver Family Override Protocol // // /** This function returns the version value associated with the driver specified by This. Retrieves the version of the driver that is used by the EFI Boot Service ConnectController() to sort the set of Driver Binding Protocols in order from highest priority to lowest priority. For drivers that support the Driver Family Override Protocol, those drivers are sorted so that the drivers with higher values returned by GetVersion() are higher priority than drivers that return lower values from GetVersion(). @param This A pointer to the EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL instance. @return The version value associated with the driver specified by This. **/ typedef UINT32 (EFIAPI *EFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION)( IN EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *This ); /// /// When installed, the Driver Family Override Protocol produces a GUID that represents /// a family of drivers. Drivers with the same GUID are members of the same family /// When drivers are connected to controllers, drivers with a higher revision value /// in the same driver family are connected with a higher priority than drivers /// with a lower revision value in the same driver family. The EFI Boot Service /// Connect Controller uses five rules to build a prioritized list of drivers when /// a request is made to connect a driver to a controller. The Driver Family Protocol /// rule is between the Platform Specific Driver Override Protocol and above the /// Bus Specific Driver Override Protocol. /// struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL { EFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION GetVersion; }; extern EFI_GUID gEfiDriverFamilyOverrideProtocolGuid; #endif /** @file EFI Driver Health Protocol definitions. When installed, the Driver Health Protocol produces a collection of services that allow the health status for a controller to be retrieved. If a controller is not in a usable state, status messages may be reported to the user, repair operations can be invoked, and the user may be asked to make software and/or hardware configuration changes. The Driver Health Protocol is optionally produced by a driver that follows the EFI Driver Model. If an EFI Driver needs to report health status to the platform, provide warning or error messages to the user, perform length repair operations, or request the user to make hardware or software configuration changes, then the Driver Health Protocol must be produced. A controller that is managed by driver that follows the EFI Driver Model and produces the Driver Health Protocol must report the current health of the controllers that the driver is currently managing. The controller can initially be healthy, failed, require repair, or require configuration. If a controller requires configuration, and the user make configuration changes, the controller may then need to be reconnected or the system may need to be rebooted for the configuration changes to take affect. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is defined in UEFI Specification 2.3d **/ #ifndef __EFI_DRIVER_HEALTH_H__ #define __EFI_DRIVER_HEALTH_H__ #define EFI_DRIVER_HEALTH_PROTOCOL_GUID \ { \ 0x2a534210, 0x9280, 0x41d8, { 0xae, 0x79, 0xca, 0xda, 0x1, 0xa2, 0xb1, 0x27 } \ } typedef struct _EFI_DRIVER_HEALTH_PROTOCOL EFI_DRIVER_HEALTH_PROTOCOL; /// /// EFI_DRIVER_HEALTH_HEALTH_STATUS /// typedef enum { EfiDriverHealthStatusHealthy, EfiDriverHealthStatusRepairRequired, EfiDriverHealthStatusConfigurationRequired, EfiDriverHealthStatusFailed, EfiDriverHealthStatusReconnectRequired, EfiDriverHealthStatusRebootRequired } EFI_DRIVER_HEALTH_STATUS; /// /// EFI_DRIVER_HEALTH_HII_MESSAGE /// typedef struct { EFI_HII_HANDLE HiiHandle; EFI_STRING_ID StringId; /// /// 64-bit numeric value of the warning/error specified by this message. /// A value of 0x0000000000000000 is used to indicate that MessageCode is not specified. /// The values 0x0000000000000001 to 0x0fffffffffffffff are reserved for allocation by the UEFI Specification. /// The values 0x1000000000000000 to 0x1fffffffffffffff are reserved for IHV-developed drivers. /// The values 0x8000000000000000 to 0x8fffffffffffffff is reserved for platform/OEM drivers. /// All other values are reserved and should not be used. /// UINT64 MessageCode; } EFI_DRIVER_HEALTH_HII_MESSAGE; /** Reports the progress of a repair operation @param[in] Value A value between 0 and Limit that identifies the current progress of the repair operation. @param[in] Limit The maximum value of Value for the current repair operation. For example, a driver that wants to specify progress in percent would use a Limit value of 100. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_HEALTH_REPAIR_NOTIFY)( IN UINTN Value, IN UINTN Limit ); /** Retrieves the health status of a controller in the platform. This function can also optionally return warning messages, error messages, and a set of HII Forms that may be repair a controller that is not proper configured. @param[in] This A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance. @param[in] ControllerHandle The handle of the controller to retrieve the health status on. This is an optional parameter that may be NULL. If this parameter is NULL, then the value of ChildHandle is ignored, and the combined health status of all the devices that the driver is managing is returned. @param[in] ChildHandle The handle of the child controller to retrieve the health status on. This is an optional parameter that may be NULL. This parameter is ignored of ControllerHandle is NULL. It will be NULL for device drivers. It will also be NULL for bus drivers when an attempt is made to collect the health status of the bus controller. If will not be NULL when an attempt is made to collect the health status for a child controller produced by the driver. @param[out] HealthStatus A pointer to the health status that is returned by this function. This is an optional parameter that may be NULL. This parameter is ignored of ControllerHandle is NULL. The health status for the controller specified by ControllerHandle and ChildHandle is returned. @param[out] MessageList A pointer to an array of warning or error messages associated with the controller specified by ControllerHandle and ChildHandle. This is an optional parameter that may be NULL. MessageList is allocated by this function with the EFI Boot Service AllocatePool(), and it is the caller's responsibility to free MessageList with the EFI Boot Service FreePool(). Each message is specified by tuple of an EFI_HII_HANDLE and an EFI_STRING_ID. The array of messages is terminated by tuple containing a EFI_HII_HANDLE with a value of NULL. The EFI_HII_STRING_PROTOCOL.GetString() function can be used to retrieve the warning or error message as a Null-terminated string in a specific language. Messages may be returned for any of the HealthStatus values except EfiDriverHealthStatusReconnectRequired and EfiDriverHealthStatusRebootRequired. @param[out] FormHiiHandle A pointer to the HII handle containing the HII form used when configuration is required. The HII handle is associated with the controller specified by ControllerHandle and ChildHandle. If this is NULL, then no HII form is available. An HII handle will only be returned with a HealthStatus value of EfiDriverHealthStatusConfigurationRequired. @retval EFI_SUCCESS ControllerHandle is NULL, and all the controllers managed by this driver specified by This have a health status of EfiDriverHealthStatusHealthy with no warning messages to be returned. The ChildHandle, HealthStatus, MessageList, and FormList parameters are ignored. @retval EFI_DEVICE_ERROR ControllerHandle is NULL, and one or more of the controllers managed by this driver specified by This do not have a health status of EfiDriverHealthStatusHealthy. The ChildHandle, HealthStatus, MessageList, and FormList parameters are ignored. @retval EFI_DEVICE_ERROR ControllerHandle is NULL, and one or more of the controllers managed by this driver specified by This have one or more warning and/or error messages. The ChildHandle, HealthStatus, MessageList, and FormList parameters are ignored. @retval EFI_SUCCESS ControllerHandle is not NULL and the health status of the controller specified by ControllerHandle and ChildHandle was returned in HealthStatus. A list of warning and error messages may be optionally returned in MessageList, and a list of HII Forms may be optionally returned in FormList. @retval EFI_UNSUPPORTED ControllerHandle is not NULL, and the controller specified by ControllerHandle and ChildHandle is not currently being managed by the driver specified by This. @retval EFI_INVALID_PARAMETER HealthStatus is NULL. @retval EFI_OUT_OF_RESOURCES MessageList is not NULL, and there are not enough resource available to allocate memory for MessageList. **/ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_HEALTH_GET_HEALTH_STATUS)( IN EFI_DRIVER_HEALTH_PROTOCOL *This, IN EFI_HANDLE ControllerHandle OPTIONAL, IN EFI_HANDLE ChildHandle OPTIONAL, OUT EFI_DRIVER_HEALTH_STATUS *HealthStatus, OUT EFI_DRIVER_HEALTH_HII_MESSAGE **MessageList OPTIONAL, OUT EFI_HII_HANDLE *FormHiiHandle OPTIONAL ); /** Performs a repair operation on a controller in the platform. This function can optionally report repair progress information back to the platform. @param[in] This A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance. @param[in] ControllerHandle The handle of the controller to repair. @param[in] ChildHandle The handle of the child controller to repair. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers when an attempt is made to repair a bus controller. If will not be NULL when an attempt is made to repair a child controller produced by the driver. @param[in] RepairNotify A notification function that may be used by a driver to report the progress of the repair operation. This is an optional parameter that may be NULL. @retval EFI_SUCCESS An attempt to repair the controller specified by ControllerHandle and ChildHandle was performed. The result of the repair operation can bet determined by calling GetHealthStatus(). @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_OF_RESOURCES There are not enough resources to perform the repair operation. */ typedef EFI_STATUS (EFIAPI *EFI_DRIVER_HEALTH_REPAIR)( IN EFI_DRIVER_HEALTH_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN EFI_DRIVER_HEALTH_REPAIR_NOTIFY RepairNotify OPTIONAL ); /// /// When installed, the Driver Health Protocol produces a collection of services /// that allow the health status for a controller to be retrieved. If a controller /// is not in a usable state, status messages may be reported to the user, repair /// operations can be invoked, and the user may be asked to make software and/or /// hardware configuration changes. /// struct _EFI_DRIVER_HEALTH_PROTOCOL { EFI_DRIVER_HEALTH_GET_HEALTH_STATUS GetHealthStatus; EFI_DRIVER_HEALTH_REPAIR Repair; }; extern EFI_GUID gEfiDriverHealthProtocolGuid; #endif /** @file The protocol provides information about the version of the EFI specification that a driver is following. This protocol is required for EFI drivers that are on PCI and other plug-in cards. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __DRIVER_SUPPORTED_EFI_VERSION_H__ #define __DRIVER_SUPPORTED_EFI_VERSION_H__ #define EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL_GUID \ { 0x5c198761, 0x16a8, 0x4e69, { 0x97, 0x2c, 0x89, 0xd6, 0x79, 0x54, 0xf8, 0x1d } } /// /// The EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL provides a /// mechanism for an EFI driver to publish the version of the EFI /// specification it conforms to. This protocol must be placed on /// the driver's image handle when the driver's entry point is /// called. /// typedef struct _EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL { /// /// The size, in bytes, of the entire structure. Future versions of this /// specification may grow the size of the structure. /// UINT32 Length; /// /// The latest version of the UEFI specification that this driver conforms to. /// UINT32 FirmwareVersion; } EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL; extern EFI_GUID gEfiDriverSupportedEfiVersionProtocolGuid; #endif /** @file Describes the protocol interface to the EBC interpreter. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_EBC_PROTOCOL_H__ #define __EFI_EBC_PROTOCOL_H__ #define EFI_EBC_INTERPRETER_PROTOCOL_GUID \ { \ 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7 } \ } // // Define OPCODES // #define OPCODE_BREAK 0x00 #define OPCODE_JMP 0x01 #define OPCODE_JMP8 0x02 #define OPCODE_CALL 0x03 #define OPCODE_RET 0x04 #define OPCODE_CMPEQ 0x05 #define OPCODE_CMPLTE 0x06 #define OPCODE_CMPGTE 0x07 #define OPCODE_CMPULTE 0x08 #define OPCODE_CMPUGTE 0x09 #define OPCODE_NOT 0x0A #define OPCODE_NEG 0x0B #define OPCODE_ADD 0x0C #define OPCODE_SUB 0x0D #define OPCODE_MUL 0x0E #define OPCODE_MULU 0x0F #define OPCODE_DIV 0x10 #define OPCODE_DIVU 0x11 #define OPCODE_MOD 0x12 #define OPCODE_MODU 0x13 #define OPCODE_AND 0x14 #define OPCODE_OR 0x15 #define OPCODE_XOR 0x16 #define OPCODE_SHL 0x17 #define OPCODE_SHR 0x18 #define OPCODE_ASHR 0x19 #define OPCODE_EXTNDB 0x1A #define OPCODE_EXTNDW 0x1B #define OPCODE_EXTNDD 0x1C #define OPCODE_MOVBW 0x1D #define OPCODE_MOVWW 0x1E #define OPCODE_MOVDW 0x1F #define OPCODE_MOVQW 0x20 #define OPCODE_MOVBD 0x21 #define OPCODE_MOVWD 0x22 #define OPCODE_MOVDD 0x23 #define OPCODE_MOVQD 0x24 #define OPCODE_MOVSNW 0x25 // Move signed natural with word index #define OPCODE_MOVSND 0x26 // Move signed natural with dword index // // #define OPCODE_27 0x27 // #define OPCODE_MOVQQ 0x28 // Does this go away? #define OPCODE_LOADSP 0x29 #define OPCODE_STORESP 0x2A #define OPCODE_PUSH 0x2B #define OPCODE_POP 0x2C #define OPCODE_CMPIEQ 0x2D #define OPCODE_CMPILTE 0x2E #define OPCODE_CMPIGTE 0x2F #define OPCODE_CMPIULTE 0x30 #define OPCODE_CMPIUGTE 0x31 #define OPCODE_MOVNW 0x32 #define OPCODE_MOVND 0x33 // // #define OPCODE_34 0x34 // #define OPCODE_PUSHN 0x35 #define OPCODE_POPN 0x36 #define OPCODE_MOVI 0x37 #define OPCODE_MOVIN 0x38 #define OPCODE_MOVREL 0x39 // // Bit masks for opcode encodings // #define OPCODE_M_OPCODE 0x3F // bits of interest for first level decode #define OPCODE_M_IMMDATA 0x80 #define OPCODE_M_IMMDATA64 0x40 #define OPCODE_M_64BIT 0x40 // for CMP #define OPCODE_M_RELADDR 0x10 // for CALL instruction #define OPCODE_M_CMPI32_DATA 0x80 // for CMPI #define OPCODE_M_CMPI64 0x40 // for CMPI 32 or 64 bit comparison #define OPERAND_M_MOVIN_N 0x80 #define OPERAND_M_CMPI_INDEX 0x10 // // Masks for instructions that encode presence of indexes for operand1 and/or // operand2. // #define OPCODE_M_IMMED_OP1 0x80 #define OPCODE_M_IMMED_OP2 0x40 // // Bit masks for operand encodings // #define OPERAND_M_INDIRECT1 0x08 #define OPERAND_M_INDIRECT2 0x80 #define OPERAND_M_OP1 0x07 #define OPERAND_M_OP2 0x70 // // Masks for data manipulation instructions // #define DATAMANIP_M_64 0x40 // 64-bit width operation #define DATAMANIP_M_IMMDATA 0x80 // // For MOV instructions, need a mask for the opcode when immediate // data applies to R2. // #define OPCODE_M_IMMED_OP2 0x40 // // The MOVI/MOVIn instructions use bit 6 of operands byte to indicate // if an index is present. Then bits 4 and 5 are used to indicate the width // of the move. // #define MOVI_M_IMMDATA 0x40 #define MOVI_M_DATAWIDTH 0xC0 #define MOVI_DATAWIDTH16 0x40 #define MOVI_DATAWIDTH32 0x80 #define MOVI_DATAWIDTH64 0xC0 #define MOVI_M_MOVEWIDTH 0x30 #define MOVI_MOVEWIDTH8 0x00 #define MOVI_MOVEWIDTH16 0x10 #define MOVI_MOVEWIDTH32 0x20 #define MOVI_MOVEWIDTH64 0x30 // // Masks for CALL instruction encodings // #define OPERAND_M_RELATIVE_ADDR 0x10 #define OPERAND_M_NATIVE_CALL 0x20 // // Masks for decoding push/pop instructions // #define PUSHPOP_M_IMMDATA 0x80 // opcode bit indicating immediate data #define PUSHPOP_M_64 0x40 // opcode bit indicating 64-bit operation // // Mask for operand of JMP instruction // #define JMP_M_RELATIVE 0x10 #define JMP_M_CONDITIONAL 0x80 #define JMP_M_CS 0x40 // // Macros to determine if a given operand is indirect // #define OPERAND1_INDIRECT(op) ((op) & OPERAND_M_INDIRECT1) #define OPERAND2_INDIRECT(op) ((op) & OPERAND_M_INDIRECT2) // // Macros to extract the operands from second byte of instructions // #define OPERAND1_REGNUM(op) ((op) & OPERAND_M_OP1) #define OPERAND2_REGNUM(op) (((op) & OPERAND_M_OP2) >> 4) #define OPERAND1_CHAR(op) ('0' + OPERAND1_REGNUM (op)) #define OPERAND2_CHAR(op) ('0' + OPERAND2_REGNUM (op)) // // Condition masks usually for byte 1 encodings of code // #define CONDITION_M_CONDITIONAL 0x80 #define CONDITION_M_CS 0x40 /// /// Protocol Guid Name defined in spec. /// #define EFI_EBC_PROTOCOL_GUID EFI_EBC_INTERPRETER_PROTOCOL_GUID /// /// Define for forward reference. /// typedef struct _EFI_EBC_PROTOCOL EFI_EBC_PROTOCOL; /** Creates a thunk for an EBC entry point, returning the address of the thunk. A PE32+ EBC image, like any other PE32+ image, contains an optional header that specifies the entry point for image execution. However, for EBC images, this is the entry point of EBC instructions, so is not directly executable by the native processor. Therefore, when an EBC image is loaded, the loader must call this service to get a pointer to native code (thunk) that can be executed, which will invoke the interpreter to begin execution at the original EBC entry point. @param This A pointer to the EFI_EBC_PROTOCOL instance. @param ImageHandle Handle of image for which the thunk is being created. @param EbcEntryPoint Address of the actual EBC entry point or protocol service the thunk should call. @param Thunk Returned pointer to a thunk created. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned. @retval EFI_OUT_OF_RESOURCES Memory could not be allocated for the thunk. **/ typedef EFI_STATUS (EFIAPI *EFI_EBC_CREATE_THUNK)( IN EFI_EBC_PROTOCOL *This, IN EFI_HANDLE ImageHandle, IN VOID *EbcEntryPoint, OUT VOID **Thunk ); /** Called prior to unloading an EBC image from memory. This function is called after an EBC image has exited, but before the image is actually unloaded. It is intended to provide the interpreter with the opportunity to perform any cleanup that may be necessary as a result of loading and executing the image. @param This A pointer to the EFI_EBC_PROTOCOL instance. @param ImageHandle Image handle of the EBC image that is being unloaded from memory. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Image handle is not recognized as belonging to an EBC image that has been executed. **/ typedef EFI_STATUS (EFIAPI *EFI_EBC_UNLOAD_IMAGE)( IN EFI_EBC_PROTOCOL *This, IN EFI_HANDLE ImageHandle ); /** This is the prototype for the Flush callback routine. A pointer to a routine of this type is passed to the EBC EFI_EBC_REGISTER_ICACHE_FLUSH protocol service. @param Start The beginning physical address to flush from the processor's instruction cache. @param Length The number of bytes to flush from the processor's instruction cache. @retval EFI_SUCCESS The function completed successfully. **/ typedef EFI_STATUS (EFIAPI *EBC_ICACHE_FLUSH)( IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length ); /** Registers a callback function that the EBC interpreter calls to flush the processor instruction cache following creation of thunks. @param This A pointer to the EFI_EBC_PROTOCOL instance. @param Flush Pointer to a function of type EBC_ICACH_FLUSH. @retval EFI_SUCCESS The function completed successfully. **/ typedef EFI_STATUS (EFIAPI *EFI_EBC_REGISTER_ICACHE_FLUSH)( IN EFI_EBC_PROTOCOL *This, IN EBC_ICACHE_FLUSH Flush ); /** Called to get the version of the interpreter. This function is called to get the version of the loaded EBC interpreter. The value and format of the returned version is identical to that returned by the EBC BREAK 1 instruction. @param This A pointer to the EFI_EBC_PROTOCOL instance. @param Version Pointer to where to store the returned version of the interpreter. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Version pointer is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_EBC_GET_VERSION)( IN EFI_EBC_PROTOCOL *This, IN OUT UINT64 *Version ); /// /// The EFI EBC protocol provides services to load and execute EBC images, which will typically be /// loaded into option ROMs. The image loader will load the EBC image, perform standard relocations, /// and invoke the CreateThunk() service to create a thunk for the EBC image's entry point. The /// image can then be run using the standard EFI start image services. /// struct _EFI_EBC_PROTOCOL { EFI_EBC_CREATE_THUNK CreateThunk; EFI_EBC_UNLOAD_IMAGE UnloadImage; EFI_EBC_REGISTER_ICACHE_FLUSH RegisterICacheFlush; EFI_EBC_GET_VERSION GetVersion; }; // // Extern the global EBC protocol GUID // extern EFI_GUID gEfiEbcProtocolGuid; #endif /** @file EDID Active Protocol from the UEFI 2.0 specification. Placed on the video output device child handle that is actively displaying output. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __EDID_ACTIVE_H__ #define __EDID_ACTIVE_H__ #define EFI_EDID_ACTIVE_PROTOCOL_GUID \ { \ 0xbd8c1056, 0x9f36, 0x44ec, {0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 } \ } /// /// This protocol contains the EDID information for an active video output device. This is either the /// EDID information retrieved from the EFI_EDID_OVERRIDE_PROTOCOL if an override is /// available, or an identical copy of the EDID information from the /// EFI_EDID_DISCOVERED_PROTOCOL if no overrides are available. /// typedef struct { /// /// The size, in bytes, of the Edid buffer. 0 if no EDID information /// is available from the video output device. Otherwise, it must be a /// minimum of 128 bytes. /// UINT32 SizeOfEdid; /// /// A pointer to a read-only array of bytes that contains the EDID /// information for an active video output device. This pointer is /// NULL if no EDID information is available for the video output /// device. The minimum size of a valid Edid buffer is 128 bytes. /// EDID information is defined in the E-EDID EEPROM /// specification published by VESA (www.vesa.org). /// UINT8 *Edid; } EFI_EDID_ACTIVE_PROTOCOL; extern EFI_GUID gEfiEdidActiveProtocolGuid; #endif /** @file EDID Discovered Protocol from the UEFI 2.0 specification. This protocol is placed on the video output device child handle. It represents the EDID information being used for the output device represented by the child handle. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __EDID_DISCOVERED_H__ #define __EDID_DISCOVERED_H__ #define EFI_EDID_DISCOVERED_PROTOCOL_GUID \ { \ 0x1c0c34f6, 0xd380, 0x41fa, {0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa } \ } /// /// This protocol contains the EDID information retrieved from a video output device. /// typedef struct { /// /// The size, in bytes, of the Edid buffer. 0 if no EDID information /// is available from the video output device. Otherwise, it must be a /// minimum of 128 bytes. /// UINT32 SizeOfEdid; /// /// A pointer to a read-only array of bytes that contains the EDID /// information for an active video output device. This pointer is /// NULL if no EDID information is available for the video output /// device. The minimum size of a valid Edid buffer is 128 bytes. /// EDID information is defined in the E-EDID EEPROM /// specification published by VESA (www.vesa.org). /// UINT8 *Edid; } EFI_EDID_DISCOVERED_PROTOCOL; extern EFI_GUID gEfiEdidDiscoveredProtocolGuid; #endif /** @file EDID Override Protocol from the UEFI 2.0 specification. Allow platform to provide EDID information to the producer of the Graphics Output protocol. Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #ifndef __EDID_OVERRIDE_H__ #define __EDID_OVERRIDE_H__ #define EFI_EDID_OVERRIDE_PROTOCOL_GUID \ { \ 0x48ecb431, 0xfb72, 0x45c0, {0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x4, 0xb, 0xd5 } \ } typedef struct _EFI_EDID_OVERRIDE_PROTOCOL EFI_EDID_OVERRIDE_PROTOCOL; #define EFI_EDID_OVERRIDE_DONT_OVERRIDE 0x01 #define EFI_EDID_OVERRIDE_ENABLE_HOT_PLUG 0x02 /** Returns policy information and potentially a replacement EDID for the specified video output device. @param This The EFI_EDID_OVERRIDE_PROTOCOL instance. @param ChildHandle A child handle produced by the Graphics Output EFI driver that represents a video output device. @param Attributes The attributes associated with ChildHandle video output device. @param EdidSize A pointer to the size, in bytes, of the Edid buffer. @param Edid A pointer to callee allocated buffer that contains the EDID that should be used for ChildHandle. A value of NULL represents no EDID override for ChildHandle. @retval EFI_SUCCESS Valid overrides returned for ChildHandle. @retval EFI_UNSUPPORTED ChildHandle has no overrides. **/ typedef EFI_STATUS (EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID)( IN EFI_EDID_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE *ChildHandle, OUT UINT32 *Attributes, IN OUT UINTN *EdidSize, IN OUT UINT8 **Edid ); /// /// This protocol is produced by the platform to allow the platform to provide /// EDID information to the producer of the Graphics Output protocol. /// struct _EFI_EDID_OVERRIDE_PROTOCOL { EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid; }; extern EFI_GUID gEfiEdidOverrideProtocolGuid; #endif /** @file This file provides control over block-oriented firmware devices. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.0 and 1.2. **/ #ifndef __FIRMWARE_VOLUME_BLOCK_H__ #define __FIRMWARE_VOLUME_BLOCK_H__ // // EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL is defined in PI 1.0 spec and its GUID value // is later updated to be the same as that of EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL // defined in PI 1.2 spec. // #define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \ { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } #define EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID \ { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } typedef struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL; typedef EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL; /** The GetAttributes() function retrieves the attributes and current settings of the block. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. @retval EFI_SUCCESS The firmware volume attributes were returned. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_GET_ATTRIBUTES)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, OUT EFI_FVB_ATTRIBUTES_2 *Attributes ); /** The SetAttributes() function sets configurable firmware volume attributes and returns the new settings of the firmware volume. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 that contains the desired firmware volume settings. On successful return, it contains the new settings of the firmware volume. Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. @retval EFI_SUCCESS The firmware volume attributes were returned. @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities as declared in the firmware volume header. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_SET_ATTRIBUTES)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes ); /** The GetPhysicalAddress() function retrieves the base address of a memory-mapped firmware volume. This function should be called only for memory-mapped firmware volumes. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Address Pointer to a caller-allocated EFI_PHYSICAL_ADDRESS that, on successful return from GetPhysicalAddress(), contains the base address of the firmware volume. @retval EFI_SUCCESS The firmware volume base address was returned. @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_GET_PHYSICAL_ADDRESS)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, OUT EFI_PHYSICAL_ADDRESS *Address ); /** The GetBlockSize() function retrieves the size of the requested block. It also returns the number of additional blocks with the identical size. The GetBlockSize() function is used to retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Lba Indicates the block for which to return the size. @param BlockSize Pointer to a caller-allocated UINTN in which the size of the block is returned. @param NumberOfBlocks Pointer to a caller-allocated UINTN in which the number of consecutive blocks, starting with Lba, is returned. All blocks in this range have a size of BlockSize. @retval EFI_SUCCESS The firmware volume base address was returned. @retval EFI_INVALID_PARAMETER The requested LBA is out of range. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_GET_BLOCK_SIZE)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, IN EFI_LBA Lba, OUT UINTN *BlockSize, OUT UINTN *NumberOfBlocks ); /** Reads the specified number of bytes into a buffer from the specified block. The Read() function reads the requested number of bytes from the requested block and stores them in the provided buffer. Implementations should be mindful that the firmware volume might be in the ReadDisabled state. If it is in this state, the Read() function must return the status code EFI_ACCESS_DENIED without modifying the contents of the buffer. The Read() function must also prevent spanning block boundaries. If a read is requested that would span a block boundary, the read must read up to the boundary but not beyond. The output parameter NumBytes must be set to correctly indicate the number of bytes actually read. The caller must be aware that a read may be partially completed. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Lba The starting logical block index from which to read. @param Offset Offset into the block at which to begin reading. @param NumBytes Pointer to a UINTN. At entry, *NumBytes contains the total size of the buffer. At exit, *NumBytes contains the total number of bytes read. @param Buffer Pointer to a caller-allocated buffer that will be used to hold the data that is read. @retval EFI_SUCCESS The firmware volume was read successfully, and contents are in Buffer. @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. On output, NumBytes contains the total number of bytes returned in Buffer. @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_READ)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, IN EFI_LBA Lba, IN UINTN Offset, IN OUT UINTN *NumBytes, IN OUT UINT8 *Buffer ); /** Writes the specified number of bytes from the input buffer to the block. The Write() function writes the specified number of bytes from the provided buffer to the specified block and offset. If the firmware volume is sticky write, the caller must ensure that all the bits of the specified range to write are in the EFI_FVB_ERASE_POLARITY state before calling the Write() function, or else the result will be unpredictable. This unpredictability arises because, for a sticky-write firmware volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY state but cannot flip it back again. Before calling the Write() function, it is recommended for the caller to first call the EraseBlocks() function to erase the specified block to write. A block erase cycle will transition bits from the (NOT)EFI_FVB_ERASE_POLARITY state back to the EFI_FVB_ERASE_POLARITY state. Implementations should be mindful that the firmware volume might be in the WriteDisabled state. If it is in this state, the Write() function must return the status code EFI_ACCESS_DENIED without modifying the contents of the firmware volume. The Write() function must also prevent spanning block boundaries. If a write is requested that spans a block boundary, the write must store up to the boundary but not beyond. The output parameter NumBytes must be set to correctly indicate the number of bytes actually written. The caller must be aware that a write may be partially completed. All writes, partial or otherwise, must be fully flushed to the hardware before the Write() service returns. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param Lba The starting logical block index to write to. @param Offset Offset into the block at which to begin writing. @param NumBytes The pointer to a UINTN. At entry, *NumBytes contains the total size of the buffer. At exit, *NumBytes contains the total number of bytes actually written. @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. @retval EFI_SUCCESS The firmware volume was written successfully. @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. On output, NumBytes contains the total number of bytes actually written. @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_WRITE)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, IN EFI_LBA Lba, IN UINTN Offset, IN OUT UINTN *NumBytes, IN UINT8 *Buffer ); /// /// EFI_LBA_LIST_TERMINATOR /// #define EFI_LBA_LIST_TERMINATOR 0xFFFFFFFFFFFFFFFFULL /** Erases and initializes a firmware volume block. The EraseBlocks() function erases one or more blocks as denoted by the variable argument list. The entire parameter list of blocks must be verified before erasing any blocks. If a block is requested that does not exist within the associated firmware volume (it has a larger index than the last block of the firmware volume), the EraseBlocks() function must return the status code EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. Implementations should be mindful that the firmware volume might be in the WriteDisabled state. If it is in this state, the EraseBlocks() function must return the status code EFI_ACCESS_DENIED without modifying the contents of the firmware volume. All calls to EraseBlocks() must be fully flushed to the hardware before the EraseBlocks() service returns. @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. @param ... The variable argument list is a list of tuples. Each tuple describes a range of LBAs to erase and consists of the following: - An EFI_LBA that indicates the starting LBA - A UINTN that indicates the number of blocks to erase. The list is terminated with an EFI_LBA_LIST_TERMINATOR. For example, the following indicates that two ranges of blocks (5-7 and 10-11) are to be erased: EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); @retval EFI_SUCCESS The erase request successfully completed. @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. The firmware device may have been partially erased. @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do not exist in the firmware volume. **/ typedef EFI_STATUS (EFIAPI *EFI_FVB_ERASE_BLOCKS)( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, ... ); /// /// The Firmware Volume Block Protocol is the low-level interface /// to a firmware volume. File-level access to a firmware volume /// should not be done using the Firmware Volume Block Protocol. /// Normal access to a firmware volume must use the Firmware /// Volume Protocol. Typically, only the file system driver that /// produces the Firmware Volume Protocol will bind to the /// Firmware Volume Block Protocol. /// struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL { EFI_FVB_GET_ATTRIBUTES GetAttributes; EFI_FVB_SET_ATTRIBUTES SetAttributes; EFI_FVB_GET_PHYSICAL_ADDRESS GetPhysicalAddress; EFI_FVB_GET_BLOCK_SIZE GetBlockSize; EFI_FVB_READ Read; EFI_FVB_WRITE Write; EFI_FVB_ERASE_BLOCKS EraseBlocks; /// /// The handle of the parent firmware volume. /// EFI_HANDLE ParentHandle; }; extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid; extern EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid; #endif /** @file This protocol is defined in UEFI spec. The EFI_FORM_BROWSER2_PROTOCOL is the interface to call for drivers to leverage the EFI configuration driver interface. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_FORM_BROWSER2_H__ #define __EFI_FORM_BROWSER2_H__ #include #define EFI_FORM_BROWSER2_PROTOCOL_GUID \ {0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58 }} typedef struct _EFI_FORM_BROWSER2_PROTOCOL EFI_FORM_BROWSER2_PROTOCOL; /** @param LeftColumn The value that designates the text column where the browser window will begin from the left-hand side of the screen @param RightColumn The value that designates the text column where the browser window will end on the right-hand side of the screen. @param TopRow The value that designates the text row from the top of the screen where the browser window will start. @param BottomRow The value that designates the text row from the bottom of the screen where the browser window will end. **/ typedef struct { UINTN LeftColumn; UINTN RightColumn; UINTN TopRow; UINTN BottomRow; } EFI_SCREEN_DESCRIPTOR; typedef UINTN EFI_BROWSER_ACTION_REQUEST; #define EFI_BROWSER_ACTION_REQUEST_NONE 0 #define EFI_BROWSER_ACTION_REQUEST_RESET 1 #define EFI_BROWSER_ACTION_REQUEST_SUBMIT 2 #define EFI_BROWSER_ACTION_REQUEST_EXIT 3 #define EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT 4 #define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT 5 #define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY 6 #define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD 7 #define EFI_BROWSER_ACTION_REQUEST_RECONNECT 8 /** Initialize the browser to display the specified configuration forms. This function is the primary interface to the internal forms-based browser. The forms browser will display forms associated with the specified Handles. The browser will select all forms in packages which have the specified Type and (for EFI_HII_PACKAGE_TYPE_GUID) the specified PackageGuid. @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL instance @param Handles A pointer to an array of Handles. This value should correspond to the value of the HII form package that is required to be displayed. @param HandleCount The number of Handles specified in Handle. @param FormSetGuid This field points to the EFI_GUID which must match the Guid field or one of the elements of the ClassId field in the EFI_IFR_FORM_SET op-code. If FormsetGuid is NULL, then this function will display the form set class EFI_HII_PLATFORM_SETUP_FORMSET_GUID. @param FormId This field specifies the identifier of the form within the form set to render as the first displayable page. If this field has a value of 0x0000, then the Forms Browser will render the first enabled form in the form set. @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in characters. @param ActionRequest Points to the action recommended by the form. @retval EFI_SUCCESS The function completed successfully @retval EFI_NOT_FOUND The variable was not found. @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. **/ typedef EFI_STATUS (EFIAPI *EFI_SEND_FORM2)( IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, IN EFI_HII_HANDLE *Handle, IN UINTN HandleCount, IN EFI_GUID *FormSetGuid OPTIONAL, IN EFI_FORM_ID FormId OPTIONAL, IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions OPTIONAL, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL ); /** This function is called by a callback handler to retrieve uncommitted state data from the browser. This routine is called by a routine which was called by the browser. This routine called this service in the browser to retrieve or set certain uncommitted state information. @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL instance. @param ResultsDataSize A pointer to the size of the buffer associated with ResultsData. On input, the size in bytes of ResultsData. On output, the size of data returned in ResultsData. @param ResultsData A string returned from an IFR browser or equivalent. The results string will have no routing information in them. @param RetrieveData A BOOLEAN field which allows an agent to retrieve (if RetrieveData = TRUE) data from the uncommitted browser state information or set (if RetrieveData = FALSE) data in the uncommitted browser state information. @param VariableGuid An optional field to indicate the target variable GUID name to use. @param VariableName An optional field to indicate the target human-readable variable name. @retval EFI_SUCCESS The results have been distributed or are awaiting distribution. @retval EFI_OUT_OF_RESOURCES The ResultsDataSize specified was too small to contain the results data. **/ typedef EFI_STATUS (EFIAPI *EFI_BROWSER_CALLBACK2)( IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, IN OUT UINTN *ResultsDataSize, IN OUT EFI_STRING ResultsData, IN CONST BOOLEAN RetrieveData, IN CONST EFI_GUID *VariableGuid OPTIONAL, IN CONST CHAR16 *VariableName OPTIONAL ); /// /// This interface will allow the caller to direct the configuration /// driver to use either the HII database or use the passed-in packet of data. /// struct _EFI_FORM_BROWSER2_PROTOCOL { EFI_SEND_FORM2 SendForm; EFI_BROWSER_CALLBACK2 BrowserCallback; }; extern EFI_GUID gEfiFormBrowser2ProtocolGuid; #endif /** @file Graphics Output Protocol from the UEFI 2.0 specification. Abstraction of a very simple graphics device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __GRAPHICS_OUTPUT_H__ #define __GRAPHICS_OUTPUT_H__ #define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ { \ 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \ } typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL; typedef struct { UINT32 RedMask; UINT32 GreenMask; UINT32 BlueMask; UINT32 ReservedMask; } EFI_PIXEL_BITMASK; typedef enum { /// /// A pixel is 32-bits and byte zero represents red, byte one represents green, /// byte two represents blue, and byte three is reserved. This is the definition /// for the physical frame buffer. The byte values for the red, green, and blue /// components represent the color intensity. This color intensity value range /// from a minimum intensity of 0 to maximum intensity of 255. /// PixelRedGreenBlueReserved8BitPerColor, /// /// A pixel is 32-bits and byte zero represents blue, byte one represents green, /// byte two represents red, and byte three is reserved. This is the definition /// for the physical frame buffer. The byte values for the red, green, and blue /// components represent the color intensity. This color intensity value range /// from a minimum intensity of 0 to maximum intensity of 255. /// PixelBlueGreenRedReserved8BitPerColor, /// /// The Pixel definition of the physical frame buffer. /// PixelBitMask, /// /// This mode does not support a physical frame buffer. /// PixelBltOnly, /// /// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value. /// PixelFormatMax } EFI_GRAPHICS_PIXEL_FORMAT; typedef struct { /// /// The version of this data structure. A value of zero represents the /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification. /// UINT32 Version; /// /// The size of video screen in pixels in the X dimension. /// UINT32 HorizontalResolution; /// /// The size of video screen in pixels in the Y dimension. /// UINT32 VerticalResolution; /// /// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly /// implies that a linear frame buffer is not available for this mode. /// EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; /// /// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask. /// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved. /// EFI_PIXEL_BITMASK PixelInformation; /// /// Defines the number of pixel elements per video memory line. /// UINT32 PixelsPerScanLine; } EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; /** Returns information for an available graphics mode that the graphics device and the set of active video output devices supports. @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. @param ModeNumber The mode number to return information on. @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer. @param Info A pointer to callee allocated buffer that returns information about ModeNumber. @retval EFI_SUCCESS Valid mode information was returned. @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. @retval EFI_INVALID_PARAMETER ModeNumber is not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info ); /** Set the video device into the specified mode and clears the visible portions of the output display to black. @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. @param ModeNumber Abstraction that defines the current video mode. @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. **/ typedef EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber ); typedef struct { UINT8 Blue; UINT8 Green; UINT8 Red; UINT8 Reserved; } EFI_GRAPHICS_OUTPUT_BLT_PIXEL; typedef union { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel; UINT32 Raw; } EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION; /// /// actions for BltOperations /// typedef enum { /// /// Write data from the BltBuffer pixel (0, 0) /// directly to every pixel of the video display rectangle /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). /// Only one pixel will be used from the BltBuffer. Delta is NOT used. /// EfiBltVideoFill, /// /// Read data from the video display rectangle /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in /// the BltBuffer rectangle (DestinationX, DestinationY ) /// (DestinationX + Width, DestinationY + Height). If DestinationX or /// DestinationY is not zero then Delta must be set to the length in bytes /// of a row in the BltBuffer. /// EfiBltVideoToBltBuffer, /// /// Write data from the BltBuffer rectangle /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the /// video display rectangle (DestinationX, DestinationY) /// (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is /// not zero then Delta must be set to the length in bytes of a row in the /// BltBuffer. /// EfiBltBufferToVideo, /// /// Copy from the video display rectangle (SourceX, SourceY) /// (SourceX + Width, SourceY + Height) to the video display rectangle /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). /// The BltBuffer and Delta are not used in this mode. /// EfiBltVideoToVideo, EfiGraphicsOutputBltOperationMax } EFI_GRAPHICS_OUTPUT_BLT_OPERATION; /** Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer. @param This Protocol instance pointer. @param BltBuffer The data to transfer to the graphics screen. Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL). @param BltOperation The operation to perform when copying BltBuffer on to the graphics screen. @param SourceX The X coordinate of source for the BltOperation. @param SourceY The Y coordinate of source for the BltOperation. @param DestinationX The X coordinate of destination for the BltOperation. @param DestinationY The Y coordinate of destination for the BltOperation. @param Width The width of a rectangle in the blt rectangle in pixels. @param Height The height of a rectangle in the blt rectangle in pixels. @param Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation. If a Delta of zero is used, the entire BltBuffer is being operated on. If a subrectangle of the BltBuffer is being used then Delta represents the number of bytes in a row of the BltBuffer. @retval EFI_SUCCESS BltBuffer was drawn to the graphics screen. @retval EFI_INVALID_PARAMETER BltOperation is not valid. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL ); typedef struct { /// /// The number of modes supported by QueryMode() and SetMode(). /// UINT32 MaxMode; /// /// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1. /// UINT32 Mode; /// /// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data. /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; /// /// Size of Info structure in bytes. /// UINTN SizeOfInfo; /// /// Base address of graphics linear frame buffer. /// Offset zero in FrameBufferBase represents the upper left pixel of the display. /// EFI_PHYSICAL_ADDRESS FrameBufferBase; /// /// Amount of frame buffer needed to support the active mode as defined by /// PixelsPerScanLine xVerticalResolution x PixelElementSize. /// UINTN FrameBufferSize; } EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; /// /// Provides a basic abstraction to set video modes and copy pixels to and from /// the graphics controller's frame buffer. The linear address of the hardware /// frame buffer is also exposed so software can write directly to the video hardware. /// struct _EFI_GRAPHICS_OUTPUT_PROTOCOL { EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; /// /// Pointer to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data. /// EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; }; extern EFI_GUID gEfiGraphicsOutputProtocolGuid; #endif /** @file EFI_HASH_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0. EFI_HASH_PROTOCOL as defined in UEFI 2.0. The EFI Hash Service Binding Protocol is used to locate hashing services support provided by a driver and to create and destroy instances of the EFI Hash Protocol so that a multiple drivers can use the underlying hashing services. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_HASH_PROTOCOL_H__ #define __EFI_HASH_PROTOCOL_H__ #define EFI_HASH_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x42881c98, 0xa4f3, 0x44b0, {0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd } \ } #define EFI_HASH_PROTOCOL_GUID \ { \ 0xc5184932, 0xdba5, 0x46db, {0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35 } \ } #define EFI_HASH_ALGORITHM_SHA1_GUID \ { \ 0x2ae9d80f, 0x3fb2, 0x4095, {0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6 } \ } #define EFI_HASH_ALGORITHM_SHA224_GUID \ { \ 0x8df01a06, 0x9bd5, 0x4bf7, {0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b } \ } #define EFI_HASH_ALGORITHM_SHA256_GUID \ { \ 0x51aa59de, 0xfdf2, 0x4ea3, {0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9 } \ } #define EFI_HASH_ALGORITHM_SHA384_GUID \ { \ 0xefa96432, 0xde33, 0x4dd2, {0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a } \ } #define EFI_HASH_ALGORITHM_SHA512_GUID \ { \ 0xcaa4381e, 0x750c, 0x4770, {0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30 } \ } #define EFI_HASH_ALGORTIHM_MD5_GUID \ { \ 0xaf7c79c, 0x65b5, 0x4319, {0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7 } \ } #define EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID \ { \ 0x24c5dc2f, 0x53e2, 0x40ca, {0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b } \ } #define EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID \ { \ 0x8628752a, 0x6cb7, 0x4814, {0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 } \ } // // Note: Use of the following algorithms with EFI_HASH_PROTOCOL is deprecated. // EFI_HASH_ALGORITHM_SHA1_GUID // EFI_HASH_ALGORITHM_SHA224_GUID // EFI_HASH_ALGORITHM_SHA256_GUID // EFI_HASH_ALGORITHM_SHA384_GUID // EFI_HASH_ALGORITHM_SHA512_GUID // EFI_HASH_ALGORTIHM_MD5_GUID // typedef struct _EFI_HASH_PROTOCOL EFI_HASH_PROTOCOL; typedef UINT8 EFI_MD5_HASH[16]; typedef UINT8 EFI_SHA1_HASH[20]; typedef UINT8 EFI_SHA224_HASH[28]; typedef UINT8 EFI_SHA256_HASH[32]; typedef UINT8 EFI_SHA384_HASH[48]; typedef UINT8 EFI_SHA512_HASH[64]; typedef union { EFI_MD5_HASH *Md5Hash; EFI_SHA1_HASH *Sha1Hash; EFI_SHA224_HASH *Sha224Hash; EFI_SHA256_HASH *Sha256Hash; EFI_SHA384_HASH *Sha384Hash; EFI_SHA512_HASH *Sha512Hash; } EFI_HASH_OUTPUT; /** Returns the size of the hash which results from a specific algorithm. @param[in] This Points to this instance of EFI_HASH_PROTOCOL. @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. @param[out] HashSize Holds the returned size of the algorithm's hash. @retval EFI_SUCCESS Hash size returned successfully. @retval EFI_INVALID_PARAMETER HashSize is NULL or HashAlgorithm is NULL. @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH_GET_HASH_SIZE)( IN CONST EFI_HASH_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, OUT UINTN *HashSize ); /** Creates a hash for the specified message text. @param[in] This Points to this instance of EFI_HASH_PROTOCOL. @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. @param[in] Extend Specifies whether to create a new hash (FALSE) or extend the specified existing hash (TRUE). @param[in] Message Points to the start of the message. @param[in] MessageSize The size of Message, in bytes. @param[in,out] Hash On input, if Extend is TRUE, then this parameter holds a pointer to a pointer to an array containing the hash to extend. If Extend is FALSE, then this parameter holds a pointer to a pointer to a caller-allocated array that will receive the result of the hash computation. On output (regardless of the value of Extend), the array will contain the result of the hash computation. @retval EFI_SUCCESS Hash returned successfully. @retval EFI_INVALID_PARAMETER Message or Hash, HashAlgorithm is NULL or MessageSize is 0. MessageSize is not an integer multiple of block size. @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver. Or, Extend is TRUE, and the algorithm doesn't support extending the hash. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH_HASH)( IN CONST EFI_HASH_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, IN BOOLEAN Extend, IN CONST UINT8 *Message, IN UINT64 MessageSize, IN OUT EFI_HASH_OUTPUT *Hash ); /// /// This protocol allows creating a hash of an arbitrary message digest /// using one or more hash algorithms. /// struct _EFI_HASH_PROTOCOL { EFI_HASH_GET_HASH_SIZE GetHashSize; EFI_HASH_HASH Hash; }; extern EFI_GUID gEfiHashServiceBindingProtocolGuid; extern EFI_GUID gEfiHashProtocolGuid; extern EFI_GUID gEfiHashAlgorithmSha1Guid; extern EFI_GUID gEfiHashAlgorithmSha224Guid; extern EFI_GUID gEfiHashAlgorithmSha256Guid; extern EFI_GUID gEfiHashAlgorithmSha384Guid; extern EFI_GUID gEfiHashAlgorithmSha512Guid; extern EFI_GUID gEfiHashAlgorithmMD5Guid; extern EFI_GUID gEfiHashAlgorithmSha1NoPadGuid; extern EFI_GUID gEfiHashAlgorithmSha256NoPadGuid; #endif /** @file EFI_HASH2_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.5. EFI_HASH2_PROTOCOL as defined in UEFI 2.5. The EFI Hash2 Service Binding Protocol is used to locate hashing services support provided by a driver and to create and destroy instances of the EFI Hash2 Protocol so that a multiple drivers can use the underlying hashing services. EFI_HASH2_PROTOCOL describes hashing functions for which the algorithm-required message padding and finalization are performed by the supporting driver. Copyright (c) 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_HASH2_PROTOCOL_H__ #define __EFI_HASH2_PROTOCOL_H__ #define EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xda836f8d, 0x217f, 0x4ca0, { 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea } \ } #define EFI_HASH2_PROTOCOL_GUID \ { \ 0x55b1d734, 0xc5e1, 0x49db, { 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b } \ } #include // // NOTE: // Algorithms EFI_HASH_ALGORITHM_SHA1_NOPAD and // EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID are not compatible with // EFI_HASH2_PROTOCOL and will return EFI_UNSUPPORTED if used with any // EFI_HASH2_PROTOCOL function. // // // Note: SHA-1 and MD5 are included for backwards compatibility. // New driver implementations are encouraged to consider stronger algorithms. // typedef struct _EFI_HASH2_PROTOCOL EFI_HASH2_PROTOCOL; typedef UINT8 EFI_MD5_HASH2[16]; typedef UINT8 EFI_SHA1_HASH2[20]; typedef UINT8 EFI_SHA224_HASH2[28]; typedef UINT8 EFI_SHA256_HASH2[32]; typedef UINT8 EFI_SHA384_HASH2[48]; typedef UINT8 EFI_SHA512_HASH2[64]; typedef union { EFI_MD5_HASH2 Md5Hash; EFI_SHA1_HASH2 Sha1Hash; EFI_SHA224_HASH2 Sha224Hash; EFI_SHA256_HASH2 Sha256Hash; EFI_SHA384_HASH2 Sha384Hash; EFI_SHA512_HASH2 Sha512Hash; } EFI_HASH2_OUTPUT; /** Returns the size of the hash which results from a specific algorithm. @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. @param[out] HashSize Holds the returned size of the algorithm's hash. @retval EFI_SUCCESS Hash size returned successfully. @retval EFI_INVALID_PARAMETER This or HashSize is NULL. @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver or HashAlgorithm is null. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH2_GET_HASH_SIZE)( IN CONST EFI_HASH2_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, OUT UINTN *HashSize ); /** Creates a hash for the specified message text. The hash is not extendable. The output is final with any algorithm-required padding added by the function. @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. @param[in] Message Points to the start of the message. @param[in] MessageSize The size of Message, in bytes. @param[in,out] Hash On input, points to a caller-allocated buffer of the size returned by GetHashSize() for the specified HashAlgorithm. On output, the buffer holds the resulting hash computed from the message. @retval EFI_SUCCESS Hash returned successfully. @retval EFI_INVALID_PARAMETER This or Hash is NULL. @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver or HashAlgorithm is Null. @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available or MessageSize is greater than platform maximum. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH2_HASH)( IN CONST EFI_HASH2_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm, IN CONST UINT8 *Message, IN UINTN MessageSize, IN OUT EFI_HASH2_OUTPUT *Hash ); /** This function must be called to initialize a digest calculation to be subsequently performed using the EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal(). @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. @retval EFI_SUCCESS Initialized successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver or HashAlgorithm is Null. @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource. @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(), or HashInit() is already called before and not terminated by HashFinal() yet on the same instance. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH2_HASH_INIT)( IN CONST EFI_HASH2_PROTOCOL *This, IN CONST EFI_GUID *HashAlgorithm ); /** Updates the hash of a computation in progress by adding a message text. @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. @param[in] Message Points to the start of the message. @param[in] MessageSize The size of Message, in bytes. @retval EFI_SUCCESS Digest in progress updated successfully. @retval EFI_INVALID_PARAMETER This or Hash is NULL. @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available or MessageSize is greater than platform maximum. @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(), or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH2_HASH_UPDATE)( IN CONST EFI_HASH2_PROTOCOL *This, IN CONST UINT8 *Message, IN UINTN MessageSize ); /** Finalizes a hash operation in progress and returns calculation result. The output is final with any necessary padding added by the function. The hash may not be further updated or extended after HashFinal(). @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. @param[in,out] Hash On input, points to a caller-allocated buffer of the size returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit(). On output, the buffer holds the resulting hash computed from the message. @retval EFI_SUCCESS Hash returned successfully. @retval EFI_INVALID_PARAMETER This or Hash is NULL. @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(), or the operation in progress was canceled by a call to Hash() on the same instance. **/ typedef EFI_STATUS (EFIAPI *EFI_HASH2_HASH_FINAL)( IN CONST EFI_HASH2_PROTOCOL *This, IN OUT EFI_HASH2_OUTPUT *Hash ); /// /// This protocol describes hashing functions for which the algorithm-required message padding and /// finalization are performed by the supporting driver. /// struct _EFI_HASH2_PROTOCOL { EFI_HASH2_GET_HASH_SIZE GetHashSize; EFI_HASH2_HASH Hash; EFI_HASH2_HASH_INIT HashInit; EFI_HASH2_HASH_UPDATE HashUpdate; EFI_HASH2_HASH_FINAL HashFinal; }; extern EFI_GUID gEfiHash2ServiceBindingProtocolGuid; extern EFI_GUID gEfiHash2ProtocolGuid; #endif /** @file The EFI HII results processing protocol invokes this type of protocol when it needs to forward results to a driver's configuration handler. This protocol is published by drivers providing and requesting configuration data from HII. It may only be invoked by HII. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __EFI_HII_CONFIG_ACCESS_H__ #define __EFI_HII_CONFIG_ACCESS_H__ #include #define EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID \ { 0x330d4706, 0xf2a0, 0x4e4f, { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } } typedef struct _EFI_HII_CONFIG_ACCESS_PROTOCOL EFI_HII_CONFIG_ACCESS_PROTOCOL; typedef UINTN EFI_BROWSER_ACTION; #define EFI_BROWSER_ACTION_CHANGING 0 #define EFI_BROWSER_ACTION_CHANGED 1 #define EFI_BROWSER_ACTION_RETRIEVE 2 #define EFI_BROWSER_ACTION_FORM_OPEN 3 #define EFI_BROWSER_ACTION_FORM_CLOSE 4 #define EFI_BROWSER_ACTION_SUBMITTED 5 #define EFI_BROWSER_ACTION_DEFAULT_STANDARD 0x1000 #define EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING 0x1001 #define EFI_BROWSER_ACTION_DEFAULT_SAFE 0x1002 #define EFI_BROWSER_ACTION_DEFAULT_PLATFORM 0x2000 #define EFI_BROWSER_ACTION_DEFAULT_HARDWARE 0x3000 #define EFI_BROWSER_ACTION_DEFAULT_FIRMWARE 0x4000 /** This function allows the caller to request the current configuration for one or more named elements. The resulting string is in format. Any and all alternative configuration strings shall also be appended to the end of the current configuration string. If they are, they must appear after the current configuration. They must contain the same routing (GUID, NAME, PATH) as the current configuration string. They must have an additional description indicating the type of alternative configuration the string represents, "ALTCFG=". That (when converted from Hex UNICODE to binary) is a reference to a string in the associated string pack. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Request A null-terminated Unicode string in format. Note that this includes the routing information as well as the configurable name / value pairs. It is invalid for this string to be in format. If a NULL is passed in for the Request field, all of the settings being abstracted by this function will be returned in the Results field. In addition, if a ConfigHdr is passed in with no request elements, all of the settings being abstracted for that particular ConfigHdr reference will be returned in the Results Field. @param Progress On return, points to a character in the Request string. Points to the string's null terminator if request was successful. Points to the most recent "&" before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair) if the request was not successful. @param Results A null-terminated Unicode string in format which has all values filled in for the names in the Request string. String to be allocated by the called function. @retval EFI_SUCCESS The Results string is filled with the values corresponding to all requested names. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_NOT_FOUND A configuration element matching the routing data is not found. Progress set to the first character in the routing header. @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set to most recent "&" before the error or the beginning of the string. @retval EFI_INVALID_PARAMETER Unknown name. Progress points to the & before the name in question. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_ACCESS_EXTRACT_CONFIG)( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Request, OUT EFI_STRING *Progress, OUT EFI_STRING *Results ); /** This function applies changes in a driver's configuration. Input is a Configuration, which has the routing data for this driver followed by name / value configuration pairs. The driver must apply those pairs to its configurable storage. If the driver's configuration is stored in a linear block of data and the driver's name / value pairs are in format, it may use the ConfigToBlock helper function (above) to simplify the job. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Configuration A null-terminated Unicode string in format. @param Progress A pointer to a string filled in with the offset of the most recent '&' before the first failing name / value pair (or the beginn ing of the string if the failure is in the first name / value pair) or the terminating NULL if all was successful. @retval EFI_SUCCESS The results have been distributed or are awaiting distribution. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_INVALID_PARAMETERS Passing in a NULL for the Results parameter would result in this type of error. @retval EFI_NOT_FOUND Target for the specified routing data was not found **/ typedef EFI_STATUS (EFIAPI *EFI_HII_ACCESS_ROUTE_CONFIG)( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress ); /** This function is called to provide results data to the driver. This data consists of a unique key that is used to identify which data is either being passed back or being asked for. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that generated the callback. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_ACCESS_FORM_CALLBACK)( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN OUT EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) ; /// /// This protocol provides a callable interface between the HII and /// drivers. Only drivers which provide IFR data to HII are required /// to publish this protocol. /// struct _EFI_HII_CONFIG_ACCESS_PROTOCOL { EFI_HII_ACCESS_EXTRACT_CONFIG ExtractConfig; EFI_HII_ACCESS_ROUTE_CONFIG RouteConfig; EFI_HII_ACCESS_FORM_CALLBACK Callback; }; extern EFI_GUID gEfiHiiConfigAccessProtocolGuid; #endif /** @file The file provides the mechanism to set and get the values associated with a keyword exposed through a x-UEFI- prefixed configuration language namespace. Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.5. **/ #ifndef __EFI_CONFIG_KEYWORD_HANDLER_H__ #define __EFI_CONFIG_KEYWORD_HANDLER_H__ #define EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL_GUID \ { \ 0x0a8badd5, 0x03b8, 0x4d19, {0xb1, 0x28, 0x7b, 0x8f, 0x0e, 0xda, 0xa5, 0x96 } \ } // *********************************************************** // Progress Errors // *********************************************************** #define KEYWORD_HANDLER_NO_ERROR 0x00000000 #define KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND 0x00000001 #define KEYWORD_HANDLER_MALFORMED_STRING 0x00000002 #define KEYWORD_HANDLER_KEYWORD_NOT_FOUND 0x00000004 #define KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED 0x00000008 #define KEYWORD_HANDLER_ACCESS_NOT_PERMITTED 0x00000010 #define KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR 0x80000000 typedef struct _EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL; /** This function accepts a formatted string, finds the associated keyword owners, creates a string from it and forwards it to the EFI_HII_ROUTING_PROTOCOL.RouteConfig function. If there is an issue in resolving the contents of the KeywordString, then the function returns an error and also sets the Progress and ProgressErr with the appropriate information about where the issue occurred and additional data about the nature of the issue. In the case when KeywordString containing multiple keywords, when an EFI_NOT_FOUND error is generated during processing the second or later keyword element, the system storage associated with earlier keywords is not modified. All elements of the KeywordString must successfully pass all tests for format and access prior to making any modifications to storage. In the case when EFI_DEVICE_ERROR is returned from the processing of a KeywordString containing multiple keywords, the state of storage associated with earlier keywords is undefined. @param This Pointer to the EFI_KEYWORD_HANDLER _PROTOCOL instance. @param KeywordString A null-terminated string in format. @param Progress On return, points to a character in the KeywordString. Points to the string's NULL terminator if the request was successful. Points to the most recent '&' before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair) if the request was not successful. @param ProgressErr If during the processing of the KeywordString there was a failure, this parameter gives additional information about the possible source of the problem. The various errors are defined in "Related Definitions" below. @retval EFI_SUCCESS The specified action was completed successfully. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: 1. KeywordString is NULL. 2. Parsing of the KeywordString resulted in an error. See Progress and ProgressErr for more data. @retval EFI_NOT_FOUND An element of the KeywordString was not found. See ProgressErr for more data. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. See ProgressErr for more data. @retval EFI_ACCESS_DENIED The action violated system policy. See ProgressErr for more data. @retval EFI_DEVICE_ERROR An unexpected system error occurred. See ProgressErr for more data. **/ typedef EFI_STATUS (EFIAPI *EFI_CONFIG_KEYWORD_HANDLER_SET_DATA)( IN EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *This, IN CONST EFI_STRING KeywordString, OUT EFI_STRING *Progress, OUT UINT32 *ProgressErr ); /** This function accepts a formatted string, finds the underlying keyword owners, creates a string from it and forwards it to the EFI_HII_ROUTING_PROTOCOL.ExtractConfig function. If there is an issue in resolving the contents of the KeywordString, then the function returns an EFI_INVALID_PARAMETER and also set the Progress and ProgressErr with the appropriate information about where the issue occurred and additional data about the nature of the issue. In the case when KeywordString is NULL, or contains multiple keywords, or when EFI_NOT_FOUND is generated while processing the keyword elements, the Results string contains values returned for all keywords processed prior to the keyword generating the error but no values for the keyword with error or any following keywords. @param This Pointer to the EFI_KEYWORD_HANDLER _PROTOCOL instance. @param NameSpaceId A null-terminated string containing the platform configuration language to search through in the system. If a NULL is passed in, then it is assumed that any platform configuration language with the prefix of "x-UEFI-" are searched. @param KeywordString A null-terminated string in format. If a NULL is passed in the KeywordString field, all of the known keywords in the system for the NameSpaceId specified are returned in the Results field. @param Progress On return, points to a character in the KeywordString. Points to the string's NULL terminator if the request was successful. Points to the most recent '&' before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair) if the request was not successful. @param ProgressErr If during the processing of the KeywordString there was a failure, this parameter gives additional information about the possible source of the problem. See the definitions in SetData() for valid value definitions. @param Results A null-terminated string in format is returned which has all the values filled in for the keywords in the KeywordString. This is a callee-allocated field, and must be freed by the caller after being used. @retval EFI_SUCCESS The specified action was completed successfully. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: 1.Progress, ProgressErr, or Results is NULL. 2.Parsing of the KeywordString resulted in an error. See Progress and ProgressErr for more data. @retval EFI_NOT_FOUND An element of the KeywordString was not found. See ProgressErr for more data. @retval EFI_NOT_FOUND The NamespaceId specified was not found. See ProgressErr for more data. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. See ProgressErr for more data. @retval EFI_ACCESS_DENIED The action violated system policy. See ProgressErr for more data. @retval EFI_DEVICE_ERROR An unexpected system error occurred. See ProgressErr for more data. **/ typedef EFI_STATUS (EFIAPI *EFI_CONFIG_KEYWORD_HANDLER_GET_DATA)( IN EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *This, IN CONST EFI_STRING NameSpaceId OPTIONAL, IN CONST EFI_STRING KeywordString OPTIONAL, OUT EFI_STRING *Progress, OUT UINT32 *ProgressErr, OUT EFI_STRING *Results ); /// /// The EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL provides the mechanism /// to set and get the values associated with a keyword exposed /// through a x-UEFI- prefixed configuration language namespace /// struct _EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL { EFI_CONFIG_KEYWORD_HANDLER_SET_DATA SetData; EFI_CONFIG_KEYWORD_HANDLER_GET_DATA GetData; }; extern EFI_GUID gEfiConfigKeywordHandlerProtocolGuid; #endif /** @file The file provides services to manage the movement of configuration data from drivers to configuration applications. It then serves as the single point to receive configuration information from configuration applications, routing the results to the appropriate drivers. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __HII_CONFIG_ROUTING_H__ #define __HII_CONFIG_ROUTING_H__ #define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ { 0x587e72d7, 0xcc50, 0x4f79, { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } } typedef struct _EFI_HII_CONFIG_ROUTING_PROTOCOL EFI_HII_CONFIG_ROUTING_PROTOCOL; /** This function allows the caller to request the current configuration for one or more named elements from one or more drivers. The resulting string is in the standard HII configuration string format. If Successful, Results contains an equivalent string with "=" and the values associated with all names added in. The expected implementation is for each substring in the Request to call the HII Configuration Routing Protocol ExtractProtocol function for the driver corresponding to the at the start of the substring. The request fails if no driver matches the substring. Note: Alternative configuration strings may also be appended to the end of the current configuration string. If they are, they must appear after the current configuration. They must contain the same routing (GUID, NAME, PATH) as the current configuration string. They must have an additional description indicating the type of alternative configuration the string represents, "ALTCFG=". That (when converted from hexadecimal (encoded as text) to binary) is a reference to a string in the associated string pack. As an example, assume that the Request string is: GUID=...&NAME=00480050&PATH=...&Fred&George&Ron&Neville A result might be: GUID=...&NAME=00480050&PATH=...&Fred=16&George=16&Ron=12&Neville=11& GUID=...&NAME=00480050&PATH=...&ALTCFG=0037&Fred=12&Neville=7 @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param Request A null-terminated string in format. @param Progress On return, points to a character in the Request string. Points to the string's null terminator if the request was successful. Points to the most recent '&' before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair) if the request was not successful @param Results A null-terminated string in format which has all values filled in for the names in the Request string. @retval EFI_SUCCESS The Results string is filled with the values corresponding to all requested names. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_INVALID_PARAMETER For example, passing in a NULL for the Request parameter would result in this type of error. The Progress parameter is set to NULL. @retval EFI_NOT_FOUND Routing data doesn't match any known driver. Progress set to the "G" in "GUID" of the routing header that doesn't match. Note: There is no requirement that all routing data be validated before any configuration extraction. @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set to the most recent & before the error, or the beginning of the string. @retval EFI_INVALID_PARAMETER The ExtractConfig function of the underlying HII Configuration Access Protocol returned EFI_INVALID_PARAMETER. Progress set to most recent & before the error or the beginning of the string. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_EXTRACT_CONFIG)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING Request, OUT EFI_STRING *Progress, OUT EFI_STRING *Results ); /** This function allows the caller to request the current configuration for the entirety of the current HII database and returns the data in a null-terminated string. This function allows the caller to request the current configuration for all of the current HII database. The results include both the current and alternate configurations as described in ExtractConfig() above. @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param Results Null-terminated Unicode string in format which has all values filled in for the entirety of the current HII database. String to be allocated by the called function. De-allocation is up to the caller. @retval EFI_SUCCESS The Results string is filled with the values corresponding to all requested names. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_INVALID_PARAMETERS For example, passing in a NULL for the Results parameter would result in this type of error. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_EXPORT_CONFIG)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, OUT EFI_STRING *Results ); /** This function routes the results of processing forms to the appropriate targets. It scans for within the string and passes the header and subsequent body to the driver whose location is described in the . Many s may appear as a single request. The expected implementation is to hand off the various substrings to the Configuration Access Protocol RouteConfig routine corresponding to the driver whose routing information is defined by the in turn. @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param Configuration A null-terminated string in format. @param Progress A pointer to a string filled in with the offset of the most recent '&' before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair), or the terminating NULL if all was successful. @retval EFI_SUCCESS The results have been distributed or are awaiting distribution. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_INVALID_PARAMETERS Passing in a NULL for the Results parameter would result in this type of error. @retval EFI_NOT_FOUND The target for the specified routing data was not found. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_ROUTE_CONFIG)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress ); /** This function extracts the current configuration from a block of bytes. To do so, it requires that the ConfigRequest string consists of a list of formatted names. It uses the offset in the name to determine the index into the Block to start the extraction and the width of each name to determine the number of bytes to extract. These are mapped to a string using the equivalent of the C "%x" format (with optional leading spaces). The call fails if, for any (offset, width) pair in ConfigRequest, offset+value >= BlockSize. @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param ConfigRequest A null-terminated string in format. @param Block An array of bytes defining the block's configuration. @param BlockSize The length in bytes of Block. @param Config The filled-in configuration string. String allocated by the function. Returned only if call is successful. The null-terminated string will be format. @param Progress A pointer to a string filled in with the offset of the most recent '&' before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair), or the terminating NULL if all was successful. @retval EFI_SUCCESS The request succeeded. Progress points to the null terminator at the end of the ConfigRequest string. @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Progress points to the first character of ConfigRequest. @retval EFI_INVALID_PARAMETERS Passing in a NULL for the ConfigRequest or Block parameter would result in this type of error. Progress points to the first character of ConfigRequest. @retval EFI_NOT_FOUND The target for the specified routing data was not found. Progress points to the 'G' in "GUID" of the errant routing data. @retval EFI_DEVICE_ERROR The block is not large enough. Progress undefined. @retval EFI_INVALID_PARAMETER Encountered non formatted string. Block is left updated and Progress points at the '&' preceding the first non-. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_BLOCK_TO_CONFIG)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING ConfigRequest, IN CONST UINT8 *Block, IN CONST UINTN BlockSize, OUT EFI_STRING *Config, OUT EFI_STRING *Progress ); /** This function maps a configuration containing a series of formatted name value pairs in ConfigResp into a Block so it may be stored in a linear mapped storage such as a UEFI Variable. If present, the function skips GUID, NAME, and PATH in . It stops when it finds a non- name / value pair (after skipping the routing header) or when it reaches the end of the string. Example Assume an existing block containing: 00 01 02 03 04 05 And the ConfigResp string is: OFFSET=4&WIDTH=1&VALUE=7&OFFSET=0&WIDTH=2&VALUE=AA55 The results are 55 AA 02 07 04 05 @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param ConfigResp A null-terminated string in format. @param Block A possibly null array of bytes representing the current block. Only bytes referenced in the ConfigResp string in the block are modified. If this parameter is null or if the BlockLength parameter is (on input) shorter than required by the Configuration string, only the BlockSize parameter is updated, and an appropriate status (see below) is returned. @param BlockSize The length of the Block in units of UINT8. On input, this is the size of the Block. On output, if successful, contains the largest index of the modified byte in the Block, or the required buffer size if the Block is not large enough. @param Progress On return, points to an element of the ConfigResp string filled in with the offset of the most recent "&" before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair), or the terminating NULL if all was successful. @retval EFI_SUCCESS The request succeeded. Progress points to the null terminator at the end of the ConfigResp string. @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Progress points to the first character of ConfigResp. @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigResp or Block parameter would result in this type of error. Progress points to the first character of ConfigResp. @retval EFI_INVALID_PARAMETER Encountered non formatted name / value pair. Block is left updated and Progress points at the '&' preceding the first non-. @retval EFI_DEVICE_ERROR Block not large enough. Progress undefined. @retval EFI_NOT_FOUND Target for the specified routing data was not found. Progress points to the "G" in "GUID" of the errant routing data. @retval EFI_BUFFER_TOO_SMALL Block not large enough. Progress undefined. BlockSize is updated with the required buffer size. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_CONFIG_TO_BLOCK)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING ConfigResp, IN OUT UINT8 *Block, IN OUT UINTN *BlockSize, OUT EFI_STRING *Progress ); /** This helper function is to be called by drivers to extract portions of a larger configuration string. @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. @param ConfigResp A null-terminated string in format. @param Guid A pointer to the GUID value to search for in the routing portion of the ConfigResp string when retrieving the requested data. If Guid is NULL, then all GUID values will be searched for. @param Name A pointer to the NAME value to search for in the routing portion of the ConfigResp string when retrieving the requested data. If Name is NULL, then all Name values will be searched for. @param DevicePath A pointer to the PATH value to search for in the routing portion of the ConfigResp string when retrieving the requested data. If DevicePath is NULL, then all DevicePath values will be searched for. @param AltCfgId A pointer to the ALTCFG value to search for in the routing portion of the ConfigResp string when retrieving the requested data. If this parameter is NULL, then the current setting will be retrieved. @param AltCfgResp A pointer to a buffer which will be allocated by the function which contains the retrieved string as requested. This buffer is only allocated if the call was successful. The null-terminated string will be format. @retval EFI_SUCCESS The request succeeded. The requested data was extracted and placed in the newly allocated AltCfgResp buffer. @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate AltCfgResp. @retval EFI_INVALID_PARAMETER Any parameter is invalid. @retval EFI_NOT_FOUND The target for the specified routing data was not found. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_ALT_CFG)( IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING ConfigResp, IN CONST EFI_GUID *Guid, IN CONST EFI_STRING Name, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST UINT16 *AltCfgId, OUT EFI_STRING *AltCfgResp ); /// /// This protocol defines the configuration routing interfaces /// between external applications and the HII. There may only be one /// instance of this protocol in the system. /// struct _EFI_HII_CONFIG_ROUTING_PROTOCOL { EFI_HII_EXTRACT_CONFIG ExtractConfig; EFI_HII_EXPORT_CONFIG ExportConfig; EFI_HII_ROUTE_CONFIG RouteConfig; EFI_HII_BLOCK_TO_CONFIG BlockToConfig; EFI_HII_CONFIG_TO_BLOCK ConfigToBlock; EFI_HII_GET_ALT_CFG GetAltConfig; }; extern EFI_GUID gEfiHiiConfigRoutingProtocolGuid; #endif /** @file The file provides Database manager for HII-related data structures. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __HII_DATABASE_H__ #define __HII_DATABASE_H__ #define EFI_HII_DATABASE_PROTOCOL_GUID \ { 0xef9fc172, 0xa1b2, 0x4693, { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } } typedef struct _EFI_HII_DATABASE_PROTOCOL EFI_HII_DATABASE_PROTOCOL; /// /// EFI_HII_DATABASE_NOTIFY_TYPE. /// typedef UINTN EFI_HII_DATABASE_NOTIFY_TYPE; #define EFI_HII_DATABASE_NOTIFY_NEW_PACK 0x00000001 #define EFI_HII_DATABASE_NOTIFY_REMOVE_PACK 0x00000002 #define EFI_HII_DATABASE_NOTIFY_EXPORT_PACK 0x00000004 #define EFI_HII_DATABASE_NOTIFY_ADD_PACK 0x00000008 /** Functions which are registered to receive notification of database events have this prototype. The actual event is encoded in NotifyType. The following table describes how PackageType, PackageGuid, Handle, and Package are used for each of the notification types. @param PackageType Package type of the notification. @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then this is the pointer to the GUID from the Guid field of EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it must be NULL. @param Package Points to the package referred to by the notification. @param Handle The handle of the package list which contains the specified package. @param NotifyType The type of change concerning the database. See EFI_HII_DATABASE_NOTIFY_TYPE. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_NOTIFY)( IN UINT8 PackageType, IN CONST EFI_GUID *PackageGuid, IN CONST EFI_HII_PACKAGE_HEADER *Package, IN EFI_HII_HANDLE Handle, IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType ); /** This function adds the packages in the package list to the database and returns a handle. If there is a EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list. For each package in the package list, registered functions with the notification type NEW_PACK and having the same package type will be called. For each call to NewPackageList(), there should be a corresponding call to EFI_HII_DATABASE_PROTOCOL.RemovePackageList(). @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER structure. @param DriverHandle Associate the package list with this EFI handle. If a NULL is specified, this data will not be associate with any drivers and cannot have a callback induced. @param Handle A pointer to the EFI_HII_HANDLE instance. @retval EFI_SUCCESS The package list associated with the Handle was added to the HII database. @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new database contents. @retval EFI_INVALID_PARAMETER PackageList is NULL, or Handle is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_NEW_PACK)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList, IN EFI_HANDLE DriverHandle OPTIONAL, OUT EFI_HII_HANDLE *Handle ); /** This function removes the package list that is associated with a handle Handle from the HII database. Before removing the package, any registered functions with the notification type REMOVE_PACK and the same package type will be called. For each call to EFI_HII_DATABASE_PROTOCOL.NewPackageList(), there should be a corresponding call to RemovePackageList. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param Handle The handle that was registered to the data that is requested for removal. @retval EFI_SUCCESS The data associated with the Handle was removed from the HII database. @retval EFI_NOT_FOUND The specified Handle is not in database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_REMOVE_PACK)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN EFI_HII_HANDLE Handle ); /** This function updates the existing package list (which has the specified Handle) in the HII databases, using the new package list specified by PackageList. The update process has the following steps: Collect all the package types in the package list specified by PackageList. A package type consists of the Type field of EFI_HII_PACKAGE_HEADER and, if the Type is EFI_HII_PACKAGE_TYPE_GUID, the Guid field, as defined in EFI_HII_PACKAGE_GUID_HEADER. Iterate through the packages within the existing package list in the HII database specified by Handle. If a package's type matches one of the collected types collected in step 1, then perform the following steps: - Call any functions registered with the notification type REMOVE_PACK. - Remove the package from the package list and the HII database. Add all of the packages within the new package list specified by PackageList, using the following steps: - Add the package to the package list and the HII database. - Call any functions registered with the notification type ADD_PACK. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param Handle The handle that was registered to the data that is requested for removal. @param PackageList A pointer to an EFI_HII_PACKAGE_LIST package. @retval EFI_SUCCESS The HII database was successfully updated. @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated database. @retval EFI_INVALID_PARAMETER PackageList was NULL. @retval EFI_NOT_FOUND The specified Handle is not in database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_UPDATE_PACK)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList ); /** This function returns a list of the package handles of the specified type that are currently active in the database. The pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param PackageType Specifies the package type of the packages to list or EFI_HII_PACKAGE_TYPE_ALL for all packages to be listed. @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then this is the pointer to the GUID which must match the Guid field of EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it must be NULL. @param HandleBufferLength On input, a pointer to the length of the handle buffer. On output, the length of the handle buffer that is required for the handles found. @param Handle An array of EFI_HII_HANDLE instances returned. @retval EFI_SUCCESS The matching handles are outputted successfully. HandleBufferLength is updated with the actual length. @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates that Handle is too small to support the number of handles. HandleBufferLength is updated with a value that will enable the data to fit. @retval EFI_NOT_FOUND No matching handle could be found in database. @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL. @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not zero and Handle was NULL. @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but PackageGuid is not NULL, PackageType is a EFI_HII_ PACKAGE_TYPE_GUID but PackageGuid is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_LIST_PACKS)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN UINT8 PackageType, IN CONST EFI_GUID *PackageGuid, IN OUT UINTN *HandleBufferLength, OUT EFI_HII_HANDLE *Handle ); /** This function will export one or all package lists in the database to a buffer. For each package list exported, this function will call functions registered with EXPORT_PACK and then copy the package list to the buffer. The registered functions may call EFI_HII_DATABASE_PROTOCOL.UpdatePackageList() to modify the package list before it is copied to the buffer. If the specified BufferSize is too small, then the status EFI_OUT_OF_RESOURCES will be returned and the actual package size will be returned in BufferSize. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param Handle An EFI_HII_HANDLE that corresponds to the desired package list in the HII database to export or NULL to indicate all package lists should be exported. @param BufferSize On input, a pointer to the length of the buffer. On output, the length of the buffer that is required for the exported data. @param Buffer A pointer to a buffer that will contain the results of the export function. @retval EFI_SUCCESS Package exported. @retval EFI_OUT_OF_RESOURCES BufferSize is too small to hold the package. @retval EFI_NOT_FOUND The specified Handle could not be found in the current database. @retval EFI_INVALID_PARAMETER BufferSize was NULL. @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero and Buffer was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_EXPORT_PACKS)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN OUT UINTN *BufferSize, OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer ); /** This function registers a function which will be called when specified actions related to packages of the specified type occur in the HII database. By registering a function, other HII-related drivers are notified when specific package types are added, removed or updated in the HII database. Each driver or application which registers a notification should use EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param PackageType The package type. See EFI_HII_PACKAGE_TYPE_x in EFI_HII_PACKAGE_HEADER. @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then this is the pointer to the GUID which must match the Guid field of EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it must be NULL. @param PackageNotifyFn Points to the function to be called when the event specified by NotificationType occurs. See EFI_HII_DATABASE_NOTIFY. @param NotifyType Describes the types of notification which this function will be receiving. See EFI_HII_DATABASE_NOTIFY_TYPE for a list of types. @param NotifyHandle Points to the unique handle assigned to the registered notification. Can be used in EFI_HII_DATABASE_PROTOCOL.UnregisterPack to stop notifications. @retval EFI_SUCCESS Notification registered successfully. @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not EFI_HII_PACKAGE_TYPE_GUID. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_REGISTER_NOTIFY)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN UINT8 PackageType, IN CONST EFI_GUID *PackageGuid, IN EFI_HII_DATABASE_NOTIFY PackageNotifyFn, IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, OUT EFI_HANDLE *NotifyHandle ); /** Removes the specified HII database package-related notification. @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. @param NotificationHandle The handle of the notification function being unregistered. @retval EFI_SUCCESS Successsfully unregistered the notification. @retval EFI_NOT_FOUND The incoming notification handle does not exist in the current hii database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_UNREGISTER_NOTIFY)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN EFI_HANDLE NotificationHandle ); /** This routine retrieves an array of GUID values for each keyboard layout that was previously registered in the system. @param This A pointer to the EFI_HII_PROTOCOL instance. @param KeyGuidBufferLength On input, a pointer to the length of the keyboard GUID buffer. On output, the length of the handle buffer that is required for the handles found. @param KeyGuidBuffer An array of keyboard layout GUID instances returned. @retval EFI_SUCCESS KeyGuidBuffer was updated successfully. @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates that KeyGuidBuffer is too small to support the number of GUIDs. KeyGuidBufferLength is updated with a value that will enable the data to fit. @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL. @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not zero and KeyGuidBuffer is NULL. @retval EFI_NOT_FOUND There was no keyboard layout. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_FIND_KEYBOARD_LAYOUTS)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN OUT UINT16 *KeyGuidBufferLength, OUT EFI_GUID *KeyGuidBuffer ); /** This routine retrieves the requested keyboard layout. The layout is a physical description of the keys on a keyboard, and the character(s) that are associated with a particular set of key strokes. @param This A pointer to the EFI_HII_PROTOCOL instance. @param KeyGuid A pointer to the unique ID associated with a given keyboard layout. If KeyGuid is NULL then the current layout will be retrieved. @param KeyboardLayoutLength On input, a pointer to the length of the KeyboardLayout buffer. On output, the length of the data placed into KeyboardLayout. @param KeyboardLayout A pointer to a buffer containing the retrieved keyboard layout. @retval EFI_SUCCESS The keyboard layout was retrieved successfully. @retval EFI_NOT_FOUND The requested keyboard layout was not found. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN CONST EFI_GUID *KeyGuid, IN OUT UINT16 *KeyboardLayoutLength, OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout ); /** This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group type. This is so that agents which are sensitive to the current keyboard layout being changed can be notified of this change. @param This A pointer to the EFI_HII_PROTOCOL instance. @param KeyGuid A pointer to the unique ID associated with a given keyboard layout. @retval EFI_SUCCESS The current keyboard layout was successfully set. @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so action was taken. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_SET_KEYBOARD_LAYOUT)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN CONST EFI_GUID *KeyGuid ); /** Return the EFI handle associated with a package list. @param This A pointer to the EFI_HII_PROTOCOL instance. @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired package list in the HIIdatabase. @param DriverHandle On return, contains the EFI_HANDLE which was registered with the package list in NewPackageList(). @retval EFI_SUCCESS The DriverHandle was returned successfully. @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DATABASE_GET_PACK_HANDLE)( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN EFI_HII_HANDLE PackageListHandle, OUT EFI_HANDLE *DriverHandle ); /// /// Database manager for HII-related data structures. /// struct _EFI_HII_DATABASE_PROTOCOL { EFI_HII_DATABASE_NEW_PACK NewPackageList; EFI_HII_DATABASE_REMOVE_PACK RemovePackageList; EFI_HII_DATABASE_UPDATE_PACK UpdatePackageList; EFI_HII_DATABASE_LIST_PACKS ListPackageLists; EFI_HII_DATABASE_EXPORT_PACKS ExportPackageLists; EFI_HII_DATABASE_REGISTER_NOTIFY RegisterPackageNotify; EFI_HII_DATABASE_UNREGISTER_NOTIFY UnregisterPackageNotify; EFI_HII_FIND_KEYBOARD_LAYOUTS FindKeyboardLayouts; EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout; EFI_HII_SET_KEYBOARD_LAYOUT SetKeyboardLayout; EFI_HII_DATABASE_GET_PACK_HANDLE GetPackageListHandle; }; extern EFI_GUID gEfiHiiDatabaseProtocolGuid; #endif /** @file The file provides services to retrieve font information. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __HII_FONT_H__ #define __HII_FONT_H__ #include #include #define EFI_HII_FONT_PROTOCOL_GUID \ { 0xe9ca4775, 0x8657, 0x47fc, { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } } typedef struct _EFI_HII_FONT_PROTOCOL EFI_HII_FONT_PROTOCOL; typedef VOID *EFI_FONT_HANDLE; /// /// EFI_HII_OUT_FLAGS. /// typedef UINT32 EFI_HII_OUT_FLAGS; #define EFI_HII_OUT_FLAG_CLIP 0x00000001 #define EFI_HII_OUT_FLAG_WRAP 0x00000002 #define EFI_HII_OUT_FLAG_CLIP_CLEAN_Y 0x00000004 #define EFI_HII_OUT_FLAG_CLIP_CLEAN_X 0x00000008 #define EFI_HII_OUT_FLAG_TRANSPARENT 0x00000010 #define EFI_HII_IGNORE_IF_NO_GLYPH 0x00000020 #define EFI_HII_IGNORE_LINE_BREAK 0x00000040 #define EFI_HII_DIRECT_TO_SCREEN 0x00000080 /** Definition of EFI_HII_ROW_INFO. **/ typedef struct _EFI_HII_ROW_INFO { /// /// The index of the first character in the string which is displayed on the line. /// UINTN StartIndex; /// /// The index of the last character in the string which is displayed on the line. /// If this is the same as StartIndex, then no characters are displayed. /// UINTN EndIndex; UINTN LineHeight; ///< The height of the line, in pixels. UINTN LineWidth; ///< The width of the text on the line, in pixels. /// /// The font baseline offset in pixels from the bottom of the row, or 0 if none. /// UINTN BaselineOffset; } EFI_HII_ROW_INFO; /// /// Font info flag. All flags (FONT, SIZE, STYLE, and COLOR) are defined. /// They are defined as EFI_FONT_INFO_*** /// typedef UINT32 EFI_FONT_INFO_MASK; #define EFI_FONT_INFO_SYS_FONT 0x00000001 #define EFI_FONT_INFO_SYS_SIZE 0x00000002 #define EFI_FONT_INFO_SYS_STYLE 0x00000004 #define EFI_FONT_INFO_SYS_FORE_COLOR 0x00000010 #define EFI_FONT_INFO_SYS_BACK_COLOR 0x00000020 #define EFI_FONT_INFO_RESIZE 0x00001000 #define EFI_FONT_INFO_RESTYLE 0x00002000 #define EFI_FONT_INFO_ANY_FONT 0x00010000 #define EFI_FONT_INFO_ANY_SIZE 0x00020000 #define EFI_FONT_INFO_ANY_STYLE 0x00040000 // // EFI_FONT_INFO // typedef struct { EFI_HII_FONT_STYLE FontStyle; UINT16 FontSize; ///< character cell height in pixels CHAR16 FontName[1]; } EFI_FONT_INFO; /** Describes font output-related information. This structure is used for describing the way in which a string should be rendered in a particular font. FontInfo specifies the basic font information and ForegroundColor and BackgroundColor specify the color in which they should be displayed. The flags in FontInfoMask describe where the system default should be supplied instead of the specified information. The flags also describe what options can be used to make a match between the font requested and the font available. **/ typedef struct _EFI_FONT_DISPLAY_INFO { EFI_GRAPHICS_OUTPUT_BLT_PIXEL ForegroundColor; EFI_GRAPHICS_OUTPUT_BLT_PIXEL BackgroundColor; EFI_FONT_INFO_MASK FontInfoMask; EFI_FONT_INFO FontInfo; } EFI_FONT_DISPLAY_INFO; /** This function renders a string to a bitmap or the screen using the specified font, color and options. It either draws the string and glyphs on an existing bitmap, allocates a new bitmap, or uses the screen. The strings can be clipped or wrapped. Optionally, the function also returns the information about each row and the character position on that row. If EFI_HII_OUT_FLAG_CLIP is set, then text will be formatted only based on explicit line breaks and all pixels which would lie outside the bounding box specified by Width and Height are ignored. The information in the RowInfoArray only describes characters which are at least partially displayed. For the final row, the LineHeight and BaseLine may describe pixels that are outside the limit specified by Height (unless EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is specified) even though those pixels were not drawn. The LineWidth may describe pixels which are outside the limit specified by Width (unless EFI_HII_OUT_FLAG_CLIP_CLEAN_X is specified) even though those pixels were not drawn. If EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that if a character's right-most on pixel cannot fit, then it will not be drawn at all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that if a row's bottom-most pixel cannot fit, then it will not be drawn at all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_WRAP is set, then text will be wrapped at the right-most line-break opportunity prior to a character whose right-most extent would exceed Width. If no line-break opportunity can be found, then the text will behave as if EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set. This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is ignored and all 'off' pixels in the character's drawn will use the pixel value from Blt. This flag cannot be used if Blt is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs are not drawn. Otherwise, they are replaced with Unicode character code 0xFFFD (REPLACEMENT CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit line break characters will be ignored. If EFI_HII_DIRECT_TO_SCREEN is set, then the string will be written directly to the output device specified by Screen. Otherwise the string will be rendered to the bitmap specified by Bitmap. @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. @param Flags Describes how the string is to be drawn. @param String Points to the null-terminated string to be @param StringInfo Points to the string output information, including the color and font. If NULL, then the string will be output in the default system font and color. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The string will be drawn onto this image and EFI_HII_OUT_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX, BltY Specifies the offset from the left and top edge of the image of the first character cell in the image. @param RowInfoArray If this is non-NULL on entry, then on exit, this will point to an allocated buffer containing row information and RowInfoArraySize will be updated to contain the number of elements. This array describes the characters that were at least partially drawn and the heights of the rows. It is the caller's responsibility to free this buffer. @param RowInfoArraySize If this is non-NULL on entry, then on exit it contains the number of elements in RowInfoArray. @param ColumnInfoArray If this is non-NULL, then on return it will be filled with the horizontal offset for each character in the string on the row where it is displayed. Non-printing characters will have the offset ~0. The caller is responsible for allocating a buffer large enough so that there is one entry for each character in the string, not including the null-terminator. It is possible when character display is normalized that some character cells overlap. @retval EFI_SUCCESS The string was successfully updated. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for RowInfoArray or Blt. @retval EFI_INVALID_PARAMETER The String or Blt was NULL. @retval EFI_INVALID_PARAMETER Flags were invalid combination. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_STRING_TO_IMAGE)( IN CONST EFI_HII_FONT_PROTOCOL *This, IN EFI_HII_OUT_FLAGS Flags, IN CONST EFI_STRING String, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY, OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, OUT UINTN *RowInfoArraySize OPTIONAL, OUT UINTN *ColumnInfoArray OPTIONAL ); /** This function renders a string as a bitmap or to the screen and can clip or wrap the string. The bitmap is either supplied by the caller or allocated by the function. The strings are drawn with the font, size and style specified and can be drawn transparently or opaquely. The function can also return information about each row and each character's position on the row. If EFI_HII_OUT_FLAG_CLIP is set, then text will be formatted based only on explicit line breaks, and all pixels that would lie outside the bounding box specified by Width and Height are ignored. The information in the RowInfoArray only describes characters which are at least partially displayed. For the final row, the LineHeight and BaseLine may describe pixels which are outside the limit specified by Height (unless EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is specified) even though those pixels were not drawn. If EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that if a character's right-most on pixel cannot fit, then it will not be drawn at all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that if a row's bottom most pixel cannot fit, then it will not be drawn at all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_WRAP is set, then text will be wrapped at the right-most line-break opportunity prior to a character whose right-most extent would exceed Width. If no line-break opportunity can be found, then the text will behave as if EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set. This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is ignored and all off" pixels in the character's glyph will use the pixel value from Blt. This flag cannot be used if Blt is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs are not drawn. Otherwise, they are replaced with Unicode character code 0xFFFD (REPLACEMENT CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit line break characters will be ignored. If EFI_HII_DIRECT_TO_SCREEN is set, then the string will be written directly to the output device specified by Screen. Otherwise the string will be rendered to the bitmap specified by Bitmap. @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. @param Flags Describes how the string is to be drawn. @param PackageList The package list in the HII database to search for the specified string. @param StringId The string's id, which is unique within PackageList. @param Language Points to the language for the retrieved string. If NULL, then the current system language is used. @param StringInfo Points to the string output information, including the color and font. If NULL, then the string will be output in the default system font and color. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The string will be drawn onto this image and EFI_HII_OUT_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX, BltY Specifies the offset from the left and top edge of the output image of the first character cell in the image. @param RowInfoArray If this is non-NULL on entry, then on exit, this will point to an allocated buffer containing row information and RowInfoArraySize will be updated to contain the number of elements. This array describes the characters which were at least partially drawn and the heights of the rows. It is the caller's responsibility to free this buffer. @param RowInfoArraySize If this is non-NULL on entry, then on exit it contains the number of elements in RowInfoArray. @param ColumnInfoArray If non-NULL, on return it is filled with the horizontal offset for each character in the string on the row where it is displayed. Non-printing characters will have the offset ~0. The caller is responsible to allocate a buffer large enough so that there is one entry for each character in the string, not including the null-terminator. It is possible when character display is normalized that some character cells overlap. @retval EFI_SUCCESS The string was successfully updated. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for RowInfoArray or Blt. @retval EFI_INVALID_PARAMETER The String, or Blt, or Height, or Width was NULL. @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL. @retval EFI_INVALID_PARAMETER Flags were invalid combination. @retval EFI_NOT_FOUND The specified PackageList is not in the Database, or the stringid is not in the specified PackageList. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_STRING_ID_TO_IMAGE)( IN CONST EFI_HII_FONT_PROTOCOL *This, IN EFI_HII_OUT_FLAGS Flags, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY, OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, OUT UINTN *RowInfoArraySize OPTIONAL, OUT UINTN *ColumnInfoArray OPTIONAL ); /** Convert the glyph for a single character into a bitmap. @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. @param Char The character to retrieve. @param StringInfo Points to the string font and color information or NULL if the string should use the default system font and color. @param Blt This must point to a NULL on entry. A buffer will be allocated to hold the output and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param Baseline The number of pixels from the bottom of the bitmap to the baseline. @retval EFI_SUCCESS The glyph bitmap created. @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt. @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the glyph for Unicode character code 0xFFFD. @retval EFI_INVALID_PARAMETER Blt is NULL, or Width is NULL, or Height is NULL **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_GLYPH)( IN CONST EFI_HII_FONT_PROTOCOL *This, IN CONST CHAR16 Char, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo, OUT EFI_IMAGE_OUTPUT **Blt, OUT UINTN *Baseline OPTIONAL ); /** This function iterates through fonts which match the specified font, using the specified criteria. If String is non-NULL, then all of the characters in the string must exist in order for a candidate font to be returned. @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. @param FontHandle On entry, points to the font handle returned by a previous call to GetFontInfo() or NULL to start with the first font. On return, points to the returned font handle or points to NULL if there are no more matching fonts. @param StringInfoIn Upon entry, points to the font to return information about. If NULL, then the information about the system default font will be returned. @param StringInfoOut Upon return, contains the matching font's information. If NULL, then no information is returned. This buffer is allocated with a call to the Boot Service AllocatePool(). It is the caller's responsibility to call the Boot Service FreePool() when the caller no longer requires the contents of StringInfoOut. @param String Points to the string which will be tested to determine if all characters are available. If NULL, then any font is acceptable. @retval EFI_SUCCESS Matching font returned successfully. @retval EFI_NOT_FOUND No matching font was found. @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_FONT_INFO)( IN CONST EFI_HII_FONT_PROTOCOL *This, IN OUT EFI_FONT_HANDLE *FontHandle, IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL, OUT EFI_FONT_DISPLAY_INFO **StringInfoOut, IN CONST EFI_STRING String OPTIONAL ); /// /// The protocol provides the service to retrieve the font informations. /// struct _EFI_HII_FONT_PROTOCOL { EFI_HII_STRING_TO_IMAGE StringToImage; EFI_HII_STRING_ID_TO_IMAGE StringIdToImage; EFI_HII_GET_GLYPH GetGlyph; EFI_HII_GET_FONT_INFO GetFontInfo; }; extern EFI_GUID gEfiHiiFontProtocolGuid; #endif /** @file The file provides services to access to images in the images database. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __HII_IMAGE_H__ #define __HII_IMAGE_H__ #include #define EFI_HII_IMAGE_PROTOCOL_GUID \ { 0x31a6406a, 0x6bdf, 0x4e46, { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } } typedef struct _EFI_HII_IMAGE_PROTOCOL EFI_HII_IMAGE_PROTOCOL; /// /// Flags in EFI_IMAGE_INPUT /// #define EFI_IMAGE_TRANSPARENT 0x00000001 /** Definition of EFI_IMAGE_INPUT. @param Flags Describe image characteristics. If EFI_IMAGE_TRANSPARENT is set, then the image was designed for transparent display. @param Width Image width, in pixels. @param Height Image height, in pixels. @param Bitmap A pointer to the actual bitmap, organized left-to-right, top-to-bottom. The size of the bitmap is Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL). **/ typedef struct _EFI_IMAGE_INPUT { UINT32 Flags; UINT16 Width; UINT16 Height; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap; } EFI_IMAGE_INPUT; /** This function adds the image Image to the group of images owned by PackageList, and returns a new image identifier (ImageId). @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. @param PackageList Handle of the package list where this image will be added. @param ImageId On return, contains the new image id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The new image was added successfully @retval EFI_OUT_OF_RESOURCES Could not add the image. @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_NEW_IMAGE)( IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, OUT EFI_IMAGE_ID *ImageId, IN CONST EFI_IMAGE_INPUT *Image ); /** This function retrieves the image specified by ImageId which is associated with the specified PackageList and copies it into the buffer specified by Image. If the image specified by ImageId is not present in the specified PackageList, then EFI_NOT_FOUND is returned. If the buffer specified by ImageSize is too small to hold the image, then EFI_BUFFER_TOO_SMALL will be returned. ImageSize will be updated to the size of buffer actually required to hold the image. @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. @param PackageList The package list in the HII database to search for the specified image. @param ImageId The image's id, which is unique within PackageList. @param Image Points to the new image. @retval EFI_SUCCESS The image was returned successfully. @retval EFI_NOT_FOUND The image specified by ImageId is not available. Or The specified PackageList is not in the database. @retval EFI_INVALID_PARAMETER The Image or Langugae was NULL. @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not enough memory. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_IMAGE)( IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, OUT EFI_IMAGE_INPUT *Image ); /** This function updates the image specified by ImageId in the specified PackageListHandle to the image specified by Image. @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. @param PackageList The package list containing the images. @param ImageId The image id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The image was successfully updated. @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. The specified PackageList is not in the database. @retval EFI_INVALID_PARAMETER The Image or Language was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_SET_IMAGE)( IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN CONST EFI_IMAGE_INPUT *Image ); /// /// EFI_HII_DRAW_FLAGS describes how the image is to be drawn. /// These flags are defined as EFI_HII_DRAW_FLAG_*** /// typedef UINT32 EFI_HII_DRAW_FLAGS; #define EFI_HII_DRAW_FLAG_CLIP 0x00000001 #define EFI_HII_DRAW_FLAG_TRANSPARENT 0x00000030 #define EFI_HII_DRAW_FLAG_DEFAULT 0x00000000 #define EFI_HII_DRAW_FLAG_FORCE_TRANS 0x00000010 #define EFI_HII_DRAW_FLAG_FORCE_OPAQUE 0x00000020 #define EFI_HII_DIRECT_TO_SCREEN 0x00000080 /** Definition of EFI_IMAGE_OUTPUT. @param Width Width of the output image. @param Height Height of the output image. @param Bitmap Points to the output bitmap. @param Screen Points to the EFI_GRAPHICS_OUTPUT_PROTOCOL which describes the screen on which to draw the specified image. **/ typedef struct _EFI_IMAGE_OUTPUT { UINT16 Width; UINT16 Height; union { EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap; EFI_GRAPHICS_OUTPUT_PROTOCOL *Screen; } Image; } EFI_IMAGE_OUTPUT; /** This function renders an image to a bitmap or the screen using the specified color and options. It draws the image on an existing bitmap, allocates a new bitmap or uses the screen. The images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then all pixels drawn outside the bounding box specified by Width and Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT is set, then all 'off' pixels in the images drawn will use the pixel value from Blt. This flag cannot be used if Blt is NULL upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then the image will be written directly to the output device specified by Screen. Otherwise the image will be rendered to the bitmap specified by Bitmap. @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. @param Flags Describes how the image is to be drawn. EFI_HII_DRAW_FLAGS is defined in Related Definitions, below. @param Image Points to the image to be displayed. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The image will be drawn onto this image and EFI_HII_DRAW_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX, BltY Specifies the offset from the left and top edge of the image of the first pixel in the image. @retval EFI_SUCCESS The image was successfully updated. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for RowInfoArray or Blt. @retval EFI_INVALID_PARAMETER The Image or Blt or Height or Width was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DRAW_IMAGE)( IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN CONST EFI_IMAGE_INPUT *Image, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY ); /** This function renders an image as a bitmap or to the screen and can clip the image. The bitmap is either supplied by the caller or else is allocated by the function. The images can be drawn transparently or opaquely. If EFI_HII_DRAW_FLAG_CLIP is set, then all pixels drawn outside the bounding box specified by Width and Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT is set, then all "off" pixels in the character's glyph will use the pixel value from Blt. This flag cannot be used if Blt is NULL upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then the image will be written directly to the output device specified by Screen. Otherwise the image will be rendered to the bitmap specified by Bitmap. This function renders an image to a bitmap or the screen using the specified color and options. It draws the image on an existing bitmap, allocates a new bitmap or uses the screen. The images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then all pixels drawn outside the bounding box specified by Width and Height are ignored. The EFI_HII_DRAW_FLAG_TRANSPARENT flag determines whether the image will be drawn transparent or opaque. If EFI_HII_DRAW_FLAG_FORCE_TRANS is set, then the image will be drawn so that all 'off' pixels in the image will be drawn using the pixel value from Blt and all other pixels will be copied. If EFI_HII_DRAW_FLAG_FORCE_OPAQUE is set, then the image's pixels will be copied directly to the destination. If EFI_HII_DRAW_FLAG_DEFAULT is set, then the image will be drawn transparently or opaque, depending on the image's transparency setting (see EFI_IMAGE_TRANSPARENT). Images cannot be drawn transparently if Blt is NULL. If EFI_HII_DIRECT_TO_SCREEN is set, then the image will be written directly to the output device specified by Screen. Otherwise the image will be rendered to the bitmap specified by Bitmap. @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. @param Flags Describes how the image is to be drawn. @param PackageList The package list in the HII database to search for the specified image. @param ImageId The image's id, which is unique within PackageList. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The image will be drawn onto this image and EFI_HII_DRAW_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX, BltY Specifies the offset from the left and top edge of the output image of the first pixel in the image. @retval EFI_SUCCESS The image was successfully updated. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for RowInfoArray or Blt. @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. Or The specified PackageList is not in the database. @retval EFI_INVALID_PARAMETER The Blt was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DRAW_IMAGE_ID)( IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY ); /// /// Services to access to images in the images database. /// struct _EFI_HII_IMAGE_PROTOCOL { EFI_HII_NEW_IMAGE NewImage; EFI_HII_GET_IMAGE GetImage; EFI_HII_SET_IMAGE SetImage; EFI_HII_DRAW_IMAGE DrawImage; EFI_HII_DRAW_IMAGE_ID DrawImageId; }; extern EFI_GUID gEfiHiiImageProtocolGuid; #endif /** @file This protocol provides generic image decoder interfaces to various image formats. (C) Copyright 2016 Hewlett Packard Enterprise Development LP
Copyright (c) 2016-2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.6. **/ #ifndef __HII_IMAGE_DECODER_H__ #define __HII_IMAGE_DECODER_H__ #include #define EFI_HII_IMAGE_DECODER_PROTOCOL_GUID \ {0x9e66f251, 0x727c, 0x418c, { 0xbf, 0xd6, 0xc2, 0xb4, 0x25, 0x28, 0x18, 0xea }} #define EFI_HII_IMAGE_DECODER_NAME_JPEG_GUID \ {0xefefd093, 0xd9b, 0x46eb, { 0xa8, 0x56, 0x48, 0x35, 0x7, 0x0, 0xc9, 0x8 }} #define EFI_HII_IMAGE_DECODER_NAME_PNG_GUID \ {0xaf060190, 0x5e3a, 0x4025, { 0xaf, 0xbd, 0xe1, 0xf9, 0x5, 0xbf, 0xaa, 0x4c }} typedef struct _EFI_HII_IMAGE_DECODER_PROTOCOL EFI_HII_IMAGE_DECODER_PROTOCOL; typedef enum { EFI_HII_IMAGE_DECODER_COLOR_TYPE_RGB = 0x0, EFI_HII_IMAGE_DECODER_COLOR_TYPE_RGBA = 0x1, EFI_HII_IMAGE_DECODER_COLOR_TYPE_CMYK = 0x2, EFI_HII_IMAGE_DECODER_COLOR_TYPE_UNKNOWN = 0xFF } EFI_HII_IMAGE_DECODER_COLOR_TYPE; // // EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER // // DecoderName Name of the decoder // ImageInfoSize The size of entire image information structure in bytes // ImageWidth The image width // ImageHeight The image height // ColorType The color type, see EFI_HII_IMAGE_DECODER_COLOR_TYPE. // ColorDepthInBits The color depth in bits // typedef struct _EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER { EFI_GUID DecoderName; UINT16 ImageInfoSize; UINT16 ImageWidth; UINT16 ImageHeight; EFI_HII_IMAGE_DECODER_COLOR_TYPE ColorType; UINT8 ColorDepthInBits; } EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER; #define EFI_IMAGE_JPEG_SCANTYPE_PROGREESSIVE 0x01 #define EFI_IMAGE_JPEG_SCANTYPE_INTERLACED 0x02 // // EFI_HII_IMAGE_DECODER_JPEG_INFO // Header The common header // ScanType The scan type of JPEG image // Reserved Reserved // typedef struct _EFI_HII_IMAGE_DECODER_JPEG_INFO { EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER Header; UINT16 ScanType; UINT64 Reserved; } EFI_HII_IMAGE_DECODER_JPEG_INFO; // // EFI_HII_IMAGE_DECODER_PNG_INFO // Header The common header // Channels Number of channels in the PNG image // Reserved Reserved // typedef struct _EFI_HII_IMAGE_DECODER_PNG_INFO { EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER Header; UINT16 Channels; UINT64 Reserved; } EFI_HII_IMAGE_DECODER_PNG_INFO; // // EFI_HII_IMAGE_DECODER_OTHER_INFO // typedef struct _EFI_HII_IMAGE_DECODER_OTHER_INFO { EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER Header; CHAR16 ImageExtenion[1]; // // Variable length of image file extension name. // } EFI_HII_IMAGE_DECODER_OTHER_INFO; /** There could be more than one EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the system for different image formats. This function returns the decoder name which callers can use to find the proper image decoder for the image. It is possible to support multiple image formats in one EFI_HII_IMAGE_DECODER_PROTOCOL. The capability of the supported image formats is returned in DecoderName and NumberOfDecoderName. @param This EFI_HII_IMAGE_DECODER_PROTOCOL instance. @param DecoderName Pointer to a dimension to retrieve the decoder names in EFI_GUID format. The number of the decoder names is returned in NumberOfDecoderName. @param NumberofDecoderName Pointer to retrieve the number of decoders which supported by this decoder driver. @retval EFI_SUCCESS Get decoder name success. @retval EFI_UNSUPPORTED Get decoder name fail. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_IMAGE_DECODER_GET_NAME)( IN EFI_HII_IMAGE_DECODER_PROTOCOL *This, IN OUT EFI_GUID **DecoderName, IN OUT UINT16 *NumberOfDecoderName ); /** This function returns the image information of the given image raw data. This function first checks whether the image raw data is supported by this decoder or not. This function may go through the first few bytes in the image raw data for the specific data structure or the image signature. If the image is not supported by this image decoder, this function returns EFI_UNSUPPORTED to the caller. Otherwise, this function returns the proper image information to the caller. It is the caller?s responsibility to free the ImageInfo. @param This EFI_HII_IMAGE_DECODER_PROTOCOL instance. @param Image Pointer to the image raw data. @param SizeOfImage Size of the entire image raw data. @param ImageInfo Pointer to receive EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER. @retval EFI_SUCCESS Get image info success. @retval EFI_UNSUPPORTED Unsupported format of image. @retval EFI_INVALID_PARAMETER Incorrect parameter. @retval EFI_BAD_BUFFER_SIZE Not enough memory. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_IMAGE_DECODER_GET_IMAGE_INFO)( IN EFI_HII_IMAGE_DECODER_PROTOCOL *This, IN VOID *Image, IN UINTN SizeOfImage, IN OUT EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER **ImageInfo ); /** This function decodes the image which the image type of this image is supported by this EFI_HII_IMAGE_DECODER_PROTOCOL. If **Bitmap is not NULL, the caller intends to put the image in the given image buffer. That allows the caller to put an image overlap on the original image. The transparency is handled by the image decoder because the transparency capability depends on the image format. Callers can set Transparent to FALSE to force disabling the transparency process on the image. Forcing Transparent to FALSE may also improve the performance of the image decoding because the image decoder can skip the transparency processing. If **Bitmap is NULL, the image decoder allocates the memory buffer for the EFI_IMAGE_OUTPUT and decodes the image to the image buffer. It is the caller?s responsibility to free the memory for EFI_IMAGE_OUTPUT. Image decoder doesn?t have to handle the transparency in this case because there is no background image given by the caller. The background color in this case is all black (#00000000). @param This EFI_HII_IMAGE_DECODER_PROTOCOL instance. @param Image Pointer to the image raw data. @param ImageRawDataSize Size of the entire image raw data. @param Blt EFI_IMAGE_OUTPUT to receive the image or overlap the image on the original buffer. @param Transparent BOOLEAN value indicates whether the image decoder has to handle the transparent image or not. @retval EFI_SUCCESS Image decode success. @retval EFI_UNSUPPORTED Unsupported format of image. @retval EFI_INVALID_PARAMETER Incorrect parameter. @retval EFI_BAD_BUFFER_SIZE Not enough memory. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_IMAGE_DECODER_DECODE)( IN EFI_HII_IMAGE_DECODER_PROTOCOL *This, IN VOID *Image, IN UINTN ImageRawDataSize, IN OUT EFI_IMAGE_OUTPUT **Bitmap, IN BOOLEAN Transparent ); struct _EFI_HII_IMAGE_DECODER_PROTOCOL { EFI_HII_IMAGE_DECODER_GET_NAME GetImageDecoderName; EFI_HII_IMAGE_DECODER_GET_IMAGE_INFO GetImageInfo; EFI_HII_IMAGE_DECODER_DECODE DecodeImage; }; extern EFI_GUID gEfiHiiImageDecoderProtocolGuid; extern EFI_GUID gEfiHiiImageDecoderNameJpegGuid; extern EFI_GUID gEfiHiiImageDecoderNamePngGuid; #endif /** @file Protocol which allows access to the images in the images database. (C) Copyright 2016-2018 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.6. **/ #ifndef __EFI_HII_IMAGE_EX_H__ #define __EFI_HII_IMAGE_EX_H__ #include // // Global ID for the Hii Image Ex Protocol. // #define EFI_HII_IMAGE_EX_PROTOCOL_GUID \ {0x1a1241e6, 0x8f19, 0x41a9, { 0xbc, 0xe, 0xe8, 0xef, 0x39, 0xe0, 0x65, 0x46 }} typedef struct _EFI_HII_IMAGE_EX_PROTOCOL EFI_HII_IMAGE_EX_PROTOCOL; /** The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.NewImage(). This protocol invokes EFI_HII_IMAGE_PROTOCOL.NewImage() implicitly. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param PackageList Handle of the package list where this image will be added. @param ImageId On return, contains the new image id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The new image was added successfully. @retval EFI_NOT_FOUND The specified PackageList could not be found in database. @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources. @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_NEW_IMAGE_EX)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, OUT EFI_IMAGE_ID *ImageId, IN CONST EFI_IMAGE_INPUT *Image ); /** Return the information about the image, associated with the package list. The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.GetImage(). This function is similar to EFI_HII_IMAGE_PROTOCOL.GetImage().The difference is that this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the system if the decoder of the certain image type is not supported by the EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that supports the requested image type. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param PackageList The package list in the HII database to search for the specified image. @param ImageId The image's id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The new image was returned successfully. @retval EFI_NOT_FOUND The image specified by ImageId is not available. The specified PackageList is not in the Database. @retval EFI_INVALID_PARAMETER Image was NULL or ImageId was 0. @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not enough memory. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_IMAGE_EX)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, OUT EFI_IMAGE_INPUT *Image ); /** Change the information about the image. Same with EFI_HII_IMAGE_PROTOCOL.SetImage(),this protocol invokes EFI_HII_IMAGE_PROTOCOL.SetImage()implicitly. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param PackageList The package list containing the images. @param ImageId The image's id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The new image was successfully updated. @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. The specified PackageList is not in the database. @retval EFI_INVALID_PARAMETER The Image was NULL, the ImageId was 0 or the Image->Bitmap was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_SET_IMAGE_EX)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN CONST EFI_IMAGE_INPUT *Image ); /** Renders an image to a bitmap or to the display. The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.DrawImage(). This protocol invokes EFI_HII_IMAGE_PROTOCOL.DrawImage() implicitly. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param Flags Describes how the image is to be drawn. @param Image Points to the image to be displayed. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The image will be drawn onto this image and EFI_HII_DRAW_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX Specifies the offset from the left and top edge of the output image of the first pixel in the image. @param BltY Specifies the offset from the left and top edge of the output image of the first pixel in the image. @retval EFI_SUCCESS The image was successfully drawn. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt. @retval EFI_INVALID_PARAMETER The Image or Blt was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DRAW_IMAGE_EX)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN CONST EFI_IMAGE_INPUT *Image, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY ); /** Renders an image to a bitmap or the screen containing the contents of the specified image. This function is similar to EFI_HII_IMAGE_PROTOCOL.DrawImageId(). The difference is that this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the system if the decoder of the certain image type is not supported by the EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that supports the requested image type. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param Flags Describes how the image is to be drawn. @param PackageList The package list in the HII database to search for the specified image. @param ImageId The image's id, which is unique within PackageList. @param Blt If this points to a non-NULL on entry, this points to the image, which is Width pixels wide and Height pixels high. The image will be drawn onto this image and EFI_HII_DRAW_FLAG_CLIP is implied. If this points to a NULL on entry, then a buffer will be allocated to hold the generated image and the pointer updated on exit. It is the caller's responsibility to free this buffer. @param BltX Specifies the offset from the left and top edge of the output image of the first pixel in the image. @param BltY Specifies the offset from the left and top edge of the output image of the first pixel in the image. @retval EFI_SUCCESS The image was successfully drawn. @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt. @retval EFI_INVALID_PARAMETER The Blt was NULL or ImageId was 0. @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. The specified PackageList is not in the database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_DRAW_IMAGE_ID_EX)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY ); /** This function returns the image information to EFI_IMAGE_OUTPUT. Only the width and height are returned to the EFI_IMAGE_OUTPUT instead of decoding the image to the buffer. This function is used to get the geometry of the image. This function will try to locate all of the EFI_HII_IMAGE_DECODER_PROTOCOL installed on the system if the decoder of image type is not supported by the EFI_HII_IMAGE_EX_PROTOCOL. @param This A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance. @param PackageList Handle of the package list where this image will be searched. @param ImageId The image's id, which is unique within PackageList. @param Image Points to the image. @retval EFI_SUCCESS The new image was returned successfully. @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. The specified PackageList is not in the database. @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the image. @retval EFI_INVALID_PARAMETER The Image was NULL or the ImageId was 0. @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not enough memory. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_IMAGE_INFO)( IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, OUT EFI_IMAGE_OUTPUT *Image ); /// /// Protocol which allows access to the images in the images database. /// struct _EFI_HII_IMAGE_EX_PROTOCOL { EFI_HII_NEW_IMAGE_EX NewImageEx; EFI_HII_GET_IMAGE_EX GetImageEx; EFI_HII_SET_IMAGE_EX SetImageEx; EFI_HII_DRAW_IMAGE_EX DrawImageEx; EFI_HII_DRAW_IMAGE_ID_EX DrawImageIdEx; EFI_HII_GET_IMAGE_INFO GetImageInfo; }; extern EFI_GUID gEfiHiiImageExProtocolGuid; #endif /** @file EFI_HII_PACKAGE_LIST_PROTOCOL as defined in UEFI 2.1. Boot service LoadImage() installs EFI_HII_PACKAGE_LIST_PROTOCOL on the handle if the image contains a custom PE/COFF resource with the type 'HII'. The protocol's interface pointer points to the HII package list, which is contained in the resource's data. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __HII_PACKAGE_LIST_H__ #define __HII_PACKAGE_LIST_H__ #define EFI_HII_PACKAGE_LIST_PROTOCOL_GUID \ { 0x6a1ee763, 0xd47a, 0x43b4, {0xaa, 0xbe, 0xef, 0x1d, 0xe2, 0xab, 0x56, 0xfc}} typedef EFI_HII_PACKAGE_LIST_HEADER *EFI_HII_PACKAGE_LIST_PROTOCOL; extern EFI_GUID gEfiHiiPackageListProtocolGuid; #endif /** @file This protocol provides services to display a popup window. The protocol is typically produced by the forms browser and consumed by a driver callback handler. Copyright (c) 2017-2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.7. **/ #ifndef __HII_POPUP_H__ #define __HII_POPUP_H__ #define EFI_HII_POPUP_PROTOCOL_GUID \ {0x4311edc0, 0x6054, 0x46d4, {0x9e, 0x40, 0x89, 0x3e, 0xa9, 0x52, 0xfc, 0xcc}} #define EFI_HII_POPUP_PROTOCOL_REVISION 1 typedef struct _EFI_HII_POPUP_PROTOCOL EFI_HII_POPUP_PROTOCOL; typedef enum { EfiHiiPopupStyleInfo, EfiHiiPopupStyleWarning, EfiHiiPopupStyleError } EFI_HII_POPUP_STYLE; typedef enum { EfiHiiPopupTypeOk, EfiHiiPopupTypeOkCancel, EfiHiiPopupTypeYesNo, EfiHiiPopupTypeYesNoCancel } EFI_HII_POPUP_TYPE; typedef enum { EfiHiiPopupSelectionOk, EfiHiiPopupSelectionCancel, EfiHiiPopupSelectionYes, EfiHiiPopupSelectionNo } EFI_HII_POPUP_SELECTION; /** Displays a popup window. @param This A pointer to the EFI_HII_POPUP_PROTOCOL instance. @param PopupStyle Popup style to use. @param PopupType Type of the popup to display. @param HiiHandle HII handle of the string pack containing Message @param Message A message to display in the popup box. @param UserSelection User selection. @retval EFI_SUCCESS The popup box was successfully displayed. @retval EFI_INVALID_PARAMETER HiiHandle and Message do not define a valid HII string. @retval EFI_INVALID_PARAMETER PopupType is not one of the values defined by this specification. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to display the popup box. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_CREATE_POPUP)( IN EFI_HII_POPUP_PROTOCOL *This, IN EFI_HII_POPUP_STYLE PopupStyle, IN EFI_HII_POPUP_TYPE PopupType, IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID Message, OUT EFI_HII_POPUP_SELECTION *UserSelection OPTIONAL ); struct _EFI_HII_POPUP_PROTOCOL { UINT64 Revision; EFI_HII_CREATE_POPUP CreatePopup; }; extern EFI_GUID gEfiHiiPopupProtocolGuid; #endif /** @file The file provides services to manipulate string data. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.1. **/ #ifndef __HII_STRING_H__ #define __HII_STRING_H__ #include #define EFI_HII_STRING_PROTOCOL_GUID \ { 0xfd96974, 0x23aa, 0x4cdc, { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } } typedef struct _EFI_HII_STRING_PROTOCOL EFI_HII_STRING_PROTOCOL; /** This function adds the string String to the group of strings owned by PackageList, with the specified font information StringFontInfo, and returns a new string id. The new string identifier is guaranteed to be unique within the package list. That new string identifier is reserved for all languages in the package list. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList The handle of the package list where this string will be added. @param StringId On return, contains the new strings id, which is unique within PackageList. @param Language Points to the language for the new string. @param LanguageName Points to the printable language name to associate with the passed in Language field.If LanguageName is not NULL and the string package header's LanguageName associated with a given Language is not zero, the LanguageName being passed in will be ignored. @param String Points to the new null-terminated string. @param StringFontInfo Points to the new string's font information or NULL if the string should have the default system font, size and style. @retval EFI_SUCCESS The new string was added successfully. @retval EFI_NOT_FOUND The specified PackageList could not be found in database. @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources. @retval EFI_INVALID_PARAMETER String is NULL, or StringId is NULL, or Language is NULL. @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in current database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_NEW_STRING)( IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, OUT EFI_STRING_ID *StringId, IN CONST CHAR8 *Language, IN CONST CHAR16 *LanguageName OPTIONAL, IN CONST EFI_STRING String, IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL ); /** This function retrieves the string specified by StringId which is associated with the specified PackageList in the language Language and copies it into the buffer specified by String. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param Language Points to the language for the retrieved string. @param PackageList The package list in the HII database to search for the specified string. @param StringId The string's id, which is unique within PackageList. @param String Points to the new null-terminated string. @param StringSize On entry, points to the size of the buffer pointed to by String, in bytes. On return, points to the length of the string, in bytes. @param StringFontInfo If not NULL, points to the string's font information. It's caller's responsibility to free this buffer. @retval EFI_SUCCESS The string was returned successfully. @retval EFI_NOT_FOUND The string specified by StringId is not available. The specified PackageList is not in the database. @retval EFI_INVALID_LANGUAGE The string specified by StringId is available but not in the specified language. @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to hold the string. @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL. @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and String was NULL. @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_STRING)( IN CONST EFI_HII_STRING_PROTOCOL *This, IN CONST CHAR8 *Language, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, OUT EFI_STRING String, IN OUT UINTN *StringSize, OUT EFI_FONT_INFO **StringFontInfo OPTIONAL ); /** This function updates the string specified by StringId in the specified PackageList to the text specified by String and, optionally, the font information specified by StringFontInfo. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList The package list containing the strings. @param StringId The string's id, which is unique within PackageList. @param Language Points to the language for the updated string. @param String Points to the new null-terminated string. @param StringFontInfo Points to the string's font information or NULL if the string font information is not changed. @retval EFI_SUCCESS The string was updated successfully. @retval EFI_NOT_FOUND The string specified by StringId is not in the database. @retval EFI_INVALID_PARAMETER The String or Language was NULL. @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in current database. @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the task. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_SET_STRING)( IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language, IN EFI_STRING String, IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL ); /** This function returns the list of supported languages. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList The package list to examine. @param Languages Points to the buffer to hold the returned null-terminated ASCII string. @param LanguagesSize On entry, points to the size of the buffer pointed to by Languages, in bytes. On return, points to the length of Languages, in bytes. @retval EFI_SUCCESS The languages were returned successfully. @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL. @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero and Languages is NULL. @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of supported languages. LanguageSize is updated to contain the required size. @retval EFI_NOT_FOUND Could not find string package in specified packagelist. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_LANGUAGES)( IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN OUT CHAR8 *Languages, IN OUT UINTN *LanguagesSize ); /** Each string package has associated with it a single primary language and zero or more secondary languages. This routine returns the secondary languages associated with a package list. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList The package list to examine. @param PrimaryLanguage Points to the null-terminated ASCII string that specifies the primary language. Languages are specified in the format specified in Appendix M of the UEFI 2.0 specification. @param SecondaryLanguages Points to the buffer to hold the returned null-terminated ASCII string that describes the list of secondary languages for the specified PrimaryLanguage. If there are no secondary languages, the function returns successfully, but this is set to NULL. @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed to by SecondaryLanguages, in bytes. On return, points to the length of SecondaryLanguages in bytes. @retval EFI_SUCCESS Secondary languages were correctly returned. @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL. @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not zero and SecondaryLanguages is NULL. @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is too small to hold the returned information. SecondaryLanguageSize is updated to hold the size of the buffer required. @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not present in the specified package list. @retval EFI_NOT_FOUND The specified PackageList is not in the Database. **/ typedef EFI_STATUS (EFIAPI *EFI_HII_GET_2ND_LANGUAGES)( IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN CONST CHAR8 *PrimaryLanguage, IN OUT CHAR8 *SecondaryLanguages, IN OUT UINTN *SecondaryLanguagesSize ); /// /// Services to manipulate the string. /// struct _EFI_HII_STRING_PROTOCOL { EFI_HII_NEW_STRING NewString; EFI_HII_GET_STRING GetString; EFI_HII_SET_STRING SetString; EFI_HII_GET_LANGUAGES GetLanguages; EFI_HII_GET_2ND_LANGUAGES GetSecondaryLanguages; }; extern EFI_GUID gEfiHiiStringProtocolGuid; #endif /** @file This file defines the EFI HTTP Protocol interface. It is split into the following two main sections: HTTP Service Binding Protocol (HTTPSB) HTTP Protocol (HTTP) Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.5 **/ #ifndef __EFI_HTTP_PROTOCOL_H__ #define __EFI_HTTP_PROTOCOL_H__ #define EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c } \ } #define EFI_HTTP_PROTOCOL_GUID \ { \ 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b } \ } typedef struct _EFI_HTTP_PROTOCOL EFI_HTTP_PROTOCOL; /// /// EFI_HTTP_VERSION /// typedef enum { HttpVersion10, HttpVersion11, HttpVersionUnsupported } EFI_HTTP_VERSION; /// /// EFI_HTTP_METHOD /// typedef enum { HttpMethodGet, HttpMethodPost, HttpMethodPatch, HttpMethodOptions, HttpMethodConnect, HttpMethodHead, HttpMethodPut, HttpMethodDelete, HttpMethodTrace, HttpMethodMax } EFI_HTTP_METHOD; /// /// EFI_HTTP_STATUS_CODE /// typedef enum { HTTP_STATUS_UNSUPPORTED_STATUS = 0, HTTP_STATUS_100_CONTINUE, HTTP_STATUS_101_SWITCHING_PROTOCOLS, HTTP_STATUS_200_OK, HTTP_STATUS_201_CREATED, HTTP_STATUS_202_ACCEPTED, HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION, HTTP_STATUS_204_NO_CONTENT, HTTP_STATUS_205_RESET_CONTENT, HTTP_STATUS_206_PARTIAL_CONTENT, HTTP_STATUS_300_MULTIPLE_CHOICES, HTTP_STATUS_301_MOVED_PERMANENTLY, HTTP_STATUS_302_FOUND, HTTP_STATUS_303_SEE_OTHER, HTTP_STATUS_304_NOT_MODIFIED, HTTP_STATUS_305_USE_PROXY, HTTP_STATUS_307_TEMPORARY_REDIRECT, HTTP_STATUS_400_BAD_REQUEST, HTTP_STATUS_401_UNAUTHORIZED, HTTP_STATUS_402_PAYMENT_REQUIRED, HTTP_STATUS_403_FORBIDDEN, HTTP_STATUS_404_NOT_FOUND, HTTP_STATUS_405_METHOD_NOT_ALLOWED, HTTP_STATUS_406_NOT_ACCEPTABLE, HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED, HTTP_STATUS_408_REQUEST_TIME_OUT, HTTP_STATUS_409_CONFLICT, HTTP_STATUS_410_GONE, HTTP_STATUS_411_LENGTH_REQUIRED, HTTP_STATUS_412_PRECONDITION_FAILED, HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE, HTTP_STATUS_414_REQUEST_URI_TOO_LARGE, HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE, HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED, HTTP_STATUS_417_EXPECTATION_FAILED, HTTP_STATUS_500_INTERNAL_SERVER_ERROR, HTTP_STATUS_501_NOT_IMPLEMENTED, HTTP_STATUS_502_BAD_GATEWAY, HTTP_STATUS_503_SERVICE_UNAVAILABLE, HTTP_STATUS_504_GATEWAY_TIME_OUT, HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED, HTTP_STATUS_308_PERMANENT_REDIRECT } EFI_HTTP_STATUS_CODE; /// /// EFI_HTTPv4_ACCESS_POINT /// typedef struct { /// /// Set to TRUE to instruct the EFI HTTP instance to use the default address /// information in every TCP connection made by this instance. In addition, when set /// to TRUE, LocalAddress and LocalSubnet are ignored. /// BOOLEAN UseDefaultAddress; /// /// If UseDefaultAddress is set to FALSE, this defines the local IP address to be /// used in every TCP connection opened by this instance. /// EFI_IPv4_ADDRESS LocalAddress; /// /// If UseDefaultAddress is set to FALSE, this defines the local subnet to be used /// in every TCP connection opened by this instance. /// EFI_IPv4_ADDRESS LocalSubnet; /// /// This defines the local port to be used in /// every TCP connection opened by this instance. /// UINT16 LocalPort; } EFI_HTTPv4_ACCESS_POINT; /// /// EFI_HTTPv6_ACCESS_POINT /// typedef struct { /// /// Local IP address to be used in every TCP connection opened by this instance. /// EFI_IPv6_ADDRESS LocalAddress; /// /// Local port to be used in every TCP connection opened by this instance. /// UINT16 LocalPort; } EFI_HTTPv6_ACCESS_POINT; /// /// EFI_HTTP_CONFIG_DATA_ACCESS_POINT /// typedef struct { /// /// HTTP version that this instance will support. /// EFI_HTTP_VERSION HttpVersion; /// /// Time out (in milliseconds) when blocking for requests. /// UINT32 TimeOutMillisec; /// /// Defines behavior of EFI DNS and TCP protocols consumed by this instance. If /// FALSE, this instance will use EFI_DNS4_PROTOCOL and EFI_TCP4_PROTOCOL. If TRUE, /// this instance will use EFI_DNS6_PROTOCOL and EFI_TCP6_PROTOCOL. /// BOOLEAN LocalAddressIsIPv6; union { /// /// When LocalAddressIsIPv6 is FALSE, this points to the local address, subnet, and /// port used by the underlying TCP protocol. /// EFI_HTTPv4_ACCESS_POINT *IPv4Node; /// /// When LocalAddressIsIPv6 is TRUE, this points to the local IPv6 address and port /// used by the underlying TCP protocol. /// EFI_HTTPv6_ACCESS_POINT *IPv6Node; } AccessPoint; } EFI_HTTP_CONFIG_DATA; /// /// EFI_HTTP_REQUEST_DATA /// typedef struct { /// /// The HTTP method (e.g. GET, POST) for this HTTP Request. /// EFI_HTTP_METHOD Method; /// /// The URI of a remote host. From the information in this field, the HTTP instance /// will be able to determine whether to use HTTP or HTTPS and will also be able to /// determine the port number to use. If no port number is specified, port 80 (HTTP) /// is assumed. See RFC 3986 for more details on URI syntax. /// CHAR16 *Url; } EFI_HTTP_REQUEST_DATA; /// /// EFI_HTTP_RESPONSE_DATA /// typedef struct { /// /// Response status code returned by the remote host. /// EFI_HTTP_STATUS_CODE StatusCode; } EFI_HTTP_RESPONSE_DATA; /// /// EFI_HTTP_HEADER /// typedef struct { /// /// Null terminated string which describes a field name. See RFC 2616 Section 14 for /// detailed information about field names. /// CHAR8 *FieldName; /// /// Null terminated string which describes the corresponding field value. See RFC 2616 /// Section 14 for detailed information about field values. /// CHAR8 *FieldValue; } EFI_HTTP_HEADER; /// /// EFI_HTTP_MESSAGE /// typedef struct { /// /// HTTP message data. /// union { /// /// When the token is used to send a HTTP request, Request is a pointer to storage that /// contains such data as URL and HTTP method. /// EFI_HTTP_REQUEST_DATA *Request; /// /// When used to await a response, Response points to storage containing HTTP response /// status code. /// EFI_HTTP_RESPONSE_DATA *Response; } Data; /// /// Number of HTTP header structures in Headers list. On request, this count is /// provided by the caller. On response, this count is provided by the HTTP driver. /// UINTN HeaderCount; /// /// Array containing list of HTTP headers. On request, this array is populated by the /// caller. On response, this array is allocated and populated by the HTTP driver. It /// is the responsibility of the caller to free this memory on both request and /// response. /// EFI_HTTP_HEADER *Headers; /// /// Length in bytes of the HTTP body. This can be zero depending on the HttpMethod type. /// UINTN BodyLength; /// /// Body associated with the HTTP request or response. This can be NULL depending on /// the HttpMethod type. /// VOID *Body; } EFI_HTTP_MESSAGE; /// /// EFI_HTTP_TOKEN /// typedef struct { /// /// This Event will be signaled after the Status field is updated by the EFI HTTP /// Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. The Task Priority /// Level (TPL) of Event must be lower than or equal to TPL_CALLBACK. /// EFI_EVENT Event; /// /// Status will be set to one of the following value if the HTTP request is /// successfully sent or if an unexpected error occurs: /// EFI_SUCCESS: The HTTP request was successfully sent to the remote host. /// EFI_HTTP_ERROR: The response message was successfully received but contains a /// HTTP error. The response status code is returned in token. /// EFI_ABORTED: The HTTP request was cancelled by the caller and removed from /// the transmit queue. /// EFI_TIMEOUT: The HTTP request timed out before reaching the remote host. /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. /// EFI_STATUS Status; /// /// Pointer to storage containing HTTP message data. /// EFI_HTTP_MESSAGE *Message; } EFI_HTTP_TOKEN; /** Returns the operational parameters for the current HTTP child instance. The GetModeData() function is used to read the current mode data (operational parameters) for this HTTP protocol instance. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[out] HttpConfigData Point to buffer for operational parameters of this HTTP instance. It is the responsibility of the caller to allocate the memory for HttpConfigData and HttpConfigData->AccessPoint.IPv6Node/IPv4Node. In fact, it is recommended to allocate sufficient memory to record IPv6Node since it is big enough for all possibilities. @retval EFI_SUCCESS Operation succeeded. @retval EFI_INVALID_PARAMETER This is NULL. HttpConfigData is NULL. HttpConfigData->AccessPoint.IPv4Node or HttpConfigData->AccessPoint.IPv6Node is NULL. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_GET_MODE_DATA)( IN EFI_HTTP_PROTOCOL *This, OUT EFI_HTTP_CONFIG_DATA *HttpConfigData ); /** Initialize or brutally reset the operational parameters for this EFI HTTP instance. The Configure() function does the following: When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring timeout, local address, port, etc. When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active connections with remote hosts, canceling all asynchronous tokens, and flush request and response buffers without informing the appropriate hosts. No other EFI HTTP function can be executed by this instance until the Configure() function is executed and returns successfully. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] HttpConfigData Pointer to the configure data to configure the instance. @retval EFI_SUCCESS Operation succeeded. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. HttpConfigData->LocalAddressIsIPv6 is FALSE and HttpConfigData->AccessPoint.IPv4Node is NULL. HttpConfigData->LocalAddressIsIPv6 is TRUE and HttpConfigData->AccessPoint.IPv6Node is NULL. @retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling Configure() with NULL to reset it. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when executing Configure(). @retval EFI_UNSUPPORTED One or more options in ConfigData are not supported in the implementation. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_CONFIGURE)( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL ); /** The Request() function queues an HTTP request to this HTTP instance, similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent successfully, or if there is an error, Status in token will be updated and Event will be signaled. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Pointer to storage containing HTTP request token. @retval EFI_SUCCESS Outgoing data was processed. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token is NULL. Token->Message is NULL. Token->Message->Body is not NULL, Token->Message->BodyLength is non-zero, and Token->Message->Data is NULL, but a previous call to Request()has not been completed successfully. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_REQUEST)( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ); /** Abort an asynchronous HTTP request or response token. The Cancel() function aborts a pending HTTP request or response transaction. If Token is not NULL and the token is in transmit or receive queues when it is being cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will be signaled. If the token is not in one of the queues, which usually means that the asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL, all asynchronous tokens issued by Request() or Response() will be aborted. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Point to storage containing HTTP request or response token. @retval EFI_SUCCESS Request and Response queues are successfully flushed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance hasn't been configured. @retval EFI_NOT_FOUND The asynchronous request or response token is not found. @retval EFI_UNSUPPORTED The implementation does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_CANCEL)( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ); /** The Response() function queues an HTTP response to this HTTP instance, similar to Receive() function in the EFI TCP driver. When the HTTP Response is received successfully, or if there is an error, Status in token will be updated and Event will be signaled. The HTTP driver will queue a receive token to the underlying TCP instance. When data is received in the underlying TCP instance, the data will be parsed and Token will be populated with the response data. If the data received from the remote host contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting (asynchronously) for more data to be sent from the remote host before signaling Event in Token. It is the responsibility of the caller to allocate a buffer for Body and specify the size in BodyLength. If the remote host provides a response that contains a content body, up to BodyLength bytes will be copied from the receive buffer into Body and BodyLength will be updated with the amount of bytes received and copied to Body. This allows the client to download a large file in chunks instead of into one contiguous block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive token to underlying TCP instance. If data arrives in the receive buffer, up to BodyLength bytes of data will be copied to Body. The HTTP driver will then update BodyLength with the amount of bytes received and copied to Body. If the HTTP driver does not have an open underlying TCP connection with the host specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain an open TCP connection between client and host. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Pointer to storage containing HTTP response token. @retval EFI_SUCCESS Allocation succeeded. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been initialized. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token is NULL. Token->Message->Headers is NULL. Token->Message is NULL. Token->Message->Body is not NULL, Token->Message->BodyLength is non-zero, and Token->Message->Data is NULL, but a previous call to Response() has not been completed successfully. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. @retval EFI_ACCESS_DENIED An open TCP connection is not present with the host specified by response URL. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_RESPONSE)( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ); /** The Poll() function can be used by network drivers and applications to increase the rate that data packets are moved between the communication devices and the transmit and receive queues. In some systems, the periodic timer event in the managed network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the Poll() function more often. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed.. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_READY No incoming or outgoing data is processed. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_POLL)( IN EFI_HTTP_PROTOCOL *This ); /// /// The EFI HTTP protocol is designed to be used by EFI drivers and applications to /// create and transmit HTTP Requests, as well as handle HTTP responses that are /// returned by a remote host. This EFI protocol uses and relies on an underlying EFI /// TCP protocol. /// struct _EFI_HTTP_PROTOCOL { EFI_HTTP_GET_MODE_DATA GetModeData; EFI_HTTP_CONFIGURE Configure; EFI_HTTP_REQUEST Request; EFI_HTTP_CANCEL Cancel; EFI_HTTP_RESPONSE Response; EFI_HTTP_POLL Poll; }; extern EFI_GUID gEfiHttpServiceBindingProtocolGuid; extern EFI_GUID gEfiHttpProtocolGuid; #endif /** @file This file defines the EFI HTTP Boot Callback Protocol interface. Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.7 **/ #ifndef __EFI_HTTP_BOOT_CALLBACK_H__ #define __EFI_HTTP_BOOT_CALLBACK_H__ #define EFI_HTTP_BOOT_CALLBACK_PROTOCOL_GUID \ { \ 0xba23b311, 0x343d, 0x11e6, {0x91, 0x85, 0x58, 0x20, 0xb1, 0xd6, 0x52, 0x99} \ } typedef struct _EFI_HTTP_BOOT_CALLBACK_PROTOCOL EFI_HTTP_BOOT_CALLBACK_PROTOCOL; /// /// EFI_HTTP_BOOT_CALLBACK_DATA_TYPE /// typedef enum { /// /// Data points to a DHCP4 packet which is about to transmit or has received. /// HttpBootDhcp4, /// /// Data points to a DHCP6 packet which is about to be transmit or has received. /// HttpBootDhcp6, /// /// Data points to an EFI_HTTP_MESSAGE structure, whichcontians a HTTP request message /// to be transmitted. /// HttpBootHttpRequest, /// /// Data points to an EFI_HTTP_MESSAGE structure, which contians a received HTTP /// response message. /// HttpBootHttpResponse, /// /// Part of the entity body has been received from the HTTP server. Data points to the /// buffer of the entity body data. /// HttpBootHttpEntityBody, HttpBootTypeMax } EFI_HTTP_BOOT_CALLBACK_DATA_TYPE; /** Callback function that is invoked when the HTTP Boot driver is about to transmit or has received a packet. This function is invoked when the HTTP Boot driver is about to transmit or has received packet. Parameters DataType and Received specify the type of event and the format of the buffer pointed to by Data. Due to the polling nature of UEFI device drivers, this callback function should not execute for more than 5 ms. The returned status code determines the behavior of the HTTP Boot driver. @param[in] This Pointer to the EFI_HTTP_BOOT_CALLBACK_PROTOCOL instance. @param[in] DataType The event that occurs in the current state. @param[in] Received TRUE if the callback is being invoked due to a receive event. FALSE if the callback is being invoked due to a transmit event. @param[in] DataLength The length in bytes of the buffer pointed to by Data. @param[in] Data A pointer to the buffer of data, the data type is specified by DataType. @retval EFI_SUCCESS Tells the HTTP Boot driver to continue the HTTP Boot process. @retval EFI_ABORTED Tells the HTTP Boot driver to abort the current HTTP Boot process. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_BOOT_CALLBACK)( IN EFI_HTTP_BOOT_CALLBACK_PROTOCOL *This, IN EFI_HTTP_BOOT_CALLBACK_DATA_TYPE DataType, IN BOOLEAN Received, IN UINT32 DataLength, IN VOID *Data OPTIONAL ); /// /// EFI HTTP Boot Callback Protocol is invoked when the HTTP Boot driver is about to transmit or /// has received a packet. The EFI HTTP Boot Callback Protocol must be installed on the same handle /// as the Load File Protocol for the HTTP Boot. /// struct _EFI_HTTP_BOOT_CALLBACK_PROTOCOL { EFI_HTTP_BOOT_CALLBACK Callback; }; extern EFI_GUID gEfiHttpBootCallbackProtocolGuid; #endif /** @file EFI HTTP Utilities protocol provides a platform independent abstraction for HTTP message comprehension. Copyright (c) 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.5 **/ #ifndef __EFI_HTTP_UTILITIES_PROTOCOL_H__ #define __EFI_HTTP_UTILITIES_PROTOCOL_H__ #include #define EFI_HTTP_UTILITIES_PROTOCOL_GUID \ { \ 0x3e35c163, 0x4074, 0x45dd, {0x43, 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 } \ } typedef struct _EFI_HTTP_UTILITIES_PROTOCOL EFI_HTTP_UTILITIES_PROTOCOL; /** Create HTTP header based on a combination of seed header, fields to delete, and fields to append. The Build() function is used to manage the headers portion of an HTTP message by providing the ability to add, remove, or replace HTTP headers. @param[in] This Pointer to EFI_HTTP_UTILITIES_PROTOCOL instance. @param[in] SeedMessageSize Size of the initial HTTP header. This can be zero. @param[in] SeedMessage Initial HTTP header to be used as a base for building a new HTTP header. If NULL, SeedMessageSize is ignored. @param[in] DeleteCount Number of null-terminated HTTP header field names in DeleteList. @param[in] DeleteList List of null-terminated HTTP header field names to remove from SeedMessage. Only the field names are in this list because the field values are irrelevant to this operation. @param[in] AppendCount Number of header fields in AppendList. @param[in] AppendList List of HTTP headers to populate NewMessage with. If SeedMessage is not NULL, AppendList will be appended to the existing list from SeedMessage in NewMessage. @param[out] NewMessageSize Pointer to number of header fields in NewMessage. @param[out] NewMessage Pointer to a new list of HTTP headers based on. @retval EFI_SUCCESS Add, remove, and replace operations succeeded. @retval EFI_OUT_OF_RESOURCES Could not allocate memory for NewMessage. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_UTILS_BUILD)( IN EFI_HTTP_UTILITIES_PROTOCOL *This, IN UINTN SeedMessageSize, IN VOID *SeedMessage OPTIONAL, IN UINTN DeleteCount, IN CHAR8 *DeleteList[] OPTIONAL, IN UINTN AppendCount, IN EFI_HTTP_HEADER *AppendList[] OPTIONAL, OUT UINTN *NewMessageSize, OUT VOID **NewMessage ); /** Parses HTTP header and produces an array of key/value pairs. The Parse() function is used to transform data stored in HttpHeader into a list of fields paired with their corresponding values. @param[in] This Pointer to EFI_HTTP_UTILITIES_PROTOCOL instance. @param[in] HttpMessage Contains raw unformatted HTTP header string. @param[in] HttpMessageSize Size of HTTP header. @param[out] HeaderFields Array of key/value header pairs. @param[out] FieldCount Number of headers in HeaderFields. @retval EFI_SUCCESS Allocation succeeded. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been initialized. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. HttpMessage is NULL. HeaderFields is NULL. FieldCount is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HTTP_UTILS_PARSE)( IN EFI_HTTP_UTILITIES_PROTOCOL *This, IN CHAR8 *HttpMessage, IN UINTN HttpMessageSize, OUT EFI_HTTP_HEADER **HeaderFields, OUT UINTN *FieldCount ); /// /// EFI_HTTP_UTILITIES_PROTOCOL /// designed to be used by EFI drivers and applications to parse HTTP /// headers from a byte stream. This driver is neither dependent on /// network connectivity, nor the existence of an underlying network /// infrastructure. /// struct _EFI_HTTP_UTILITIES_PROTOCOL { EFI_HTTP_UTILS_BUILD Build; EFI_HTTP_UTILS_PARSE Parse; }; extern EFI_GUID gEfiHttpUtilitiesProtocolGuid; #endif /** @file This file declares EFI IDE Controller Init Protocol The EFI_IDE_CONTROLLER_INIT_PROTOCOL provides the chipset-specific information to the driver entity. This protocol is mandatory for IDE controllers if the IDE devices behind the controller are to be enumerated by a driver entity. There can only be one instance of EFI_IDE_CONTROLLER_INIT_PROTOCOL for each IDE controller in a system. It is installed on the handle that corresponds to the IDE controller. A driver entity that wishes to manage an IDE bus and possibly IDE devices in a system will have to retrieve the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance that is associated with the controller to be managed. A device handle for an IDE controller must contain an EFI_DEVICE_PATH_PROTOCOL. Copyright (c) 2007 - 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 _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H_ #define _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H_ #include /// /// Global ID for the EFI_IDE_CONTROLLER_INIT_PROTOCOL. /// #define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \ { \ 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9 } \ } /// /// Forward declaration for EFI_IDE_CONTROLLER_INIT_PROTOCOL. /// typedef struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL EFI_IDE_CONTROLLER_INIT_PROTOCOL; /// /// The phase of the IDE Controller enumeration. /// typedef enum { /// /// The driver entity is about to begin enumerating the devices /// behind the specified channel. This notification can be used to /// perform any chipset-specific programming. /// EfiIdeBeforeChannelEnumeration, /// /// The driver entity has completed enumerating the devices /// behind the specified channel. This notification can be used to /// perform any chipset-specific programming. /// EfiIdeAfterChannelEnumeration, /// /// The driver entity is about to reset the devices behind the /// specified channel. This notification can be used to perform any /// chipset-specific programming. /// EfiIdeBeforeChannelReset, /// /// The driver entity has completed resetting the devices behind /// the specified channel. This notification can be used to perform /// any chipset-specific programming. /// EfiIdeAfterChannelReset, /// /// The driver entity is about to detect the presence of devices /// behind the specified channel. This notification can be used to /// set up the bus signals to default levels or for implementing /// predelays. /// EfiIdeBusBeforeDevicePresenceDetection, /// /// The driver entity is done with detecting the presence of /// devices behind the specified channel. This notification can be /// used to perform any chipset-specific programming. /// EfiIdeBusAfterDevicePresenceDetection, /// /// The IDE bus is requesting the IDE controller driver to /// reprogram the IDE controller hardware and thereby reset all /// the mode and timing settings to default settings. /// EfiIdeResetMode, EfiIdeBusPhaseMaximum } EFI_IDE_CONTROLLER_ENUM_PHASE; /// /// This extended mode describes the SATA physical protocol. /// SATA physical layers can operate at different speeds. /// These speeds are defined below. Various PATA protocols /// and associated modes are not applicable to SATA devices. /// typedef enum { EfiAtaSataTransferProtocol } EFI_ATA_EXT_TRANSFER_PROTOCOL; /// /// Automatically detects the optimum SATA speed. /// #define EFI_SATA_AUTO_SPEED 0 /// /// Indicates a first-generation (Gen1) SATA speed. /// #define EFI_SATA_GEN1_SPEED 1 /// /// Indicates a second-generation (Gen2) SATA speed. /// #define EFI_SATA_GEN2_SPEED 2 /// /// EFI_ATA_MODE structure. /// typedef struct { BOOLEAN Valid; ///< TRUE if Mode is valid. UINT32 Mode; ///< The actual ATA mode. This field is not a bit map. } EFI_ATA_MODE; /// /// EFI_ATA_EXTENDED_MODE structure /// typedef struct { /// /// An enumeration defining various transfer protocols other than the protocols /// that exist at the time this specification was developed (i.e., PIO, single /// word DMA, multiword DMA, and UDMA). Each transfer protocol is associated /// with a mode. The various transfer protocols are defined by the ATA/ATAPI /// specification. This enumeration makes the interface extensible because we /// can support new transport protocols beyond UDMA. Type EFI_ATA_EXT_TRANSFER_PROTOCOL /// is defined below. /// EFI_ATA_EXT_TRANSFER_PROTOCOL TransferProtocol; /// /// The mode for operating the transfer protocol that is identified by TransferProtocol. /// UINT32 Mode; } EFI_ATA_EXTENDED_MODE; /// /// EFI_ATA_COLLECTIVE_MODE structure. /// typedef struct { /// /// This field specifies the PIO mode. PIO modes are defined in the ATA/ATAPI /// specification. The ATA/ATAPI specification defines the enumeration. In /// other words, a value of 1 in this field means PIO mode 1. The actual meaning /// of PIO mode 1 is governed by the ATA/ATAPI specification. Type EFI_ATA_MODE /// is defined below. /// EFI_ATA_MODE PioMode; /// /// This field specifies the single word DMA mode. Single word DMA modes are defined /// in the ATA/ATAPI specification, versions 1 and 2. Single word DMA support was /// obsoleted in the ATA/ATAPI specification, version 3. Therefore, most devices and /// controllers will not support this transfer mode. The ATA/ATAPI specification defines /// the enumeration. In other words, a value of 1 in this field means single word DMA /// mode 1. The actual meaning of single word DMA mode 1 is governed by the ATA/ /// ATAPI specification. /// EFI_ATA_MODE SingleWordDmaMode; /// /// This field specifies the multiword DMA mode. Various multiword DMA modes are /// defined in the ATA/ATAPI specification. A value of 1 in this field means multiword /// DMA mode 1. The actual meaning of multiword DMA mode 1 is governed by the /// ATA/ATAPI specification. /// EFI_ATA_MODE MultiWordDmaMode; /// /// This field specifies the ultra DMA (UDMA) mode. UDMA modes are defined in the /// ATA/ATAPI specification. A value of 1 in this field means UDMA mode 1. The /// actual meaning of UDMA mode 1 is governed by the ATA/ATAPI specification. /// EFI_ATA_MODE UdmaMode; /// /// The number of extended-mode bitmap entries. Extended modes describe transfer /// protocols beyond PIO, single word DMA, multiword DMA, and UDMA. This field /// can be zero and provides extensibility. /// UINT32 ExtModeCount; /// /// ExtModeCount number of entries. Each entry represents a transfer protocol other /// than the ones defined above (i.e., PIO, single word DMA, multiword DMA, and /// UDMA). This field is defined for extensibility. At this time, only one extended /// transfer protocol is defined to cover SATA transfers. Type /// EFI_ATA_EXTENDED_MODE is defined below. /// EFI_ATA_EXTENDED_MODE ExtMode[1]; } EFI_ATA_COLLECTIVE_MODE; /// /// EFI_ATA_IDENTIFY_DATA & EFI_ATAPI_IDENTIFY_DATA structure /// /// The definition of these two structures is not part of the protocol /// definition because the ATA/ATAPI Specification controls the definition /// of all the fields. The ATA/ATAPI Specification can obsolete old fields /// or redefine existing fields. typedef ATA_IDENTIFY_DATA EFI_ATA_IDENTIFY_DATA; typedef ATAPI_IDENTIFY_DATA EFI_ATAPI_IDENTIFY_DATA; /// /// This flag indicates whether the IDENTIFY data is a response from an ATA device /// (EFI_ATA_IDENTIFY_DATA) or response from an ATAPI device /// (EFI_ATAPI_IDENTIFY_DATA). According to the ATA/ATAPI specification, /// EFI_IDENTIFY_DATA is for an ATA device if bit 15 of the Config field is zero. /// The Config field is common to both EFI_ATA_IDENTIFY_DATA and /// EFI_ATAPI_IDENTIFY_DATA. /// #define EFI_ATAPI_DEVICE_IDENTIFY_DATA 0x8000 /// /// EFI_IDENTIFY_DATA structure. /// typedef union { /// /// The data that is returned by an ATA device upon successful completion /// of the ATA IDENTIFY_DEVICE command. /// EFI_ATA_IDENTIFY_DATA AtaData; /// /// The data that is returned by an ATAPI device upon successful completion /// of the ATA IDENTIFY_PACKET_DEVICE command. /// EFI_ATAPI_IDENTIFY_DATA AtapiData; } EFI_IDENTIFY_DATA; /** Returns the information about the specified IDE channel. This function can be used to obtain information about a particular IDE channel. The driver entity uses this information during the enumeration process. If Enabled is set to FALSE, the driver entity will not scan the channel. Note that it will not prevent an operating system driver from scanning the channel. For most of today's controllers, MaxDevices will either be 1 or 2. For SATA controllers, this value will always be 1. SATA configurations can contain SATA port multipliers. SATA port multipliers behave like SATA bridges and can support up to 16 devices on the other side. If a SATA port out of the IDE controller is connected to a port multiplier, MaxDevices will be set to the number of SATA devices that the port multiplier supports. Because today's port multipliers support up to fifteen SATA devices, this number can be as large as fifteen. The IDE bus driver is required to scan for the presence of port multipliers behind an SATA controller and enumerate up to MaxDevices number of devices behind the port multiplier. In this context, the devices behind a port multiplier constitute a channel. @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Channel Zero-based channel number. @param[out] Enabled TRUE if this channel is enabled. Disabled channels are not scanned to see if any devices are present. @param[out] MaxDevices The maximum number of IDE devices that the bus driver can expect on this channel. For the ATA/ATAPI specification, version 6, this number will either be one or two. For Serial ATA (SATA) configurations with a port multiplier, this number can be as large as fifteen. @retval EFI_SUCCESS Information was returned without any errors. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_GET_CHANNEL_INFO)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, OUT BOOLEAN *Enabled, OUT UINT8 *MaxDevices ); /** The notifications from the driver entity that it is about to enter a certain phase of the IDE channel enumeration process. This function can be used to notify the IDE controller driver to perform specific actions, including any chipset-specific initialization, so that the chipset is ready to enter the next phase. Seven notification points are defined at this time. More synchronization points may be added as required in the future. @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Phase The phase during enumeration. @param[in] Channel Zero-based channel number. @retval EFI_SUCCESS The notification was accepted without any errors. @retval EFI_UNSUPPORTED Phase is not supported. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). @retval EFI_NOT_READY This phase cannot be entered at this time; for example, an attempt was made to enter a Phase without having entered one or more previous Phase. **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_NOTIFY_PHASE)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase, IN UINT8 Channel ); /** Submits the device information to the IDE controller driver. This function is used by the driver entity to pass detailed information about a particular device to the IDE controller driver. The driver entity obtains this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData is the pointer to the response data buffer. The IdentifyData buffer is owned by the driver entity, and the IDE controller driver must make a local copy of the entire buffer or parts of the buffer as needed. The original IdentifyData buffer pointer may not be valid when - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point. The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to compute the optimum mode for the device. These fields are not limited to the timing information. For example, an implementation of the IDE controller driver may examine the vendor and type/mode field to match known bad drives. The driver entity may submit drive information in any order, as long as it submits information for all the devices belonging to the enumeration group before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() should be called with IdentifyData set to NULL. The IDE controller driver may not have any other mechanism to know whether a device is present or not. Therefore, setting IdentifyData to NULL does not constitute an error condition. EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a given (Channel, Device) pair. @param[in] This A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Channel Zero-based channel number. @param[in] Device Zero-based device number on the Channel. @param[in] IdentifyData The device's response to the ATA IDENTIFY_DEVICE command. @retval EFI_SUCCESS The information was accepted without any errors. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). @retval EFI_INVALID_PARAMETER Device is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_SUBMIT_DATA)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_IDENTIFY_DATA *IdentifyData ); /** Disqualifies specific modes for an IDE device. This function allows the driver entity or other drivers (such as platform drivers) to reject certain timing modes and request the IDE controller driver to recalculate modes. This function allows the driver entity and the IDE controller driver to negotiate the timings on a per-device basis. This function is useful in the case of drives that lie about their capabilities. An example is when the IDE device fails to accept the timing modes that are calculated by the IDE controller driver based on the response to the Identify Drive command. If the driver entity does not want to limit the ATA timing modes and leave that decision to the IDE controller driver, it can either not call this function for the given device or call this function and set the Valid flag to FALSE for all modes that are listed in EFI_ATA_COLLECTIVE_MODE. The driver entity may disqualify modes for a device in any order and any number of times. This function can be called multiple times to invalidate multiple modes of the same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI specification for more information on PIO modes. For Serial ATA (SATA) controllers, this member function can be used to disqualify a higher transfer rate mode on a given channel. For example, a platform driver may inform the IDE controller driver to not use second-generation (Gen2) speeds for a certain SATA drive. @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Channel The zero-based channel number. @param[in] Device The zero-based device number on the Channel. @param[in] BadModes The modes that the device does not support and that should be disqualified. @retval EFI_SUCCESS The modes were accepted without any errors. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). @retval EFI_INVALID_PARAMETER Device is invalid. @retval EFI_INVALID_PARAMETER IdentifyData is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_DISQUALIFY_MODE)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_COLLECTIVE_MODE *BadModes ); /** Returns the information about the optimum modes for the specified IDE device. This function is used by the driver entity to obtain the optimum ATA modes for a specific device. The IDE controller driver takes into account the following while calculating the mode: - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() for all the devices that belong to an enumeration group before calling EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group. The IDE controller driver will use controller- and possibly platform-specific algorithms to arrive at SupportedModes. The IDE controller may base its decision on user preferences and other considerations as well. This function may be called multiple times because the driver entity may renegotiate the mode with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode(). The driver entity may collect timing information for various devices in any order. The driver entity is responsible for making sure that all the dependencies are satisfied. For example, the SupportedModes information for device A that was previously returned may become stale after a call to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B. The buffer SupportedModes is allocated by the callee because the caller does not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE is defined in a way that allows for future extensibility and can be of variable length. This memory pool should be deallocated by the caller when it is no longer necessary. The IDE controller driver for a Serial ATA (SATA) controller can use this member function to force a lower speed (first-generation [Gen1] speeds on a second-generation [Gen2]-capable hardware). The IDE controller driver can also allow the driver entity to stay with the speed that has been negotiated by the physical layer. @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Channel A zero-based channel number. @param[in] Device A zero-based device number on the Channel. @param[out] SupportedModes The optimum modes for the device. @retval EFI_SUCCESS SupportedModes was returned. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). @retval EFI_INVALID_PARAMETER Device is invalid. @retval EFI_INVALID_PARAMETER SupportedModes is NULL. @retval EFI_NOT_READY Modes cannot be calculated due to a lack of data. This error may happen if EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData() were not called for at least one drive in the same enumeration group. **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_CALCULATE_MODE)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes ); /** Commands the IDE controller driver to program the IDE controller hardware so that the specified device can operate at the specified mode. This function is used by the driver entity to instruct the IDE controller driver to program the IDE controller hardware to the specified modes. This function can be called only once for a particular device. For a Serial ATA (SATA) Advanced Host Controller Interface (AHCI) controller, no controller- specific programming may be required. @param[in] This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. @param[in] Channel Zero-based channel number. @param[in] Device Zero-based device number on the Channel. @param[in] Modes The modes to set. @retval EFI_SUCCESS The command was accepted without any errors. @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). @retval EFI_INVALID_PARAMETER Device is invalid. @retval EFI_NOT_READY Modes cannot be set at this time due to lack of data. @retval EFI_DEVICE_ERROR Modes cannot be set due to hardware failure. The driver entity should not use this device. **/ typedef EFI_STATUS (EFIAPI *EFI_IDE_CONTROLLER_SET_TIMING)( IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_COLLECTIVE_MODE *Modes ); /// /// Provides the basic interfaces to abstract an IDE controller. /// struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL { /// /// Returns the information about a specific channel. /// EFI_IDE_CONTROLLER_GET_CHANNEL_INFO GetChannelInfo; /// /// The notification that the driver entity is about to enter the /// specified phase during the enumeration process. /// EFI_IDE_CONTROLLER_NOTIFY_PHASE NotifyPhase; /// /// Submits the Drive Identify data that was returned by the device. /// EFI_IDE_CONTROLLER_SUBMIT_DATA SubmitData; /// /// Submits information about modes that should be disqualified. The specified /// IDE device does not support these modes and these modes should not be /// returned by EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() /// EFI_IDE_CONTROLLER_DISQUALIFY_MODE DisqualifyMode; /// /// Calculates and returns the optimum mode for a particular IDE device. /// EFI_IDE_CONTROLLER_CALCULATE_MODE CalculateMode; /// /// Programs the IDE controller hardware to the default timing or per the modes /// that were returned by the last call to EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode(). /// EFI_IDE_CONTROLLER_SET_TIMING SetTiming; /// /// Set to TRUE if the enumeration group includes all the channels that are /// produced by this controller. Set to FALSE if an enumeration group consists of /// only one channel. /// BOOLEAN EnumAll; /// /// The number of channels that are produced by this controller. Parallel ATA /// (PATA) controllers can support up to two channels. Advanced Host Controller /// Interface (AHCI) Serial ATA (SATA) controllers can support up to 32 channels, /// each of which can have up to one device. In the presence of a multiplier, /// each channel can have fifteen devices. /// UINT8 ChannelCount; }; extern EFI_GUID gEfiIdeControllerInitProtocolGuid; #endif /** @file This file defines the EFI IPv4 (Internet Protocol version 4) Protocol interface. It is split into the following three main sections: - EFI IPv4 Service Binding Protocol - EFI IPv4 Variable (deprecated in UEFI 2.4B) - EFI IPv4 Protocol. The EFI IPv4 Protocol provides basic network IPv4 packet I/O services, which includes support foR a subset of the Internet Control Message Protocol (ICMP) and may include support for the Internet Group Management Protocol (IGMP). Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0. **/ #ifndef __EFI_IP4_PROTOCOL_H__ #define __EFI_IP4_PROTOCOL_H__ #include #define EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xc51711e7, 0xb4bf, 0x404a, {0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4 } \ } #define EFI_IP4_PROTOCOL_GUID \ { \ 0x41d94cd2, 0x35b6, 0x455a, {0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \ } typedef struct _EFI_IP4_PROTOCOL EFI_IP4_PROTOCOL; /// /// EFI_IP4_ADDRESS_PAIR is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE InstanceHandle; EFI_IPv4_ADDRESS Ip4Address; EFI_IPv4_ADDRESS SubnetMask; } EFI_IP4_ADDRESS_PAIR; /// /// EFI_IP4_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE DriverHandle; UINT32 AddressCount; EFI_IP4_ADDRESS_PAIR AddressPairs[1]; } EFI_IP4_VARIABLE_DATA; typedef struct { /// /// The default IPv4 protocol packets to send and receive. Ignored /// when AcceptPromiscuous is TRUE. /// UINT8 DefaultProtocol; /// /// Set to TRUE to receive all IPv4 packets that get through the receive filters. /// Set to FALSE to receive only the DefaultProtocol IPv4 /// packets that get through the receive filters. /// BOOLEAN AcceptAnyProtocol; /// /// Set to TRUE to receive ICMP error report packets. Ignored when /// AcceptPromiscuous or AcceptAnyProtocol is TRUE. /// BOOLEAN AcceptIcmpErrors; /// /// Set to TRUE to receive broadcast IPv4 packets. Ignored when /// AcceptPromiscuous is TRUE. /// Set to FALSE to stop receiving broadcast IPv4 packets. /// BOOLEAN AcceptBroadcast; /// /// Set to TRUE to receive all IPv4 packets that are sent to any /// hardware address or any protocol address. /// Set to FALSE to stop receiving all promiscuous IPv4 packets /// BOOLEAN AcceptPromiscuous; /// /// Set to TRUE to use the default IPv4 address and default routing table. /// BOOLEAN UseDefaultAddress; /// /// The station IPv4 address that will be assigned to this EFI IPv4Protocol instance. /// EFI_IPv4_ADDRESS StationAddress; /// /// The subnet address mask that is associated with the station address. /// EFI_IPv4_ADDRESS SubnetMask; /// /// TypeOfService field in transmitted IPv4 packets. /// UINT8 TypeOfService; /// /// TimeToLive field in transmitted IPv4 packets. /// UINT8 TimeToLive; /// /// State of the DoNotFragment bit in transmitted IPv4 packets. /// BOOLEAN DoNotFragment; /// /// Set to TRUE to send and receive unformatted packets. The other /// IPv4 receive filters are still applied. Fragmentation is disabled for RawData mode. /// BOOLEAN RawData; /// /// The timer timeout value (number of microseconds) for the /// receive timeout event to be associated with each assembled /// packet. Zero means do not drop assembled packets. /// UINT32 ReceiveTimeout; /// /// The timer timeout value (number of microseconds) for the /// transmit timeout event to be associated with each outgoing /// packet. Zero means do not drop outgoing packets. /// UINT32 TransmitTimeout; } EFI_IP4_CONFIG_DATA; typedef struct { EFI_IPv4_ADDRESS SubnetAddress; EFI_IPv4_ADDRESS SubnetMask; EFI_IPv4_ADDRESS GatewayAddress; } EFI_IP4_ROUTE_TABLE; typedef struct { UINT8 Type; UINT8 Code; } EFI_IP4_ICMP_TYPE; typedef struct { /// /// Set to TRUE after this EFI IPv4 Protocol instance has been successfully configured. /// BOOLEAN IsStarted; /// /// The maximum packet size, in bytes, of the packet which the upper layer driver could feed. /// UINT32 MaxPacketSize; /// /// Current configuration settings. /// EFI_IP4_CONFIG_DATA ConfigData; /// /// Set to TRUE when the EFI IPv4 Protocol instance has a station address and subnet mask. /// BOOLEAN IsConfigured; /// /// Number of joined multicast groups. /// UINT32 GroupCount; /// /// List of joined multicast group addresses. /// EFI_IPv4_ADDRESS *GroupTable; /// /// Number of entries in the routing table. /// UINT32 RouteCount; /// /// Routing table entries. /// EFI_IP4_ROUTE_TABLE *RouteTable; /// /// Number of entries in the supported ICMP types list. /// UINT32 IcmpTypeCount; /// /// Array of ICMP types and codes that are supported by this EFI IPv4 Protocol driver /// EFI_IP4_ICMP_TYPE *IcmpTypeList; } EFI_IP4_MODE_DATA; #pragma pack(1) typedef struct { UINT8 HeaderLength : 4; UINT8 Version : 4; UINT8 TypeOfService; UINT16 TotalLength; UINT16 Identification; UINT16 Fragmentation; UINT8 TimeToLive; UINT8 Protocol; UINT16 Checksum; EFI_IPv4_ADDRESS SourceAddress; EFI_IPv4_ADDRESS DestinationAddress; } EFI_IP4_HEADER; #pragma pack() typedef struct { UINT32 FragmentLength; VOID *FragmentBuffer; } EFI_IP4_FRAGMENT_DATA; typedef struct { EFI_TIME TimeStamp; EFI_EVENT RecycleSignal; UINT32 HeaderLength; EFI_IP4_HEADER *Header; UINT32 OptionsLength; VOID *Options; UINT32 DataLength; UINT32 FragmentCount; EFI_IP4_FRAGMENT_DATA FragmentTable[1]; } EFI_IP4_RECEIVE_DATA; typedef struct { EFI_IPv4_ADDRESS SourceAddress; EFI_IPv4_ADDRESS GatewayAddress; UINT8 Protocol; UINT8 TypeOfService; UINT8 TimeToLive; BOOLEAN DoNotFragment; } EFI_IP4_OVERRIDE_DATA; typedef struct { EFI_IPv4_ADDRESS DestinationAddress; EFI_IP4_OVERRIDE_DATA *OverrideData; // OPTIONAL UINT32 OptionsLength; // OPTIONAL VOID *OptionsBuffer; // OPTIONAL UINT32 TotalDataLength; UINT32 FragmentCount; EFI_IP4_FRAGMENT_DATA FragmentTable[1]; } EFI_IP4_TRANSMIT_DATA; typedef struct { /// /// This Event will be signaled after the Status field is updated /// by the EFI IPv4 Protocol driver. The type of Event must be /// EFI_NOTIFY_SIGNAL. The Task Priority Level (TPL) of /// Event must be lower than or equal to TPL_CALLBACK. /// EFI_EVENT Event; /// /// The status that is returned to the caller at the end of the operation /// to indicate whether this operation completed successfully. /// EFI_STATUS Status; union { /// /// When this token is used for receiving, RxData is a pointer to the EFI_IP4_RECEIVE_DATA. /// EFI_IP4_RECEIVE_DATA *RxData; /// /// When this token is used for transmitting, TxData is a pointer to the EFI_IP4_TRANSMIT_DATA. /// EFI_IP4_TRANSMIT_DATA *TxData; } Packet; } EFI_IP4_COMPLETION_TOKEN; /** Gets the current operational settings for this instance of the EFI IPv4 Protocol driver. The GetModeData() function returns the current operational mode data for this driver instance. The data fields in EFI_IP4_MODE_DATA are read only. This function is used optionally to retrieve the operational mode data of underlying networks or drivers. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param Ip4ModeData The pointer to the EFI IPv4 Protocol mode data structure. @param MnpConfigData The pointer to the managed network configuration data structure. @param SnpModeData The pointer to the simple network mode data structure. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_GET_MODE_DATA)( IN CONST EFI_IP4_PROTOCOL *This, OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Assigns an IPv4 address and subnet mask to this EFI IPv4 Protocol driver instance. The Configure() function is used to set, change, or reset the operational parameters and filter settings for this EFI IPv4 Protocol instance. Until these parameters have been set, no network traffic can be sent or received by this instance. Once the parameters have been reset (by calling this function with IpConfigData set to NULL), no more traffic can be sent or received until these parameters have been set again. Each EFI IPv4 Protocol instance can be started and stopped independently of each other by enabling or disabling their receive filter settings with the Configure() function. When IpConfigData.UseDefaultAddress is set to FALSE, the new station address will be appended as an alias address into the addresses list in the EFI IPv4 Protocol driver. While set to TRUE, Configure() will trigger the EFI_IP4_CONFIG_PROTOCOL to retrieve the default IPv4 address if it is not available yet. Clients could frequently call GetModeData() to check the status to ensure that the default IPv4 address is ready. If operational parameters are reset or changed, any pending transmit and receive requests will be cancelled. Their completion token status will be set to EFI_ABORTED and their events will be signaled. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param IpConfigData The pointer to the EFI IPv4 Protocol configuration data structure. @retval EFI_SUCCESS The driver instance was successfully opened. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. IpConfigData.StationAddress is not a unicast IPv4 address. IpConfigData.SubnetMask is not a valid IPv4 subnet @retval EFI_UNSUPPORTED One or more of the following conditions is TRUE: A configuration protocol (DHCP, BOOTP, RARP, etc.) could not be located when clients choose to use the default IPv4 address. This EFI IPv4 Protocol implementation does not support this requested filter or timeout setting. @retval EFI_OUT_OF_RESOURCES The EFI IPv4 Protocol driver instance data could not be allocated. @retval EFI_ALREADY_STARTED The interface is already open and must be stopped before the IPv4 address or subnet mask can be changed. The interface must also be stopped when switching to/from raw packet mode. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv4 Protocol driver instance is not opened. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIGURE)( IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL ); /** Joins and leaves multicast groups. The Groups() function is used to join and leave multicast group sessions. Joining a group will enable reception of matching multicast packets. Leaving a group will disable the multicast packet reception. If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param JoinFlag Set to TRUE to join the multicast group session and FALSE to leave. @param GroupAddress The pointer to the IPv4 multicast address. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: - This is NULL. - JoinFlag is TRUE and GroupAddress is NULL. - GroupAddress is not NULL and *GroupAddress is not a multicast IPv4 address. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_OUT_OF_RESOURCES System resources could not be allocated. @retval EFI_UNSUPPORTED This EFI IPv4 Protocol implementation does not support multicast groups. @retval EFI_ALREADY_STARTED The group address is already in the group table (when JoinFlag is TRUE). @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_GROUPS)( IN EFI_IP4_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL ); /** Adds and deletes routing table entries. The Routes() function adds a route to or deletes a route from the routing table. Routes are determined by comparing the SubnetAddress with the destination IPv4 address arithmetically AND-ed with the SubnetMask. The gateway address must be on the same subnet as the configured station address. The default route is added with SubnetAddress and SubnetMask both set to 0.0.0.0. The default route matches all destination IPv4 addresses that do not match any other routes. A GatewayAddress that is zero is a nonroute. Packets are sent to the destination IP address if it can be found in the ARP cache or on the local subnet. One automatic nonroute entry will be inserted into the routing table for outgoing packets that are addressed to a local subnet (gateway address of 0.0.0.0). Each EFI IPv4 Protocol instance has its own independent routing table. Those EFI IPv4 Protocol instances that use the default IPv4 address will also have copies of the routing table that was provided by the EFI_IP4_CONFIG_PROTOCOL, and these copies will be updated whenever the EIF IPv4 Protocol driver reconfigures its instances. As a result, client modification to the routing table will be lost. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param DeleteRoute Set to TRUE to delete this route from the routing table. Set to FALSE to add this route to the routing table. SubnetAddress and SubnetMask are used as the key to each route entry. @param SubnetAddress The address of the subnet that needs to be routed. @param SubnetMask The subnet mask of SubnetAddress. @param GatewayAddress The unicast gateway IPv4 address for this route. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The driver instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - SubnetAddress is NULL. - SubnetMask is NULL. - GatewayAddress is NULL. - *SubnetAddress is not a valid subnet address. - *SubnetMask is not a valid subnet mask. - *GatewayAddress is not a valid unicast IPv4 address. @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table. @retval EFI_NOT_FOUND This route is not in the routing table (when DeleteRoute is TRUE). @retval EFI_ACCESS_DENIED The route is already defined in the routing table (when DeleteRoute is FALSE). **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_ROUTES)( IN EFI_IP4_PROTOCOL *This, IN BOOLEAN DeleteRoute, IN EFI_IPv4_ADDRESS *SubnetAddress, IN EFI_IPv4_ADDRESS *SubnetMask, IN EFI_IPv4_ADDRESS *GatewayAddress ); /** Places outgoing data packets into the transmit queue. The Transmit() function places a sending request in the transmit queue of this EFI IPv4 Protocol instance. Whenever the packet in the token is sent out or some errors occur, the event in the token will be signaled and the status is updated. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param Token The pointer to the transmit token. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more pameters are invalid. @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event was already in the transmit queue. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_NOT_FOUND Not route is found to destination address. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. @retval EFI_BUFFER_TOO_SMALL Token.Packet.TxData.TotalDataLength is too short to transmit. @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length + total data length is greater than MTU (or greater than the maximum packet size if Token.Packet.TxData.OverrideData. DoNotFragment is TRUE.) **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_TRANSMIT)( IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token ); /** Places a receiving request into the receiving queue. The Receive() function places a completion token into the receive packet queue. This function is always asynchronous. The Token.Event field in the completion token must be filled in by the caller and cannot be NULL. When the receive operation completes, the EFI IPv4 Protocol driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event is signaled. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param Token The pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI IPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv4 Protocol instance has been reset to startup defaults. @retval EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already in the receive queue. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. @retval EFI_ICMP_ERROR An ICMP error packet was received. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_RECEIVE)( IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token ); /** Abort an asynchronous transmit or receive request. The Cancel() function is used to abort a pending transmit or receive request. If the token is in the transmit or receive request queues, after calling this function, Token->Status will be set to EFI_ABORTED and then Token->Event will be signaled. If the token is not in one of the queues, which usually means the asynchronous operation has completed, this function will not signal the token and EFI_NOT_FOUND is returned. @param This The pointer to the EFI_IP4_PROTOCOL instance. @param Token The pointer to a token that has been issued by EFI_IP4_PROTOCOL.Transmit() or EFI_IP4_PROTOCOL.Receive(). If NULL, all pending tokens are aborted. Type EFI_IP4_COMPLETION_TOKEN is defined in EFI_IP4_PROTOCOL.Transmit(). @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token->Event was signaled. When Token is NULL, all pending requests were aborted and their events were signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was not found in the transmit or receive queue. It has either completed or was not issued by Transmit() and Receive(). **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CANCEL)( IN EFI_IP4_PROTOCOL *This, IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL ); /** Polls for incoming data packets and processes outgoing data packets. The Poll() function polls for incoming data packets and processes outgoing data packets. Network drivers and applications can call the EFI_IP4_PROTOCOL.Poll() function to increase the rate that data packets are moved between the communications device and the transmit and receive queues. In some systems the periodic timer event may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the EFI_IP4_PROTOCOL.Poll() function more often. @param This The pointer to the EFI_IP4_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_NOT_STARTED This EFI IPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY No incoming or outgoing data is processed. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_POLL)( IN EFI_IP4_PROTOCOL *This ); /// /// The EFI IPv4 Protocol implements a simple packet-oriented interface that can be /// used by drivers, daemons, and applications to transmit and receive network packets. /// struct _EFI_IP4_PROTOCOL { EFI_IP4_GET_MODE_DATA GetModeData; EFI_IP4_CONFIGURE Configure; EFI_IP4_GROUPS Groups; EFI_IP4_ROUTES Routes; EFI_IP4_TRANSMIT Transmit; EFI_IP4_RECEIVE Receive; EFI_IP4_CANCEL Cancel; EFI_IP4_POLL Poll; }; extern EFI_GUID gEfiIp4ServiceBindingProtocolGuid; extern EFI_GUID gEfiIp4ProtocolGuid; #endif /** @file This file provides a definition of the EFI IPv4 Configuration Protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0. **/ #ifndef __EFI_IP4CONFIG_PROTOCOL_H__ #define __EFI_IP4CONFIG_PROTOCOL_H__ #include #define EFI_IP4_CONFIG_PROTOCOL_GUID \ { \ 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e } \ } typedef struct _EFI_IP4_CONFIG_PROTOCOL EFI_IP4_CONFIG_PROTOCOL; #define IP4_CONFIG_VARIABLE_ATTRIBUTES \ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) /// /// EFI_IP4_IPCONFIG_DATA contains the minimum IPv4 configuration data /// that is needed to start basic network communication. The StationAddress /// and SubnetMask must be a valid unicast IP address and subnet mask. /// If RouteTableSize is not zero, then RouteTable contains a properly /// formatted routing table for the StationAddress/SubnetMask, with the /// last entry in the table being the default route. /// typedef struct { /// /// Default station IP address, stored in network byte order. /// EFI_IPv4_ADDRESS StationAddress; /// /// Default subnet mask, stored in network byte order. /// EFI_IPv4_ADDRESS SubnetMask; /// /// Number of entries in the following RouteTable. May be zero. /// UINT32 RouteTableSize; /// /// Default routing table data (stored in network byte order). /// Ignored if RouteTableSize is zero. /// EFI_IP4_ROUTE_TABLE *RouteTable; } EFI_IP4_IPCONFIG_DATA; /** Starts running the configuration policy for the EFI IPv4 Protocol driver. The Start() function is called to determine and to begin the platform configuration policy by the EFI IPv4 Protocol driver. This determination may be as simple as returning EFI_UNSUPPORTED if there is no EFI IPv4 Protocol driver configuration policy. It may be as involved as loading some defaults from nonvolatile storage, downloading dynamic data from a DHCP server, and checking permissions with a site policy server. Starting the configuration policy is just the beginning. It may finish almost instantly or it may take several minutes before it fails to retrieve configuration information from one or more servers. Once the policy is started, drivers should use the DoneEvent parameter to determine when the configuration policy has completed. EFI_IP4_CONFIG_PROTOCOL.GetData() must then be called to determine if the configuration succeeded or failed. Until the configuration completes successfully, EFI IPv4 Protocol driver instances that are attempting to use default configurations must return EFI_NO_MAPPING. Once the configuration is complete, the EFI IPv4 Configuration Protocol driver signals DoneEvent. The configuration may need to be updated in the future. Note that in this case the EFI IPv4 Configuration Protocol driver must signal ReconfigEvent, and all EFI IPv4 Protocol driver instances that are using default configurations must return EFI_NO_MAPPING until the configuration policy has been rerun. @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. @param DoneEvent Event that will be signaled when the EFI IPv4 Protocol driver configuration policy completes execution. This event must be of type EVT_NOTIFY_SIGNAL. @param ReconfigEvent Event that will be signaled when the EFI IPv4 Protocol driver configuration needs to be updated. This event must be of type EVT_NOTIFY_SIGNAL. @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol driver is now running. @retval EFI_INVALID_PARAMETER One or more of the following parameters is NULL: This DoneEvent ReconfigEvent @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ALREADY_STARTED The configuration policy for the EFI IPv4 Protocol driver was already started. @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred. @retval EFI_UNSUPPORTED This interface does not support the EFI IPv4 Protocol driver configuration. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG_START)( IN EFI_IP4_CONFIG_PROTOCOL *This, IN EFI_EVENT DoneEvent, IN EFI_EVENT ReconfigEvent ); /** Stops running the configuration policy for the EFI IPv4 Protocol driver. The Stop() function stops the configuration policy for the EFI IPv4 Protocol driver. All configuration data will be lost after calling Stop(). @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol driver has been stopped. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol driver was not started. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG_STOP)( IN EFI_IP4_CONFIG_PROTOCOL *This ); /** Returns the default configuration data (if any) for the EFI IPv4 Protocol driver. The GetData() function returns the current configuration data for the EFI IPv4 Protocol driver after the configuration policy has completed. @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. @param IpConfigDataSize On input, the size of the IpConfigData buffer. On output, the count of bytes that were written into the IpConfigData buffer. @param IpConfigData The pointer to the EFI IPv4 Configuration Protocol driver configuration data structure. Type EFI_IP4_IPCONFIG_DATA is defined in "Related Definitions" below. @retval EFI_SUCCESS The EFI IPv4 Protocol driver configuration has been returned. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol driver is not running. @retval EFI_NOT_READY EFI IPv4 Protocol driver configuration is still running. @retval EFI_ABORTED EFI IPv4 Protocol driver configuration could not complete. @retval EFI_BUFFER_TOO_SMALL *IpConfigDataSize is smaller than the configuration data buffer or IpConfigData is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG_GET_DATA)( IN EFI_IP4_CONFIG_PROTOCOL *This, IN OUT UINTN *IpConfigDataSize, OUT EFI_IP4_IPCONFIG_DATA *IpConfigData OPTIONAL ); /// /// The EFI_IP4_CONFIG_PROTOCOL driver performs platform-dependent and policy-dependent /// configurations for the EFI IPv4 Protocol driver. /// struct _EFI_IP4_CONFIG_PROTOCOL { EFI_IP4_CONFIG_START Start; EFI_IP4_CONFIG_STOP Stop; EFI_IP4_CONFIG_GET_DATA GetData; }; extern EFI_GUID gEfiIp4ConfigProtocolGuid; #endif /** @file This file provides a definition of the EFI IPv4 Configuration II Protocol. Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.5 **/ #ifndef __EFI_IP4CONFIG2_PROTOCOL_H__ #define __EFI_IP4CONFIG2_PROTOCOL_H__ #include #define EFI_IP4_CONFIG2_PROTOCOL_GUID \ { \ 0x5b446ed1, 0xe30b, 0x4faa, {0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ } typedef struct _EFI_IP4_CONFIG2_PROTOCOL EFI_IP4_CONFIG2_PROTOCOL; /// /// EFI_IP4_CONFIG2_DATA_TYPE /// typedef enum { /// /// The interface information of the communication device this EFI /// IPv4 Configuration II Protocol instance manages. This type of /// data is read only. The corresponding Data is of type /// EFI_IP4_CONFIG2_INTERFACE_INFO. /// Ip4Config2DataTypeInterfaceInfo, /// /// The general configuration policy for the EFI IPv4 network stack /// running on the communication device this EFI IPv4 /// Configuration II Protocol instance manages. The policy will /// affect other configuration settings. The corresponding Data is of /// type EFI_IP4_CONFIG2_POLICY. /// Ip4Config2DataTypePolicy, /// /// The station addresses set manually for the EFI IPv4 network /// stack. It is only configurable when the policy is /// Ip4Config2PolicyStatic. The corresponding Data is of /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS. When DataSize /// is 0 and Data is NULL, the existing configuration is cleared /// from the EFI IPv4 Configuration II Protocol instance. /// Ip4Config2DataTypeManualAddress, /// /// The gateway addresses set manually for the EFI IPv4 network /// stack running on the communication device this EFI IPv4 /// Configuration II Protocol manages. It is not configurable when /// the policy is Ip4Config2PolicyDhcp. The gateway /// addresses must be unicast IPv4 addresses. The corresponding /// Data is a pointer to an array of EFI_IPv4_ADDRESS instances. /// When DataSize is 0 and Data is NULL, the existing configuration /// is cleared from the EFI IPv4 Configuration II Protocol instance. /// Ip4Config2DataTypeGateway, /// /// The DNS server list for the EFI IPv4 network stack running on /// the communication device this EFI IPv4 Configuration II /// Protocol manages. It is not configurable when the policy is /// Ip4Config2PolicyDhcp. The DNS server addresses must be /// unicast IPv4 addresses. The corresponding Data is a pointer to /// an array of EFI_IPv4_ADDRESS instances. When DataSize /// is 0 and Data is NULL, the existing configuration is cleared /// from the EFI IPv4 Configuration II Protocol instance. /// Ip4Config2DataTypeDnsServer, Ip4Config2DataTypeMaximum } EFI_IP4_CONFIG2_DATA_TYPE; /// /// EFI_IP4_CONFIG2_INTERFACE_INFO related definitions /// #define EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE 32 /// /// EFI_IP4_CONFIG2_INTERFACE_INFO /// typedef struct { /// /// The name of the interface. It is a NULL-terminated Unicode string. /// CHAR16 Name[EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE]; /// /// The interface type of the network interface. See RFC 1700, /// section "Number Hardware Type". /// UINT8 IfType; /// /// The size, in bytes, of the network interface's hardware address. /// UINT32 HwAddressSize; /// /// The hardware address for the network interface. /// EFI_MAC_ADDRESS HwAddress; /// /// The station IPv4 address of this EFI IPv4 network stack. /// EFI_IPv4_ADDRESS StationAddress; /// /// The subnet address mask that is associated with the station address. /// EFI_IPv4_ADDRESS SubnetMask; /// /// Size of the following RouteTable, in bytes. May be zero. /// UINT32 RouteTableSize; /// /// The route table of the IPv4 network stack runs on this interface. /// Set to NULL if RouteTableSize is zero. Type EFI_IP4_ROUTE_TABLE is defined in /// EFI_IP4_PROTOCOL.GetModeData(). /// EFI_IP4_ROUTE_TABLE *RouteTable OPTIONAL; } EFI_IP4_CONFIG2_INTERFACE_INFO; /// /// EFI_IP4_CONFIG2_POLICY /// typedef enum { /// /// Under this policy, the Ip4Config2DataTypeManualAddress, /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration /// data are required to be set manually. The EFI IPv4 Protocol will get all /// required configuration such as IPv4 address, subnet mask and /// gateway settings from the EFI IPv4 Configuration II protocol. /// Ip4Config2PolicyStatic, /// /// Under this policy, the Ip4Config2DataTypeManualAddress, /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration data are /// not allowed to set via SetData(). All of these configurations are retrieved from DHCP /// server or other auto-configuration mechanism. /// Ip4Config2PolicyDhcp, Ip4Config2PolicyMax } EFI_IP4_CONFIG2_POLICY; /// /// EFI_IP4_CONFIG2_MANUAL_ADDRESS /// typedef struct { /// /// The IPv4 unicast address. /// EFI_IPv4_ADDRESS Address; /// /// The subnet mask. /// EFI_IPv4_ADDRESS SubnetMask; } EFI_IP4_CONFIG2_MANUAL_ADDRESS; /** Set the configuration for the EFI IPv4 network stack running on the communication device this EFI IPv4 Configuration II Protocol instance manages. This function is used to set the configuration data of type DataType for the EFI IPv4 network stack running on the communication device this EFI IPv4 Configuration II Protocol instance manages. The successfully configured data is valid after system reset or power-off. The DataSize is used to calculate the count of structure instances in the Data for some DataType that multiple structure instances are allowed. This function is always non-blocking. When setting some typeof configuration data, an asynchronous process is invoked to check the correctness of the data, such as doing address conflict detection on the manually set local IPv4 address. EFI_NOT_READY is returned immediately to indicate that such an asynchronous process is invoked and the process is not finished yet. The caller willing to get the result of the asynchronous process is required to call RegisterDataNotify() to register an event on the specified configuration data. Once the event is signaled, the caller can call GetData()to get back the configuration data in order to know the result. For other types of configuration data that do not require an asynchronous configuration process, the result of the operation is immediately returned. @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. @param[in] DataType The type of data to set. @param[in] DataSize Size of the buffer pointed to by Data in bytes. @param[in] Data The data buffer to set. The type ofthe data buffer is associated with the DataType. @retval EFI_SUCCESS The specified configuration data for the EFI IPv4 network stack is set successfully. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: This is NULL. One or more fields in Data and DataSize do not match the requirement of the data type indicated by DataType. @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified configuration data can not be set under the current policy. @retval EFI_ACCESS_DENIED Another set operation on the specified configuration data is already in process. @retval EFI_NOT_READY An asynchronous process is invoked to set the specified configuration data and the process is not finished yet. @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type indicated by DataType. @retval EFI_UNSUPPORTED This DataType is not supported. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG2_SET_DATA)( IN EFI_IP4_CONFIG2_PROTOCOL *This, IN EFI_IP4_CONFIG2_DATA_TYPE DataType, IN UINTN DataSize, IN VOID *Data ); /** Get the configuration data for the EFI IPv4 network stack running on the communication device this EFI IPv4 Configuration II Protocol instance manages. This function returns the configuration data of type DataType for the EFI IPv4 network stack running on the communication device this EFI IPv4 Configuration II Protocol instance manages. The caller is responsible for allocating the buffer usedto return the specified configuration data and the required size will be returned to the caller if the size of the buffer is too small. EFI_NOT_READY is returned if the specified configuration data is not ready due to an already in progress asynchronous configuration process. The caller can call RegisterDataNotify() to register an event on the specified configuration data. Once the asynchronous configuration process is finished, the event will be signaled and a subsequent GetData() call will return the specified configuration data. @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. @param[in] DataType The type of data to get. @param[out] DataSize On input, in bytes, the size of Data. On output, in bytes, the size of buffer required to store the specified configuration data. @param[in] Data The data buffer in which the configuration data is returned. The type of the data buffer is associated with the DataType. Ignored if DataSize is 0. @retval EFI_SUCCESS The specified configuration data is got successfully. @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: This is NULL. DataSize is NULL. Data is NULL if *DataSizeis not zero. @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data and the required size is returned in DataSize. @retval EFI_NOT_READY The specified configuration data is not ready due to an already in progress asynchronous configuration process. @retval EFI_NOT_FOUND The specified configuration data is not found. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG2_GET_DATA)( IN EFI_IP4_CONFIG2_PROTOCOL *This, IN EFI_IP4_CONFIG2_DATA_TYPE DataType, IN OUT UINTN *DataSize, IN VOID *Data OPTIONAL ); /** Register an event that is to be signaled whenever a configuration process on the specified configuration data is done. This function registers an event that is to be signaled whenever a configuration process on the specified configuration data is done. An event can be registered for different DataType simultaneously and the caller is responsible for determining which type of configuration data causes the signaling of the event in such case. @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. @param[in] DataType The type of data to unregister the event for. @param[in] Event The event to register. @retval EFI_SUCCESS The notification event for the specified configuration data is registered. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not supported. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The Event is already registered for the DataType. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG2_REGISTER_NOTIFY)( IN EFI_IP4_CONFIG2_PROTOCOL *This, IN EFI_IP4_CONFIG2_DATA_TYPE DataType, IN EFI_EVENT Event ); /** Remove a previously registered event for the specified configuration data. This function removes a previously registeredevent for the specified configuration data. @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. @param[in] DataType The type of data to remove the previously registered event for. @param[in] Event The event to unregister. @retval EFI_SUCCESS The event registered for the specified configuration data is removed. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_NOT_FOUND The Eventhas not been registered for the specified DataType. **/ typedef EFI_STATUS (EFIAPI *EFI_IP4_CONFIG2_UNREGISTER_NOTIFY)( IN EFI_IP4_CONFIG2_PROTOCOL *This, IN EFI_IP4_CONFIG2_DATA_TYPE DataType, IN EFI_EVENT Event ); /// /// The EFI_IP4_CONFIG2_PROTOCOL is designed to be the central repository for the common /// configurations and the administrator configurable settings for the EFI IPv4 network stack. /// An EFI IPv4 Configuration II Protocol instance will be installed on each communication device that /// the EFI IPv4 network stack runs on. /// struct _EFI_IP4_CONFIG2_PROTOCOL { EFI_IP4_CONFIG2_SET_DATA SetData; EFI_IP4_CONFIG2_GET_DATA GetData; EFI_IP4_CONFIG2_REGISTER_NOTIFY RegisterDataNotify; EFI_IP4_CONFIG2_UNREGISTER_NOTIFY UnregisterDataNotify; }; extern EFI_GUID gEfiIp4Config2ProtocolGuid; #endif /** @file This file defines the EFI IPv6 (Internet Protocol version 6) Protocol interface. It is split into the following three main sections: - EFI IPv6 Service Binding Protocol - EFI IPv6 Variable (deprecated in UEFI 2.4B) - EFI IPv6 Protocol The EFI IPv6 Protocol provides basic network IPv6 packet I/O services, which includes support for Neighbor Discovery Protocol (ND), Multicast Listener Discovery Protocol (MLD), and a subset of the Internet Control Message Protocol (ICMPv6). Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_IP6_PROTOCOL_H__ #define __EFI_IP6_PROTOCOL_H__ #include #define EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xec835dd3, 0xfe0f, 0x617b, {0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 } \ } #define EFI_IP6_PROTOCOL_GUID \ { \ 0x2c8759d5, 0x5c2d, 0x66ef, {0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 } \ } typedef struct _EFI_IP6_PROTOCOL EFI_IP6_PROTOCOL; /// /// EFI_IP6_ADDRESS_PAIR is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { /// /// The EFI IPv6 Protocol instance handle that is using this address/prefix pair. /// EFI_HANDLE InstanceHandle; /// /// IPv6 address in network byte order. /// EFI_IPv6_ADDRESS Ip6Address; /// /// The length of the prefix associated with the Ip6Address. /// UINT8 PrefixLength; } EFI_IP6_ADDRESS_PAIR; /// /// EFI_IP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { /// /// The handle of the driver that creates this entry. /// EFI_HANDLE DriverHandle; /// /// The number of IPv6 address pairs that follow this data structure. /// UINT32 AddressCount; /// /// List of IPv6 address pairs that are currently in use. /// EFI_IP6_ADDRESS_PAIR AddressPairs[1]; } EFI_IP6_VARIABLE_DATA; /// /// ICMPv6 type definitions for error messages /// ///@{ #define ICMP_V6_DEST_UNREACHABLE 0x1 #define ICMP_V6_PACKET_TOO_BIG 0x2 #define ICMP_V6_TIME_EXCEEDED 0x3 #define ICMP_V6_PARAMETER_PROBLEM 0x4 ///@} /// /// ICMPv6 type definition for informational messages /// ///@{ #define ICMP_V6_ECHO_REQUEST 0x80 #define ICMP_V6_ECHO_REPLY 0x81 #define ICMP_V6_LISTENER_QUERY 0x82 #define ICMP_V6_LISTENER_REPORT 0x83 #define ICMP_V6_LISTENER_DONE 0x84 #define ICMP_V6_ROUTER_SOLICIT 0x85 #define ICMP_V6_ROUTER_ADVERTISE 0x86 #define ICMP_V6_NEIGHBOR_SOLICIT 0x87 #define ICMP_V6_NEIGHBOR_ADVERTISE 0x88 #define ICMP_V6_REDIRECT 0x89 #define ICMP_V6_LISTENER_REPORT_2 0x8F ///@} /// /// ICMPv6 code definitions for ICMP_V6_DEST_UNREACHABLE /// ///@{ #define ICMP_V6_NO_ROUTE_TO_DEST 0x0 #define ICMP_V6_COMM_PROHIBITED 0x1 #define ICMP_V6_BEYOND_SCOPE 0x2 #define ICMP_V6_ADDR_UNREACHABLE 0x3 #define ICMP_V6_PORT_UNREACHABLE 0x4 #define ICMP_V6_SOURCE_ADDR_FAILED 0x5 #define ICMP_V6_ROUTE_REJECTED 0x6 ///@} /// /// ICMPv6 code definitions for ICMP_V6_TIME_EXCEEDED /// ///@{ #define ICMP_V6_TIMEOUT_HOP_LIMIT 0x0 #define ICMP_V6_TIMEOUT_REASSEMBLE 0x1 ///@} /// /// ICMPv6 code definitions for ICMP_V6_PARAMETER_PROBLEM /// ///@{ #define ICMP_V6_ERRONEOUS_HEADER 0x0 #define ICMP_V6_UNRECOGNIZE_NEXT_HDR 0x1 #define ICMP_V6_UNRECOGNIZE_OPTION 0x2 ///@} /// /// EFI_IP6_CONFIG_DATA /// is used to report and change IPv6 session parameters. /// typedef struct { /// /// For the IPv6 packet to send and receive, this is the default value /// of the 'Next Header' field in the last IPv6 extension header or in /// the IPv6 header if there are no extension headers. Ignored when /// AcceptPromiscuous is TRUE. /// UINT8 DefaultProtocol; /// /// Set to TRUE to receive all IPv6 packets that get through the /// receive filters. /// Set to FALSE to receive only the DefaultProtocol IPv6 /// packets that get through the receive filters. Ignored when /// AcceptPromiscuous is TRUE. /// BOOLEAN AcceptAnyProtocol; /// /// Set to TRUE to receive ICMP error report packets. Ignored when /// AcceptPromiscuous or AcceptAnyProtocol is TRUE. /// BOOLEAN AcceptIcmpErrors; /// /// Set to TRUE to receive all IPv6 packets that are sent to any /// hardware address or any protocol address. Set to FALSE to stop /// receiving all promiscuous IPv6 packets. /// BOOLEAN AcceptPromiscuous; /// /// The destination address of the packets that will be transmitted. /// Ignored if it is unspecified. /// EFI_IPv6_ADDRESS DestinationAddress; /// /// The station IPv6 address that will be assigned to this EFI IPv6 /// Protocol instance. This field can be set and changed only when /// the EFI IPv6 driver is transitioning from the stopped to the started /// states. If the StationAddress is specified, the EFI IPv6 Protocol /// driver will deliver only incoming IPv6 packets whose destination /// matches this IPv6 address exactly. The StationAddress is required /// to be one of currently configured IPv6 addresses. An address /// containing all zeroes is also accepted as a special case. Under this /// situation, the IPv6 driver is responsible for binding a source /// address to this EFI IPv6 protocol instance according to the source /// address selection algorithm. Only incoming packets destined to /// the selected address will be delivered to the user. And the /// selected station address can be retrieved through later /// GetModeData() call. If no address is available for selecting, /// EFI_NO_MAPPING will be returned, and the station address will /// only be successfully bound to this EFI IPv6 protocol instance /// after IP6ModeData.IsConfigured changed to TRUE. /// EFI_IPv6_ADDRESS StationAddress; /// /// TrafficClass field in transmitted IPv6 packets. Default value /// is zero. /// UINT8 TrafficClass; /// /// HopLimit field in transmitted IPv6 packets. /// UINT8 HopLimit; /// /// FlowLabel field in transmitted IPv6 packets. Default value is /// zero. /// UINT32 FlowLabel; /// /// The timer timeout value (number of microseconds) for the /// receive timeout event to be associated with each assembled /// packet. Zero means do not drop assembled packets. /// UINT32 ReceiveTimeout; /// /// The timer timeout value (number of microseconds) for the /// transmit timeout event to be associated with each outgoing /// packet. Zero means do not drop outgoing packets. /// UINT32 TransmitTimeout; } EFI_IP6_CONFIG_DATA; /// /// EFI_IP6_ADDRESS_INFO /// typedef struct { EFI_IPv6_ADDRESS Address; ///< The IPv6 address. UINT8 PrefixLength; ///< The length of the prefix associated with the Address. } EFI_IP6_ADDRESS_INFO; /// /// EFI_IP6_ROUTE_TABLE /// is the entry structure that is used in routing tables /// typedef struct { /// /// The IPv6 address of the gateway to be used as the next hop for /// packets to this prefix. If the IPv6 address is all zeros, then the /// prefix is on-link. /// EFI_IPv6_ADDRESS Gateway; /// /// The destination prefix to be routed. /// EFI_IPv6_ADDRESS Destination; /// /// The length of the prefix associated with the Destination. /// UINT8 PrefixLength; } EFI_IP6_ROUTE_TABLE; /// /// EFI_IP6_NEIGHBOR_STATE /// typedef enum { /// /// Address resolution is being performed on this entry. Specially, /// Neighbor Solicitation has been sent to the solicited-node /// multicast address of the target, but corresponding Neighbor /// Advertisement has not been received. /// EfiNeighborInComplete, /// /// Positive confirmation was received that the forward path to the /// neighbor was functioning properly. /// EfiNeighborReachable, /// /// Reachable Time has elapsed since the last positive confirmation /// was received. In this state, the forward path to the neighbor was /// functioning properly. /// EfiNeighborStale, /// /// This state is an optimization that gives upper-layer protocols /// additional time to provide reachability confirmation. /// EfiNeighborDelay, /// /// A reachability confirmation is actively sought by retransmitting /// Neighbor Solicitations every RetransTimer milliseconds until a /// reachability confirmation is received. /// EfiNeighborProbe } EFI_IP6_NEIGHBOR_STATE; /// /// EFI_IP6_NEIGHBOR_CACHE /// is the entry structure that is used in neighbor cache. It records a set /// of entries about individual neighbors to which traffic has been sent recently. /// typedef struct { EFI_IPv6_ADDRESS Neighbor; ///< The on-link unicast/anycast IP address of the neighbor. EFI_MAC_ADDRESS LinkAddress; ///< Link-layer address of the neighbor. EFI_IP6_NEIGHBOR_STATE State; ///< State of this neighbor cache entry. } EFI_IP6_NEIGHBOR_CACHE; /// /// EFI_IP6_ICMP_TYPE /// is used to describe those ICMP messages that are supported by this EFI /// IPv6 Protocol driver. /// typedef struct { UINT8 Type; ///< The type of ICMP message. UINT8 Code; ///< The code of the ICMP message. } EFI_IP6_ICMP_TYPE; /// /// EFI_IP6_MODE_DATA /// typedef struct { /// /// Set to TRUE after this EFI IPv6 Protocol instance is started. /// All other fields in this structure are undefined until this field is TRUE. /// Set to FALSE when the EFI IPv6 Protocol instance is stopped. /// BOOLEAN IsStarted; /// /// The maximum packet size, in bytes, of the packet which the upper layer driver could feed. /// UINT32 MaxPacketSize; /// /// Current configuration settings. Undefined until IsStarted is TRUE. /// EFI_IP6_CONFIG_DATA ConfigData; /// /// Set to TRUE when the EFI IPv6 Protocol instance is configured. /// The instance is configured when it has a station address and /// corresponding prefix length. /// Set to FALSE when the EFI IPv6 Protocol instance is not configured. /// BOOLEAN IsConfigured; /// /// Number of configured IPv6 addresses on this interface. /// UINT32 AddressCount; /// /// List of currently configured IPv6 addresses and corresponding /// prefix lengths assigned to this interface. It is caller's /// responsibility to free this buffer. /// EFI_IP6_ADDRESS_INFO *AddressList; /// /// Number of joined multicast groups. Undefined until /// IsConfigured is TRUE. /// UINT32 GroupCount; /// /// List of joined multicast group addresses. It is caller's /// responsibility to free this buffer. Undefined until /// IsConfigured is TRUE. /// EFI_IPv6_ADDRESS *GroupTable; /// /// Number of entries in the routing table. Undefined until /// IsConfigured is TRUE. /// UINT32 RouteCount; /// /// Routing table entries. It is caller's responsibility to free this buffer. /// EFI_IP6_ROUTE_TABLE *RouteTable; /// /// Number of entries in the neighbor cache. Undefined until /// IsConfigured is TRUE. /// UINT32 NeighborCount; /// /// Neighbor cache entries. It is caller's responsibility to free this /// buffer. Undefined until IsConfigured is TRUE. /// EFI_IP6_NEIGHBOR_CACHE *NeighborCache; /// /// Number of entries in the prefix table. Undefined until /// IsConfigured is TRUE. /// UINT32 PrefixCount; /// /// On-link Prefix table entries. It is caller's responsibility to free this /// buffer. Undefined until IsConfigured is TRUE. /// EFI_IP6_ADDRESS_INFO *PrefixTable; /// /// Number of entries in the supported ICMP types list. /// UINT32 IcmpTypeCount; /// /// Array of ICMP types and codes that are supported by this EFI /// IPv6 Protocol driver. It is caller's responsibility to free this /// buffer. /// EFI_IP6_ICMP_TYPE *IcmpTypeList; } EFI_IP6_MODE_DATA; /// /// EFI_IP6_HEADER /// The fields in the IPv6 header structure are defined in the Internet /// Protocol version6 specification. /// #pragma pack(1) typedef struct _EFI_IP6_HEADER { UINT8 TrafficClassH : 4; UINT8 Version : 4; UINT8 FlowLabelH : 4; UINT8 TrafficClassL : 4; UINT16 FlowLabelL; UINT16 PayloadLength; UINT8 NextHeader; UINT8 HopLimit; EFI_IPv6_ADDRESS SourceAddress; EFI_IPv6_ADDRESS DestinationAddress; } EFI_IP6_HEADER; #pragma pack() /// /// EFI_IP6_FRAGMENT_DATA /// describes the location and length of the IPv6 packet /// fragment to transmit or that has been received. /// typedef struct _EFI_IP6_FRAGMENT_DATA { UINT32 FragmentLength; ///< Length of fragment data. This field may not be set to zero. VOID *FragmentBuffer; ///< Pointer to fragment data. This field may not be set to NULL. } EFI_IP6_FRAGMENT_DATA; /// /// EFI_IP6_RECEIVE_DATA /// typedef struct _EFI_IP6_RECEIVE_DATA { /// /// Time when the EFI IPv6 Protocol driver accepted the packet. /// Ignored if it is zero. /// EFI_TIME TimeStamp; /// /// After this event is signaled, the receive data structure is released /// and must not be referenced. /// EFI_EVENT RecycleSignal; /// /// Length of the IPv6 packet headers, including both the IPv6 /// header and any extension headers. /// UINT32 HeaderLength; /// /// Pointer to the IPv6 packet header. If the IPv6 packet was /// fragmented, this argument is a pointer to the header in the first /// fragment. /// EFI_IP6_HEADER *Header; /// /// Sum of the lengths of IPv6 packet buffers in FragmentTable. May /// be zero. /// UINT32 DataLength; /// /// Number of IPv6 payload fragments. May be zero. /// UINT32 FragmentCount; /// /// Array of payload fragment lengths and buffer pointers. /// EFI_IP6_FRAGMENT_DATA FragmentTable[1]; } EFI_IP6_RECEIVE_DATA; /// /// EFI_IP6_OVERRIDE_DATA /// The information and flags in the override data structure will override /// default parameters or settings for one Transmit() function call. /// typedef struct _EFI_IP6_OVERRIDE_DATA { UINT8 Protocol; ///< Protocol type override. UINT8 HopLimit; ///< Hop-Limit override. UINT32 FlowLabel; ///< Flow-Label override. } EFI_IP6_OVERRIDE_DATA; /// /// EFI_IP6_TRANSMIT_DATA /// typedef struct _EFI_IP6_TRANSMIT_DATA { /// /// The destination IPv6 address. If it is unspecified, /// ConfigData.DestinationAddress will be used instead. /// EFI_IPv6_ADDRESS DestinationAddress; /// /// If not NULL, the IPv6 transmission control override data. /// EFI_IP6_OVERRIDE_DATA *OverrideData; /// /// Total length in byte of the IPv6 extension headers specified in /// ExtHdrs. /// UINT32 ExtHdrsLength; /// /// Pointer to the IPv6 extension headers. The IP layer will append /// the required extension headers if they are not specified by /// ExtHdrs. Ignored if ExtHdrsLength is zero. /// VOID *ExtHdrs; /// /// The protocol of first extension header in ExtHdrs. Ignored if /// ExtHdrsLength is zero. /// UINT8 NextHeader; /// /// Total length in bytes of the FragmentTable data to transmit. /// UINT32 DataLength; /// /// Number of entries in the fragment data table. /// UINT32 FragmentCount; /// /// Start of the fragment data table. /// EFI_IP6_FRAGMENT_DATA FragmentTable[1]; } EFI_IP6_TRANSMIT_DATA; /// /// EFI_IP6_COMPLETION_TOKEN /// structures are used for both transmit and receive operations. /// typedef struct { /// /// This Event will be signaled after the Status field is updated by /// the EFI IPv6 Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. /// EFI_EVENT Event; /// /// Will be set to one of the following values: /// - EFI_SUCCESS: The receive or transmit completed /// successfully. /// - EFI_ABORTED: The receive or transmit was aborted /// - EFI_TIMEOUT: The transmit timeout expired. /// - EFI_ICMP_ERROR: An ICMP error packet was received. /// - EFI_DEVICE_ERROR: An unexpected system or network /// error occurred. /// - EFI_SECURITY_VIOLATION: The transmit or receive was /// failed because of an IPsec policy check. /// - EFI_NO_MEDIA: There was a media error. /// EFI_STATUS Status; union { /// /// When the Token is used for receiving, RxData is a pointer to the EFI_IP6_RECEIVE_DATA. /// EFI_IP6_RECEIVE_DATA *RxData; /// /// When the Token is used for transmitting, TxData is a pointer to the EFI_IP6_TRANSMIT_DATA. /// EFI_IP6_TRANSMIT_DATA *TxData; } Packet; } EFI_IP6_COMPLETION_TOKEN; /** Gets the current operational settings for this instance of the EFI IPv6 Protocol driver. The GetModeData() function returns the current operational mode data for this driver instance. The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to retrieve the operational mode data of underlying networks or drivers.. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[out] Ip6ModeData Pointer to the EFI IPv6 Protocol mode data structure. @param[out] MnpConfigData Pointer to the managed network configuration data structure. @param[out] SnpModeData Pointer to the simple network mode data structure. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_GET_MODE_DATA)( IN EFI_IP6_PROTOCOL *This, OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance. The Configure() function is used to set, change, or reset the operational parameters and filter settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic can be sent or received by this instance. Once the parameters have been reset (by calling this function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped independently of each other by enabling or disabling their receive filter settings with the Configure() function. If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required to be one of the currently configured IPv6 addresses list in the EFI IPv6 drivers, or else EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is unspecified, the IPv6 driver will bind a source address according to the source address selection algorithm. Clients could frequently call GetModeData() to check get currently configured IPv6 address list in the EFI IPv6 driver. If both Ip6ConfigData.StationAddress and Ip6ConfigData.Destination are unspecified, when transmitting the packet afterwards, the source address filled in each outgoing IPv6 packet is decided based on the destination of this packet. . If operational parameters are reset or changed, any pending transmit and receive requests will be cancelled. Their completion token status will be set to EFI_ABORTED and their events will be signaled. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] Ip6ConfigData Pointer to the EFI IPv6 Protocol configuration data structure. @retval EFI_SUCCESS The driver instance was successfully opened. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Ip6ConfigData.StationAddress is neither zero nor a unicast IPv6 address. - Ip6ConfigData.StationAddress is neither zero nor one of the configured IP addresses in the EFI IPv6 driver. - Ip6ConfigData.DefaultProtocol is illegal. @retval EFI_OUT_OF_RESOURCES The EFI IPv6 Protocol driver instance data could not be allocated. @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_ALREADY_STARTED The interface is already open and must be stopped before the IPv6 address or prefix length can be changed. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv6 Protocol driver instance is not opened. @retval EFI_UNSUPPORTED Default protocol specified through Ip6ConfigData.DefaulProtocol isn't supported. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CONFIGURE)( IN EFI_IP6_PROTOCOL *This, IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL ); /** Joins and leaves multicast groups. The Groups() function is used to join and leave multicast group sessions. Joining a group will enable reception of matching multicast packets. Leaving a group will disable reception of matching multicast packets. Source-Specific Multicast isn't required to be supported. If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] JoinFlag Set to TRUE to join the multicast group session and FALSE to leave. @param[in] GroupAddress Pointer to the IPv6 multicast address. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: - This is NULL. - JoinFlag is TRUE and GroupAddress is NULL. - GroupAddress is not NULL and *GroupAddress is not a multicast IPv6 address. - GroupAddress is not NULL and *GroupAddress is in the range of SSM destination address. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_OUT_OF_RESOURCES System resources could not be allocated. @retval EFI_UNSUPPORTED This EFI IPv6 Protocol implementation does not support multicast groups. @retval EFI_ALREADY_STARTED The group address is already in the group table (when JoinFlag is TRUE). @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_GROUPS)( IN EFI_IP6_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL ); /** Adds and deletes routing table entries. The Routes() function adds a route to or deletes a route from the routing table. Routes are determined by comparing the leftmost PrefixLength bits of Destination with the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the configured station address. The default route is added with Destination and PrefixLegth both set to all zeros. The default route matches all destination IPv6 addresses that do not match any other routes. All EFI IPv6 Protocol instances share a routing table. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] DeleteRoute Set to TRUE to delete this route from the routing table. Set to FALSE to add this route to the routing table. Destination, PrefixLength and Gateway are used as the key to each route entry. @param[in] Destination The address prefix of the subnet that needs to be routed. @param[in] PrefixLength The prefix length of Destination. Ignored if Destination is NULL. @param[in] GatewayAddress The unicast gateway IPv6 address for this route. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The driver instance has not been started. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - When DeleteRoute is TRUE, both Destination and GatewayAddress are NULL. - When DeleteRoute is FALSE, either Destination or GatewayAddress is NULL. - *GatewayAddress is not a valid unicast IPv6 address. - *GatewayAddress is one of the local configured IPv6 addresses. @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table. @retval EFI_NOT_FOUND This route is not in the routing table (when DeleteRoute is TRUE). @retval EFI_ACCESS_DENIED The route is already defined in the routing table (when DeleteRoute is FALSE). **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_ROUTES)( IN EFI_IP6_PROTOCOL *This, IN BOOLEAN DeleteRoute, IN EFI_IPv6_ADDRESS *Destination OPTIONAL, IN UINT8 PrefixLength, IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL ); /** Add or delete Neighbor cache entries. The Neighbors() function is used to add, update, or delete an entry from neighbor cache. IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as network traffic is processed. Most neighbor cache entries will time out and be deleted if the network traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not timeout) or dynamic (will time out). The implementation should follow the neighbor cache timeout mechanism which is defined in RFC4861. The default neighbor cache timeout value should be tuned for the expected network environment @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] DeleteFlag Set to TRUE to delete the specified cache entry, set to FALSE to add (or update, if it already exists and Override is TRUE) the specified cache entry. TargetIp6Address is used as the key to find the requested cache entry. @param[in] TargetIp6Address Pointer to Target IPv6 address. @param[in] TargetLinkAddress Pointer to link-layer address of the target. Ignored if NULL. @param[in] Timeout Time in 100-ns units that this entry will remain in the neighbor cache, it will be deleted after Timeout. A value of zero means that the entry is permanent. A non-zero value means that the entry is dynamic. @param[in] Override If TRUE, the cached link-layer address of the matching entry will be overridden and updated; if FALSE, EFI_ACCESS_DENIED will be returned if a corresponding cache entry already existed. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - TargetIpAddress is NULL. - *TargetLinkAddress is invalid when not NULL. - *TargetIpAddress is not a valid unicast IPv6 address. - *TargetIpAddress is one of the local configured IPv6 addresses. @retval EFI_OUT_OF_RESOURCES Could not add the entry to the neighbor cache. @retval EFI_NOT_FOUND This entry is not in the neighbor cache (when DeleteFlag is TRUE or when DeleteFlag is FALSE while TargetLinkAddress is NULL.). @retval EFI_ACCESS_DENIED The to-be-added entry is already defined in the neighbor cache, and that entry is tagged as un-overridden (when DeleteFlag is FALSE). **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_NEIGHBORS)( IN EFI_IP6_PROTOCOL *This, IN BOOLEAN DeleteFlag, IN EFI_IPv6_ADDRESS *TargetIp6Address, IN EFI_MAC_ADDRESS *TargetLinkAddress, IN UINT32 Timeout, IN BOOLEAN Override ); /** Places outgoing data packets into the transmit queue. The Transmit() function places a sending request in the transmit queue of this EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some errors occur, the event in the token will be signaled and the status is updated. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] Token Pointer to the transmit token. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing a source address for this transmission, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. - Token.Packet.TxData is NULL. - Token.Packet.ExtHdrsLength is not zero and Token.Packet.ExtHdrs is NULL. - Token.Packet.FragmentCount is zero. - One or more of the Token.Packet.TxData.FragmentTable[].FragmentLength fields is zero. - One or more of the Token.Packet.TxData.FragmentTable[].FragmentBuffer fields is NULL. - Token.Packet.TxData.DataLength is zero or not equal to the sum of fragment lengths. - Token.Packet.TxData.DestinationAddress is non-zero when DestinationAddress is configured as non-zero when doing Configure() for this EFI IPv6 protocol instance. - Token.Packet.TxData.DestinationAddress is unspecified when DestinationAddress is unspecified when doing Configure() for this EFI IPv6 protocol instance. @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event was already in the transmit queue. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_NOT_FOUND Not route is found to destination address. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. @retval EFI_BUFFER_TOO_SMALL Token.Packet.TxData.TotalDataLength is too short to transmit. @retval EFI_BAD_BUFFER_SIZE If Token.Packet.TxData.DataLength is beyond the maximum that which can be described through the Fragment Offset field in Fragment header when performing fragmentation. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_TRANSMIT)( IN EFI_IP6_PROTOCOL *This, IN EFI_IP6_COMPLETION_TOKEN *Token ); /** Places a receiving request into the receiving queue. The Receive() function places a completion token into the receive packet queue. This function is always asynchronous. The Token.Event field in the completion token must be filled in by the caller and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event is signaled. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] Token Pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started. @retval EFI_NO_MAPPING When IP6 driver responsible for binding source address to this instance, while no source address is available for use. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv6 Protocol instance has been reset to startup defaults. @retval EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already in the receive queue. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_RECEIVE)( IN EFI_IP6_PROTOCOL *This, IN EFI_IP6_COMPLETION_TOKEN *Token ); /** Abort an asynchronous transmit or receive request. The Cancel() function is used to abort a pending transmit or receive request. If the token is in the transmit or receive request queues, after calling this function, Token->Status will be set to EFI_ABORTED and then Token->Event will be signaled. If the token is not in one of the queues, which usually means the asynchronous operation has completed, this function will not signal the token and EFI_NOT_FOUND is returned. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @param[in] Token Pointer to a token that has been issued by EFI_IP6_PROTOCOL.Transmit() or EFI_IP6_PROTOCOL.Receive(). If NULL, all pending tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is defined in EFI_IP6_PROTOCOL.Transmit(). @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token->Event was signaled. When Token is NULL, all pending requests were aborted and their events were signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was not found in the transmit or receive queue. It has either completed or was not issued by Transmit() and Receive(). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CANCEL)( IN EFI_IP6_PROTOCOL *This, IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL ); /** Polls for incoming data packets and processes outgoing data packets. The Poll() function polls for incoming data packets and processes outgoing data packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll() function to increase the rate that data packets are moved between the communications device and the transmit and receive queues. In some systems the periodic timer event may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function more often. @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY No incoming or outgoing data is processed. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_POLL)( IN EFI_IP6_PROTOCOL *This ); /// /// The EFI IPv6 Protocol implements a simple packet-oriented interface that can be /// used by drivers, daemons, and applications to transmit and receive network packets. /// struct _EFI_IP6_PROTOCOL { EFI_IP6_GET_MODE_DATA GetModeData; EFI_IP6_CONFIGURE Configure; EFI_IP6_GROUPS Groups; EFI_IP6_ROUTES Routes; EFI_IP6_NEIGHBORS Neighbors; EFI_IP6_TRANSMIT Transmit; EFI_IP6_RECEIVE Receive; EFI_IP6_CANCEL Cancel; EFI_IP6_POLL Poll; }; extern EFI_GUID gEfiIp6ServiceBindingProtocolGuid; extern EFI_GUID gEfiIp6ProtocolGuid; #endif /** @file This file provides a definition of the EFI IPv6 Configuration Protocol. Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_IP6CONFIG_PROTOCOL_H__ #define __EFI_IP6CONFIG_PROTOCOL_H__ #include #define EFI_IP6_CONFIG_PROTOCOL_GUID \ { \ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ } typedef struct _EFI_IP6_CONFIG_PROTOCOL EFI_IP6_CONFIG_PROTOCOL; /// /// EFI_IP6_CONFIG_DATA_TYPE /// typedef enum { /// /// The interface information of the communication /// device this EFI IPv6 Configuration Protocol instance manages. /// This type of data is read only.The corresponding Data is of type /// EFI_IP6_CONFIG_INTERFACE_INFO. /// Ip6ConfigDataTypeInterfaceInfo, /// /// The alternative interface ID for the /// communication device this EFI IPv6 Configuration Protocol /// instance manages if the link local IPv6 address generated from /// the interfaced ID based on the default source the EFI IPv6 /// Protocol uses is a duplicate address. The length of the interface /// ID is 64 bit. The corresponding Data is of type /// EFI_IP6_CONFIG_INTERFACE_ID. /// Ip6ConfigDataTypeAltInterfaceId, /// /// The general configuration policy for the EFI IPv6 network /// stack running on the communication device this EFI IPv6 /// Configuration Protocol instance manages. The policy will affect /// other configuration settings. The corresponding Data is of type /// EFI_IP6_CONFIG_POLICY. /// Ip6ConfigDataTypePolicy, /// /// The number of consecutive /// Neighbor Solicitation messages sent while performing Duplicate /// Address Detection on a tentative address. A value of zero /// indicates that Duplicate Address Detection will not be performed /// on tentative addresses. The corresponding Data is of type /// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS. /// Ip6ConfigDataTypeDupAddrDetectTransmits, /// /// The station addresses set manually for the EFI /// IPv6 network stack. It is only configurable when the policy is /// Ip6ConfigPolicyManual. The corresponding Data is a /// pointer to an array of EFI_IPv6_ADDRESS instances. When /// DataSize is 0 and Data is NULL, the existing configuration /// is cleared from the EFI IPv6 Configuration Protocol instance. /// Ip6ConfigDataTypeManualAddress, /// /// The gateway addresses set manually for the EFI IPv6 /// network stack running on the communication device this EFI /// IPv6 Configuration Protocol manages. It is not configurable when /// the policy is Ip6ConfigPolicyAutomatic. The gateway /// addresses must be unicast IPv6 addresses. The corresponding /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances. /// When DataSize is 0 and Data is NULL, the existing configuration /// is cleared from the EFI IPv6 Configuration Protocol instance. /// Ip6ConfigDataTypeGateway, /// /// The DNS server list for the EFI IPv6 network stack /// running on the communication device this EFI IPv6 /// Configuration Protocol manages. It is not configurable when the /// policy is Ip6ConfigPolicyAutomatic.The DNS server /// addresses must be unicast IPv6 addresses. The corresponding /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances. /// When DataSize is 0 and Data is NULL, the existing configuration /// is cleared from the EFI IPv6 Configuration Protocol instance. /// Ip6ConfigDataTypeDnsServer, /// /// The number of this enumeration memebers. /// Ip6ConfigDataTypeMaximum } EFI_IP6_CONFIG_DATA_TYPE; /// /// EFI_IP6_CONFIG_INTERFACE_INFO /// describes the operational state of the interface this /// EFI IPv6 Configuration Protocol instance manages. /// typedef struct { /// /// The name of the interface. It is a NULL-terminated string. /// CHAR16 Name[32]; /// /// The interface type of the network interface. /// UINT8 IfType; /// /// The size, in bytes, of the network interface's hardware address. /// UINT32 HwAddressSize; /// /// The hardware address for the network interface. /// EFI_MAC_ADDRESS HwAddress; /// /// Number of EFI_IP6_ADDRESS_INFO structures pointed to by AddressInfo. /// UINT32 AddressInfoCount; /// /// Pointer to an array of EFI_IP6_ADDRESS_INFO instances /// which contain the local IPv6 addresses and the corresponding /// prefix length information. Set to NULL if AddressInfoCount /// is zero. /// EFI_IP6_ADDRESS_INFO *AddressInfo; /// /// Number of route table entries in the following RouteTable. /// UINT32 RouteCount; /// /// The route table of the IPv6 network stack runs on this interface. /// Set to NULL if RouteCount is zero. /// EFI_IP6_ROUTE_TABLE *RouteTable; } EFI_IP6_CONFIG_INTERFACE_INFO; /// /// EFI_IP6_CONFIG_INTERFACE_ID /// describes the 64-bit interface ID. /// typedef struct { UINT8 Id[8]; } EFI_IP6_CONFIG_INTERFACE_ID; /// /// EFI_IP6_CONFIG_POLICY /// defines the general configuration policy the EFI IPv6 /// Configuration Protocol supports. /// typedef enum { /// /// Under this policy, the IpI6ConfigDataTypeManualAddress, /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer /// configuration data are required to be set manually. /// The EFI IPv6 Protocol will get all required configuration /// such as address, prefix and gateway settings from the EFI /// IPv6 Configuration protocol. /// Ip6ConfigPolicyManual, /// /// Under this policy, the IpI6ConfigDataTypeManualAddress, /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer /// configuration data are not allowed to set via SetData(). /// All of these configurations are retrieved from some auto /// configuration mechanism. /// The EFI IPv6 Protocol will use the IPv6 stateless address /// autoconfiguration mechanism and/or the IPv6 stateful address /// autoconfiguration mechanism described in the related RFCs to /// get address and other configuration information /// Ip6ConfigPolicyAutomatic } EFI_IP6_CONFIG_POLICY; /// /// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS /// describes the number of consecutive Neighbor Solicitation messages sent /// while performing Duplicate Address Detection on a tentative address. /// The default value for a newly detected communication device is 1. /// typedef struct { UINT32 DupAddrDetectTransmits; ///< The number of consecutive Neighbor Solicitation messages sent. } EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS; /// /// EFI_IP6_CONFIG_MANUAL_ADDRESS /// is used to set the station address information for the EFI IPv6 network /// stack manually when the policy is Ip6ConfigPolicyManual. /// typedef struct { EFI_IPv6_ADDRESS Address; ///< The IPv6 unicast address. BOOLEAN IsAnycast; ///< Set to TRUE if Address is anycast. UINT8 PrefixLength; ///< The length, in bits, of the prefix associated with this Address. } EFI_IP6_CONFIG_MANUAL_ADDRESS; /** Set the configuration for the EFI IPv6 network stack running on the communication device this EFI IPv6 Configuration Protocol instance manages. This function is used to set the configuration data of type DataType for the EFI IPv6 network stack running on the communication device this EFI IPv6 Configuration Protocol instance manages. The DataSize is used to calculate the count of structure instances in the Data for some DataType that multiple structure instances are allowed. This function is always non-blocking. When setting some type of configuration data, an asynchronous process is invoked to check the correctness of the data, such as doing Duplicate Address Detection on the manually set local IPv6 addresses. EFI_NOT_READY is returned immediately to indicate that such an asynchronous process is invoked and the process is not finished yet. The caller willing to get the result of the asynchronous process is required to call RegisterDataNotify() to register an event on the specified configuration data. Once the event is signaled, the caller can call GetData() to get back the configuration data in order to know the result. For other types of configuration data that do not require an asynchronous configuration process, the result of the operation is immediately returned. @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to set. @param[in] DataSize Size of the buffer pointed to by Data in bytes. @param[in] Data The data buffer to set. The type of the data buffer is associated with the DataType. @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 network stack is set successfully. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - One or more fields in Data and DataSize do not match the requirement of the data type indicated by DataType. @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified configuration data can not be set under the current policy @retval EFI_ACCESS_DENIED Another set operation on the specified configuration data is already in process. @retval EFI_NOT_READY An asynchronous process is invoked to set the specified configuration data and the process is not finished yet. @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type indicated by DataType. @retval EFI_UNSUPPORTED This DataType is not supported. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CONFIG_SET_DATA)( IN EFI_IP6_CONFIG_PROTOCOL *This, IN EFI_IP6_CONFIG_DATA_TYPE DataType, IN UINTN DataSize, IN VOID *Data ); /** Get the configuration data for the EFI IPv6 network stack running on the communication device this EFI IPv6 Configuration Protocol instance manages. This function returns the configuration data of type DataType for the EFI IPv6 network stack running on the communication device this EFI IPv6 Configuration Protocol instance manages. The caller is responsible for allocating the buffer used to return the specified configuration data and the required size will be returned to the caller if the size of the buffer is too small. EFI_NOT_READY is returned if the specified configuration data is not ready due to an already in progress asynchronous configuration process. The caller can call RegisterDataNotify() to register an event on the specified configuration data. Once the asynchronous configuration process is finished, the event will be signaled and a subsequent GetData() call will return the specified configuration data. @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to get. @param[in,out] DataSize On input, in bytes, the size of Data. On output, in bytes, the size of buffer required to store the specified configuration data. @param[in] Data The data buffer in which the configuration data is returned. The type of the data buffer is associated with the DataType. @retval EFI_SUCCESS The specified configuration data is got successfully. @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: - This is NULL. - DataSize is NULL. - Data is NULL if *DataSize is not zero. @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data and the required size is returned in DataSize. @retval EFI_NOT_READY The specified configuration data is not ready due to an already in progress asynchronous configuration process. @retval EFI_NOT_FOUND The specified configuration data is not found. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CONFIG_GET_DATA)( IN EFI_IP6_CONFIG_PROTOCOL *This, IN EFI_IP6_CONFIG_DATA_TYPE DataType, IN OUT UINTN *DataSize, IN VOID *Data OPTIONAL ); /** Register an event that is to be signaled whenever a configuration process on the specified configuration data is done. This function registers an event that is to be signaled whenever a configuration process on the specified configuration data is done. An event can be registered for different DataType simultaneously and the caller is responsible for determining which type of configuration data causes the signaling of the event in such case. @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to unregister the event for. @param[in] Event The event to register. @retval EFI_SUCCESS The notification event for the specified configuration data is registered. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not supported. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The Event is already registered for the DataType. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CONFIG_REGISTER_NOTIFY)( IN EFI_IP6_CONFIG_PROTOCOL *This, IN EFI_IP6_CONFIG_DATA_TYPE DataType, IN EFI_EVENT Event ); /** Remove a previously registered event for the specified configuration data. This function removes a previously registered event for the specified configuration data. @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to remove the previously registered event for. @param[in] Event The event to unregister. @retval EFI_SUCCESS The event registered for the specified configuration data is removed. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_NOT_FOUND The Event has not been registered for the specified DataType. **/ typedef EFI_STATUS (EFIAPI *EFI_IP6_CONFIG_UNREGISTER_NOTIFY)( IN EFI_IP6_CONFIG_PROTOCOL *This, IN EFI_IP6_CONFIG_DATA_TYPE DataType, IN EFI_EVENT Event ); /// /// The EFI_IP6_CONFIG_PROTOCOL provides the mechanism to set and get various /// types of configurations for the EFI IPv6 network stack. /// struct _EFI_IP6_CONFIG_PROTOCOL { EFI_IP6_CONFIG_SET_DATA SetData; EFI_IP6_CONFIG_GET_DATA GetData; EFI_IP6_CONFIG_REGISTER_NOTIFY RegisterDataNotify; EFI_IP6_CONFIG_UNREGISTER_NOTIFY UnregisterDataNotify; }; extern EFI_GUID gEfiIp6ConfigProtocolGuid; #endif /** @file EFI IPSEC Protocol Definition The EFI_IPSEC_PROTOCOL is used to abstract the ability to deal with the individual packets sent and received by the host and provide packet-level security for IP datagram. The EFI_IPSEC2_PROTOCOL is used to abstract the ability to deal with the individual packets sent and received by the host and provide packet-level security for IP datagram. In addition, it supports the Option (extension header) processing in IPsec which doesn't support in EFI_IPSEC_PROTOCOL. It is also recommended to use EFI_IPSEC2_PROTOCOL instead of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel Mode. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: The EFI_IPSEC2_PROTOCOL is introduced in UEFI Specification 2.3D. **/ #ifndef __EFI_IPSEC_PROTOCOL_H__ #define __EFI_IPSEC_PROTOCOL_H__ #include #define EFI_IPSEC_PROTOCOL_GUID \ { \ 0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 } \ } #define EFI_IPSEC2_PROTOCOL_GUID \ { \ 0xa3979e64, 0xace8, 0x4ddc, {0xbc, 0x7, 0x4d, 0x66, 0xb8, 0xfd, 0x9, 0x77 } \ } typedef struct _EFI_IPSEC_PROTOCOL EFI_IPSEC_PROTOCOL; typedef struct _EFI_IPSEC2_PROTOCOL EFI_IPSEC2_PROTOCOL; /// /// EFI_IPSEC_FRAGMENT_DATA /// defines the instances of packet fragments. /// typedef struct _EFI_IPSEC_FRAGMENT_DATA { UINT32 FragmentLength; VOID *FragmentBuffer; } EFI_IPSEC_FRAGMENT_DATA; /** Handles IPsec packet processing for inbound and outbound IP packets. The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet. The behavior is that it can perform one of the following actions: bypass the packet, discard the packet, or protect the packet. @param[in] This Pointer to the EFI_IPSEC_PROTOCOL instance. @param[in] NicHandle Instance of the network interface. @param[in] IpVer IPV4 or IPV6. @param[in, out] IpHead Pointer to the IP Header. @param[in] LastHead The protocol of the next layer to be processed by IPsec. @param[in] OptionsBuffer Pointer to the options buffer. @param[in] OptionsLength Length of the options buffer. @param[in, out] FragmentTable Pointer to a list of fragments. @param[in] FragmentCount Number of fragments. @param[in] TrafficDirection Traffic direction. @param[out] RecycleSignal Event for recycling of resources. @retval EFI_SUCCESS The packet was bypassed and all buffers remain the same. @retval EFI_SUCCESS The packet was protected. @retval EFI_ACCESS_DENIED The packet was discarded. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_PROCESS)( IN EFI_IPSEC_PROTOCOL *This, IN EFI_HANDLE NicHandle, IN UINT8 IpVer, IN OUT VOID *IpHead, IN UINT8 *LastHead, IN VOID *OptionsBuffer, IN UINT32 OptionsLength, IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, IN UINT32 *FragmentCount, IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection, OUT EFI_EVENT *RecycleSignal ); /// /// EFI_IPSEC_PROTOCOL /// provides the ability for securing IP communications by authenticating /// and/or encrypting each IP packet in a data stream. // EFI_IPSEC_PROTOCOL can be consumed by both the IPv4 and IPv6 stack. // A user can employ this protocol for IPsec package handling in both IPv4 // and IPv6 environment. /// struct _EFI_IPSEC_PROTOCOL { EFI_IPSEC_PROCESS Process; ///< Handle the IPsec message. EFI_EVENT DisabledEvent; ///< Event signaled when the interface is disabled. BOOLEAN DisabledFlag; ///< State of the interface. }; /** Handles IPsec processing for both inbound and outbound IP packets. Compare with Process() in EFI_IPSEC_PROTOCOL, this interface has the capability to process Option(Extension Header). The EFI_IPSEC2_PROCESS process routine handles each inbound or outbound packet. The behavior is that it can perform one of the following actions: bypass the packet, discard the packet, or protect the packet. @param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance. @param[in] NicHandle Instance of the network interface. @param[in] IpVer IP version.IPv4 or IPv6. @param[in, out] IpHead Pointer to the IP Header it is either the EFI_IP4_HEADER or EFI_IP6_HEADER. On input, it contains the IP header. On output, 1) in tunnel mode and the traffic direction is inbound, the buffer will be reset to zero by IPsec; 2) in tunnel mode and the traffic direction is outbound, the buffer will reset to be the tunnel IP header.3) in transport mode, the related fielders (like payload length, Next header) in IP header will be modified according to the condition. @param[in, out] LastHead For IP4, it is the next protocol in IP header. For IP6 it is the Next Header of the last extension header. @param[in, out] OptionsBuffer On input, it contains the options (extensions header) to be processed by IPsec. On output, 1) in tunnel mode and the traffic direction is outbound, it will be set to NULL, and that means this contents was wrapped after inner header and should not be concatenated after tunnel header again; 2) in transport mode and the traffic direction is inbound, if there are IP options (extension headers) protected by IPsec, IPsec will concatenate the those options after the input options (extension headers); 3) on other situations, the output of contents of OptionsBuffer might be same with input's. The caller should take the responsibility to free the buffer both on input and on output. @param[in, out] OptionsLength On input, the input length of the options buffer. On output, the output length of the options buffer. @param[in, out] FragmentTable Pointer to a list of fragments. On input, these fragments contain the IP payload. On output, 1) in tunnel mode and the traffic direction is inbound, the fragments contain the whole IP payload which is from the IP inner header to the last byte of the packet; 2) in tunnel mode and the traffic direction is the outbound, the fragments contains the whole encapsulated payload which encapsulates the whole IP payload between the encapsulated header and encapsulated trailer fields. 3) in transport mode and the traffic direction is inbound, the fragments contains the IP payload which is from the next layer protocol to the last byte of the packet; 4) in transport mode and the traffic direction is outbound, the fragments contains the whole encapsulated payload which encapsulates the next layer protocol information between the encapsulated header and encapsulated trailer fields. @param[in, out] FragmentCount Number of fragments. @param[in] TrafficDirection Traffic direction. @param[out] RecycleSignal Event for recycling of resources. @retval EFI_SUCCESS The packet was processed by IPsec successfully. @retval EFI_ACCESS_DENIED The packet was discarded. @retval EFI_NOT_READY The IKE negotiation is invoked and the packet was discarded. @retval EFI_INVALID_PARAMETER One or more of following are TRUE: If OptionsBuffer is NULL; If OptionsLength is NULL; If FragmentTable is NULL; If FragmentCount is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_PROCESSEXT)( IN EFI_IPSEC2_PROTOCOL *This, IN EFI_HANDLE NicHandle, IN UINT8 IpVer, IN OUT VOID *IpHead, IN OUT UINT8 *LastHead, IN OUT VOID **OptionsBuffer, IN OUT UINT32 *OptionsLength, IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable, IN OUT UINT32 *FragmentCount, IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection, OUT EFI_EVENT *RecycleSignal ); /// /// EFI_IPSEC2_PROTOCOL /// supports the Option (extension header) processing in IPsec which doesn't support /// in EFI_IPSEC_PROTOCOL. It is also recommended to use EFI_IPSEC2_PROTOCOL instead /// of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel Mode. /// provides the ability for securing IP communications by authenticating and/or /// encrypting each IP packet in a data stream. /// struct _EFI_IPSEC2_PROTOCOL { EFI_IPSEC_PROCESSEXT ProcessExt; EFI_EVENT DisabledEvent; BOOLEAN DisabledFlag; }; extern EFI_GUID gEfiIpSecProtocolGuid; extern EFI_GUID gEfiIpSec2ProtocolGuid; #endif /** @file EFI IPsec Configuration Protocol Definition The EFI_IPSEC_CONFIG_PROTOCOL provides the mechanism to set and retrieve security and policy related information for the EFI IPsec protocol driver. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_IPSE_CCONFIG_PROTOCOL_H__ #define __EFI_IPSE_CCONFIG_PROTOCOL_H__ #define EFI_IPSEC_CONFIG_PROTOCOL_GUID \ { \ 0xce5e5929, 0xc7a3, 0x4602, {0xad, 0x9e, 0xc9, 0xda, 0xf9, 0x4e, 0xbf, 0xcf } \ } typedef struct _EFI_IPSEC_CONFIG_PROTOCOL EFI_IPSEC_CONFIG_PROTOCOL; /// /// EFI_IPSEC_CONFIG_DATA_TYPE /// typedef enum { /// /// The IPsec Security Policy Database (aka SPD) setting. In IPsec, /// an essential element of Security Association (SA) processing is /// underlying SPD that specifies what services are to be offered to /// IP datagram and in what fashion. The SPD must be consulted /// during the processing of all traffic (inbound and outbound), /// including traffic not protected by IPsec, that traverses the IPsec /// boundary. With this DataType, SetData() function is to set /// the SPD entry information, which may add one new entry, delete /// one existed entry or flush the whole database according to the /// parameter values. The corresponding Data is of type /// EFI_IPSEC_SPD_DATA /// IPsecConfigDataTypeSpd, /// /// The IPsec Security Association Database (aka SAD) setting. A /// SA is a simplex connection that affords security services to the /// traffic carried by it. Security services are afforded to an SA by the /// use of AH, or ESP, but not both. The corresponding Data is of /// type EFI_IPSEC_SAD_DATA. /// IPsecConfigDataTypeSad, /// /// The IPsec Peer Authorization Database (aka PAD) setting, which /// provides the link between the SPD and a security association /// management protocol. The PAD entry specifies the /// authentication protocol (e.g. IKEv1, IKEv2) method used and the /// authentication data. The corresponding Data is of type /// EFI_IPSEC_PAD_DATA. /// IPsecConfigDataTypePad, IPsecConfigDataTypeMaximum } EFI_IPSEC_CONFIG_DATA_TYPE; /// /// EFI_IP_ADDRESS_INFO /// typedef struct _EFI_IP_ADDRESS_INFO { EFI_IP_ADDRESS Address; ///< The IPv4 or IPv6 address UINT8 PrefixLength; ///< The length of the prefix associated with the Address. } EFI_IP_ADDRESS_INFO; /// /// EFI_IPSEC_SPD_SELECTOR /// typedef struct _EFI_IPSEC_SPD_SELECTOR { /// /// Specifies the actual number of entries in LocalAddress. /// UINT32 LocalAddressCount; /// /// A list of ranges of IPv4 or IPv6 addresses, which refers to the /// addresses being protected by IPsec policy. /// EFI_IP_ADDRESS_INFO *LocalAddress; /// /// Specifies the actual number of entries in RemoteAddress. /// UINT32 RemoteAddressCount; /// /// A list of ranges of IPv4 or IPv6 addresses, which are peer entities /// to LocalAddress. /// EFI_IP_ADDRESS_INFO *RemoteAddress; /// /// Next layer protocol. Obtained from the IPv4 Protocol or the IPv6 /// Next Header fields. The next layer protocol is whatever comes /// after any IP extension headers that are present. A zero value is a /// wildcard that matches any value in NextLayerProtocol field. /// UINT16 NextLayerProtocol; /// /// Local Port if the Next Layer Protocol uses two ports (as do TCP, /// UDP, and others). A zero value is a wildcard that matches any /// value in LocalPort field. /// UINT16 LocalPort; /// /// A designed port range size. The start port is LocalPort, and /// the total number of ports is described by LocalPortRange. /// This field is ignored if NextLayerProtocol does not use /// ports. /// UINT16 LocalPortRange; /// /// Remote Port if the Next Layer Protocol uses two ports. A zero /// value is a wildcard that matches any value in RemotePort field. /// UINT16 RemotePort; /// /// A designed port range size. The start port is RemotePort, and /// the total number of ports is described by RemotePortRange. /// This field is ignored if NextLayerProtocol does not use ports. /// UINT16 RemotePortRange; } EFI_IPSEC_SPD_SELECTOR; /// /// EFI_IPSEC_TRAFFIC_DIR /// represents the directionality in an SPD entry. /// typedef enum { /// /// The EfiIPsecInBound refers to traffic entering an IPsec implementation via /// the unprotected interface or emitted by the implementation on the unprotected /// side of the boundary and directed towards the protected interface. /// EfiIPsecInBound, /// /// The EfiIPsecOutBound refers to traffic entering the implementation via /// the protected interface, or emitted by the implementation on the protected side /// of the boundary and directed toward the unprotected interface. /// EfiIPsecOutBound } EFI_IPSEC_TRAFFIC_DIR; /// /// EFI_IPSEC_ACTION /// represents three possible processing choices. /// typedef enum { /// /// Refers to traffic that is not allowed to traverse the IPsec boundary. /// EfiIPsecActionDiscard, /// /// Refers to traffic that is allowed to cross the IPsec boundary /// without protection. /// EfiIPsecActionBypass, /// /// Refers to traffic that is afforded IPsec protection, and for such /// traffic the SPD must specify the security protocols to be /// employed, their mode, security service options, and the /// cryptographic algorithms to be used. /// EfiIPsecActionProtect } EFI_IPSEC_ACTION; /// /// EFI_IPSEC_SA_LIFETIME /// defines the lifetime of an SA, which represents when a SA must be /// replaced or terminated. A value of all 0 for each field removes /// the limitation of a SA lifetime. /// typedef struct _EFI_IPSEC_SA_LIFETIME { /// /// The number of bytes to which the IPsec cryptographic algorithm /// can be applied. For ESP, this is the encryption algorithm and for /// AH, this is the authentication algorithm. The ByteCount /// includes pad bytes for cryptographic operations. /// UINT64 ByteCount; /// /// A time interval in second that warns the implementation to /// initiate action such as setting up a replacement SA. /// UINT64 SoftLifetime; /// /// A time interval in second when the current SA ends and is /// destroyed. /// UINT64 HardLifetime; } EFI_IPSEC_SA_LIFETIME; /// /// EFI_IPSEC_MODE /// There are two modes of IPsec operation: transport mode and tunnel mode. In /// EfiIPsecTransport mode, AH and ESP provide protection primarily for next layer protocols; /// In EfiIPsecTunnel mode, AH and ESP are applied to tunneled IP packets. /// typedef enum { EfiIPsecTransport, EfiIPsecTunnel } EFI_IPSEC_MODE; /// /// EFI_IPSEC_TUNNEL_DF_OPTION /// The option of copying the DF bit from an outbound package to /// the tunnel mode header that it emits, when traffic is carried /// via a tunnel mode SA. This applies to SAs where both inner and /// outer headers are IPv4. /// typedef enum { EfiIPsecTunnelClearDf, ///< Clear DF bit from inner header. EfiIPsecTunnelSetDf, ///< Set DF bit from inner header. EfiIPsecTunnelCopyDf ///< Copy DF bit from inner header. } EFI_IPSEC_TUNNEL_DF_OPTION; /// /// EFI_IPSEC_TUNNEL_OPTION /// typedef struct _EFI_IPSEC_TUNNEL_OPTION { /// /// Local tunnel address when IPsec mode is EfiIPsecTunnel. /// EFI_IP_ADDRESS LocalTunnelAddress; /// /// Remote tunnel address when IPsec mode is EfiIPsecTunnel. /// EFI_IP_ADDRESS RemoteTunnelAddress; /// /// The option of copying the DF bit from an outbound package /// to the tunnel mode header that it emits, when traffic is /// carried via a tunnel mode SA. /// EFI_IPSEC_TUNNEL_DF_OPTION DF; } EFI_IPSEC_TUNNEL_OPTION; /// /// EFI_IPSEC_PROTOCOL_TYPE /// typedef enum { EfiIPsecAH, ///< IP Authentication Header protocol which is specified in RFC 4302. EfiIPsecESP ///< IP Encapsulating Security Payload which is specified in RFC 4303. } EFI_IPSEC_PROTOCOL_TYPE; /// /// EFI_IPSEC_PROCESS_POLICY /// describes a policy list for traffic processing. /// typedef struct _EFI_IPSEC_PROCESS_POLICY { /// /// Extended Sequence Number. Is this SA using extended sequence /// numbers. 64 bit counter is used if TRUE. /// BOOLEAN ExtSeqNum; /// /// A flag indicating whether overflow of the sequence number /// counter should generate an auditable event and prevent /// transmission of additional packets on the SA, or whether rollover /// is permitted. /// BOOLEAN SeqOverflow; /// /// Is this SA using stateful fragment checking. TRUE represents /// stateful fragment checking. /// BOOLEAN FragCheck; /// /// A time interval after which a SA must be replaced with a new SA /// (and new SPI) or terminated. /// EFI_IPSEC_SA_LIFETIME SaLifetime; /// /// IPsec mode: tunnel or transport. /// EFI_IPSEC_MODE Mode; /// /// Tunnel Option. TunnelOption is ignored if Mode is EfiIPsecTransport. /// EFI_IPSEC_TUNNEL_OPTION *TunnelOption; /// /// IPsec protocol: AH or ESP /// EFI_IPSEC_PROTOCOL_TYPE Proto; /// /// Cryptographic algorithm type used for authentication. /// UINT8 AuthAlgoId; /// /// Cryptographic algorithm type used for encryption. EncAlgo is /// NULL when IPsec protocol is AH. For ESP protocol, EncAlgo /// can also be used to describe the algorithm if a combined mode /// algorithm is used. /// UINT8 EncAlgoId; } EFI_IPSEC_PROCESS_POLICY; /// /// EFI_IPSEC_SA_ID /// A triplet to identify an SA, consisting of the following members. /// typedef struct _EFI_IPSEC_SA_ID { /// /// Security Parameter Index (aka SPI). An arbitrary 32-bit value /// that is used by a receiver to identity the SA to which an incoming /// package should be bound. /// UINT32 Spi; /// /// IPsec protocol: AH or ESP /// EFI_IPSEC_PROTOCOL_TYPE Proto; /// /// Destination IP address. /// EFI_IP_ADDRESS DestAddress; } EFI_IPSEC_SA_ID; #define MAX_PEERID_LEN 128 /// /// EFI_IPSEC_SPD_DATA /// typedef struct _EFI_IPSEC_SPD_DATA { /// /// A null-terminated ASCII name string which is used as a symbolic /// identifier for an IPsec Local or Remote address. /// UINT8 Name[MAX_PEERID_LEN]; /// /// Bit-mapped list describing Populate from Packet flags. When /// creating a SA, if PackageFlag bit is set to TRUE, instantiate /// the selector from the corresponding field in the package that /// triggered the creation of the SA, else from the value(s) in the /// corresponding SPD entry. The PackageFlag bit setting for /// corresponding selector field of EFI_IPSEC_SPD_SELECTOR: /// Bit 0: EFI_IPSEC_SPD_SELECTOR.LocalAddress /// Bit 1: EFI_IPSEC_SPD_SELECTOR.RemoteAddress /// Bit 2: /// EFI_IPSEC_SPD_SELECTOR.NextLayerProtocol /// Bit 3: EFI_IPSEC_SPD_SELECTOR.LocalPort /// Bit 4: EFI_IPSEC_SPD_SELECTOR.RemotePort /// Others: Reserved. /// UINT32 PackageFlag; /// /// The traffic direction of data gram. /// EFI_IPSEC_TRAFFIC_DIR TrafficDirection; /// /// Processing choices to indicate which action is required by this /// policy. /// EFI_IPSEC_ACTION Action; /// /// The policy and rule information for a SPD entry. /// EFI_IPSEC_PROCESS_POLICY *ProcessingPolicy; /// /// Specifies the actual number of entries in SaId list. /// UINTN SaIdCount; /// /// The SAD entry used for the traffic processing. The /// existed SAD entry links indicate this is the manual key case. /// EFI_IPSEC_SA_ID SaId[1]; } EFI_IPSEC_SPD_DATA; /// /// EFI_IPSEC_AH_ALGO_INFO /// The security algorithm selection for IPsec AH authentication. /// The required authentication algorithm is specified in RFC 4305. /// typedef struct _EFI_IPSEC_AH_ALGO_INFO { UINT8 AuthAlgoId; UINTN AuthKeyLength; VOID *AuthKey; } EFI_IPSEC_AH_ALGO_INFO; /// /// EFI_IPSEC_ESP_ALGO_INFO /// The security algorithm selection for IPsec ESP encryption and authentication. /// The required authentication algorithm is specified in RFC 4305. /// EncAlgoId fields can also specify an ESP combined mode algorithm /// (e.g. AES with CCM mode, specified in RFC 4309), which provides both /// confidentiality and authentication services. /// typedef struct _EFI_IPSEC_ESP_ALGO_INFO { UINT8 EncAlgoId; UINTN EncKeyLength; VOID *EncKey; UINT8 AuthAlgoId; UINTN AuthKeyLength; VOID *AuthKey; } EFI_IPSEC_ESP_ALGO_INFO; /// /// EFI_IPSEC_ALGO_INFO /// typedef union { EFI_IPSEC_AH_ALGO_INFO AhAlgoInfo; EFI_IPSEC_ESP_ALGO_INFO EspAlgoInfo; } EFI_IPSEC_ALGO_INFO; /// /// EFI_IPSEC_SA_DATA /// typedef struct _EFI_IPSEC_SA_DATA { /// /// IPsec mode: tunnel or transport. /// EFI_IPSEC_MODE Mode; /// /// Sequence Number Counter. A 64-bit counter used to generate the /// sequence number field in AH or ESP headers. /// UINT64 SNCount; /// /// Anti-Replay Window. A 64-bit counter and a bit-map used to /// determine whether an inbound AH or ESP packet is a replay. /// UINT8 AntiReplayWindows; /// /// AH/ESP cryptographic algorithm, key and parameters. /// EFI_IPSEC_ALGO_INFO AlgoInfo; /// /// Lifetime of this SA. /// EFI_IPSEC_SA_LIFETIME SaLifetime; /// /// Any observed path MTU and aging variables. The Path MTU /// processing is defined in section 8 of RFC 4301. /// UINT32 PathMTU; /// /// Link to one SPD entry. /// EFI_IPSEC_SPD_SELECTOR *SpdSelector; /// /// Indication of whether it's manually set or negotiated automatically. /// If ManualSet is FALSE, the corresponding SA entry is inserted through /// IKE protocol negotiation. /// BOOLEAN ManualSet; } EFI_IPSEC_SA_DATA; /// /// EFI_IPSEC_SA_DATA2 /// typedef struct _EFI_IPSEC_SA_DATA2 { /// /// IPsec mode: tunnel or transport /// EFI_IPSEC_MODE Mode; /// /// Sequence Number Counter. A 64-bit counter used to generate the sequence /// number field in AH or ESP headers. /// UINT64 SNCount; /// /// Anti-Replay Window. A 64-bit counter and a bit-map used to determine /// whether an inbound AH or ESP packet is a replay. /// UINT8 AntiReplayWindows; /// /// AH/ESP cryptographic algorithm, key and parameters. /// EFI_IPSEC_ALGO_INFO AlgoInfo; /// /// Lifetime of this SA. /// EFI_IPSEC_SA_LIFETIME SaLifetime; /// /// Any observed path MTU and aging variables. The Path MTU processing is /// defined in section 8 of RFC 4301. /// UINT32 PathMTU; /// /// Link to one SPD entry /// EFI_IPSEC_SPD_SELECTOR *SpdSelector; /// /// Indication of whether it's manually set or negotiated automatically. /// If ManualSet is FALSE, the corresponding SA entry is inserted through IKE /// protocol negotiation /// BOOLEAN ManualSet; /// /// The tunnel header IP source address. /// EFI_IP_ADDRESS TunnelSourceAddress; /// /// The tunnel header IP destination address. /// EFI_IP_ADDRESS TunnelDestinationAddress; } EFI_IPSEC_SA_DATA2; /// /// EFI_IPSEC_PAD_ID /// specifies the identifier for PAD entry, which is also used for SPD lookup. /// IpAddress Pointer to the IPv4 or IPv6 address range. /// typedef struct _EFI_IPSEC_PAD_ID { /// /// Flag to identify which type of PAD Id is used. /// BOOLEAN PeerIdValid; union { /// /// Pointer to the IPv4 or IPv6 address range. /// EFI_IP_ADDRESS_INFO IpAddress; /// /// Pointer to a null terminated ASCII string /// representing the symbolic names. A PeerId can be a DNS /// name, Distinguished Name, RFC 822 email address or Key ID /// (specified in section 4.4.3.1 of RFC 4301) /// UINT8 PeerId[MAX_PEERID_LEN]; } Id; } EFI_IPSEC_PAD_ID; /// /// EFI_IPSEC_CONFIG_SELECTOR /// describes the expected IPsec configuration data selector /// of type EFI_IPSEC_CONFIG_DATA_TYPE. /// typedef union { EFI_IPSEC_SPD_SELECTOR SpdSelector; EFI_IPSEC_SA_ID SaId; EFI_IPSEC_PAD_ID PadId; } EFI_IPSEC_CONFIG_SELECTOR; /// /// EFI_IPSEC_AUTH_PROTOCOL_TYPE /// defines the possible authentication protocol for IPsec /// security association management. /// typedef enum { EfiIPsecAuthProtocolIKEv1, EfiIPsecAuthProtocolIKEv2, EfiIPsecAuthProtocolMaximum } EFI_IPSEC_AUTH_PROTOCOL_TYPE; /// /// EFI_IPSEC_AUTH_METHOD /// typedef enum { /// /// Using Pre-shared Keys for manual security associations. /// EfiIPsecAuthMethodPreSharedSecret, /// /// IKE employs X.509 certificates for SA establishment. /// EfiIPsecAuthMethodCertificates, EfiIPsecAuthMethodMaximum } EFI_IPSEC_AUTH_METHOD; /// /// EFI_IPSEC_PAD_DATA /// typedef struct _EFI_IPSEC_PAD_DATA { /// /// Authentication Protocol for IPsec security association management. /// EFI_IPSEC_AUTH_PROTOCOL_TYPE AuthProtocol; /// /// Authentication method used. /// EFI_IPSEC_AUTH_METHOD AuthMethod; /// /// The IKE ID payload will be used as a symbolic name for SPD /// lookup if IkeIdFlag is TRUE. Otherwise, the remote IP /// address provided in traffic selector playloads will be used. /// BOOLEAN IkeIdFlag; /// /// The size of Authentication data buffer, in bytes. /// UINTN AuthDataSize; /// /// Buffer for Authentication data, (e.g., the pre-shared secret or the /// trust anchor relative to which the peer's certificate will be /// validated). /// VOID *AuthData; /// /// The size of RevocationData, in bytes /// UINTN RevocationDataSize; /// /// Pointer to CRL or OCSP data, if certificates are used for /// authentication method. /// VOID *RevocationData; } EFI_IPSEC_PAD_DATA; /** Set the security association, security policy and peer authorization configuration information for the EFI IPsec driver. This function is used to set the IPsec configuration information of type DataType for the EFI IPsec driver. The IPsec configuration data has a unique selector/identifier separately to identify a data entry. The selector structure depends on DataType's definition. Using SetData() with a Data of NULL causes the IPsec configuration data entry identified by DataType and Selector to be deleted. @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to be set. @param[in] Selector Pointer to an entry selector on operated configuration data specified by DataType. A NULL Selector causes the entire specified-type configuration information to be flushed. @param[in] Data The data buffer to be set. The structure of the data buffer is associated with the DataType. @param[in] InsertBefore Pointer to one entry selector which describes the expected position the new data entry will be added. If InsertBefore is NULL, the new entry will be appended the end of database. @retval EFI_SUCCESS The specified configuration entry data is set successfully. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. @retval EFI_UNSUPPORTED The specified DataType is not supported. @retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_CONFIG_SET_DATA)( IN EFI_IPSEC_CONFIG_PROTOCOL *This, IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN EFI_IPSEC_CONFIG_SELECTOR *Selector, IN VOID *Data, IN EFI_IPSEC_CONFIG_SELECTOR *InsertBefore OPTIONAL ); /** Return the configuration value for the EFI IPsec driver. This function lookup the data entry from IPsec database or IKEv2 configuration information. The expected data type and unique identification are described in DataType and Selector parameters. @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to retrieve. @param[in] Selector Pointer to an entry selector which is an identifier of the IPsec configuration data entry. @param[in, out] DataSize On output the size of data returned in Data. @param[out] Data The buffer to return the contents of the IPsec configuration data. The type of the data buffer is associated with the DataType. @retval EFI_SUCCESS The specified configuration data is got successfully. @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: - This is NULL. - Selector is NULL. - DataSize is NULL. - Data is NULL and *DataSize is not zero @retval EFI_NOT_FOUND The configuration data specified by Selector is not found. @retval EFI_UNSUPPORTED The specified DataType is not supported. @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been updated with the size needed to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_CONFIG_GET_DATA)( IN EFI_IPSEC_CONFIG_PROTOCOL *This, IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN EFI_IPSEC_CONFIG_SELECTOR *Selector, IN OUT UINTN *DataSize, OUT VOID *Data ); /** Enumerates the current selector for IPsec configuration data entry. This function is called multiple times to retrieve the entry Selector in IPsec configuration database. On each call to GetNextSelector(), the next entry Selector are retrieved into the output interface. If the entire IPsec configuration database has been iterated, the error EFI_NOT_FOUND is returned. If the Selector buffer is too small for the next Selector copy, an EFI_BUFFER_TOO_SMALL error is returned, and SelectorSize is updated to reflect the size of buffer needed. On the initial call to GetNextSelector() to start the IPsec configuration database search, a pointer to the buffer with all zero value is passed in Selector. Calls to SetData() between calls to GetNextSelector may produce unpredictable results. @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance. @param[in] DataType The type of IPsec configuration data to retrieve. @param[in, out] SelectorSize The size of the Selector buffer. @param[in, out] Selector On input, supplies the pointer to last Selector that was returned by GetNextSelector(). On output, returns one copy of the current entry Selector of a given DataType. @retval EFI_SUCCESS The specified configuration data is got successfully. @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: - This is NULL. - SelectorSize is NULL. - Selector is NULL. @retval EFI_NOT_FOUND The next configuration data entry was not found. @retval EFI_UNSUPPORTED The specified DataType is not supported. @retval EFI_BUFFER_TOO_SMALL The SelectorSize is too small for the result. This parameter has been updated with the size needed to complete the search request. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_CONFIG_GET_NEXT_SELECTOR)( IN EFI_IPSEC_CONFIG_PROTOCOL *This, IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN OUT UINTN *SelectorSize, IN OUT EFI_IPSEC_CONFIG_SELECTOR *Selector ); /** Register an event that is to be signaled whenever a configuration process on the specified IPsec configuration information is done. This function registers an event that is to be signaled whenever a configuration process on the specified IPsec configuration data is done (e.g. IPsec security policy database configuration is ready). An event can be registered for different DataType simultaneously and the caller is responsible for determining which type of configuration data causes the signaling of the event in such case. @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance. @param[in] DataType The type of data to be registered the event for. @param[in] Event The event to be registered. @retval EFI_SUCCESS The event is registered successfully. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_ACCESS_DENIED The Event is already registered for the DataType. @retval EFI_UNSUPPORTED The notify registration unsupported or the specified DataType is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_CONFIG_REGISTER_NOTIFY)( IN EFI_IPSEC_CONFIG_PROTOCOL *This, IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN EFI_EVENT Event ); /** Remove the specified event that is previously registered on the specified IPsec configuration data. This function removes a previously registered event for the specified configuration data. @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance. @param[in] DataType The configuration data type to remove the registered event for. @param[in] Event The event to be unregistered. @retval EFI_SUCCESS The event is removed successfully. @retval EFI_NOT_FOUND The Event specified by DataType could not be found in the database. @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. @retval EFI_UNSUPPORTED The notify registration unsupported or the specified DataType is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_IPSEC_CONFIG_UNREGISTER_NOTIFY)( IN EFI_IPSEC_CONFIG_PROTOCOL *This, IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN EFI_EVENT Event ); /// /// EFI_IPSEC_CONFIG_PROTOCOL /// provides the ability to set and lookup the IPsec SAD (Security Association Database), /// SPD (Security Policy Database) data entry and configure the security association /// management protocol such as IKEv2. This protocol is used as the central /// repository of any policy-specific configuration for EFI IPsec driver. /// EFI_IPSEC_CONFIG_PROTOCOL can be bound to both IPv4 and IPv6 stack. User can use this /// protocol for IPsec configuration in both IPv4 and IPv6 environment. /// struct _EFI_IPSEC_CONFIG_PROTOCOL { EFI_IPSEC_CONFIG_SET_DATA SetData; EFI_IPSEC_CONFIG_GET_DATA GetData; EFI_IPSEC_CONFIG_GET_NEXT_SELECTOR GetNextSelector; EFI_IPSEC_CONFIG_REGISTER_NOTIFY RegisterDataNotify; EFI_IPSEC_CONFIG_UNREGISTER_NOTIFY UnregisterDataNotify; }; extern EFI_GUID gEfiIpSecConfigProtocolGuid; #endif /** @file EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers on the platform's ISA Bus. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ISA_ACPI_H_ #define __ISA_ACPI_H_ /// /// Global ID for the EFI ISA ACPI Protocol. /// #define EFI_ISA_ACPI_PROTOCOL_GUID \ { \ 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \ } /// /// Forward declaration fo the EFI ISA ACPI Protocol /// typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL; /// /// ISA ACPI Protocol interrupt resource attributes. /// #define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///< Edge triggered interrupt on a rising edge. #define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///< Edge triggered interrupt on a falling edge. #define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///< Level sensitive interrupt active high. #define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///< Level sensitive interrupt active low. /// /// ISA ACPI Protocol DMA resource attributes. /// #define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask of supported DMA speed attributes. #define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA controller supports compatibility mode DMA transfers. #define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA controller supports type A DMA transfers. #define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA controller supports type B DMA transfers. #define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA controller supports type F DMA transfers. #define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA controller increments DMA address by bytes (8-bit). #define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA controller increments DMA address by words (16-bit). #define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA controller is a DMA bus master. #define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA controller only supports 8-bit DMA transfers. #define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40 ///< ISA controller both 8-bit and 16-bit DMA transfers. #define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA controller only supports 16-bit DMA transfers. /// /// ISA ACPI Protocol MMIO resource attributes /// #define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask of supported ISA memory width attributes. #define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA MMIO region only supports 8-bit access. #define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA MMIO region only supports 16-bit access. #define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///< ISA MMIO region supports both 8-bit and 16-bit access. #define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO region supports write transactions. #define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO region supports being cached. #define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA MMIO region may be shadowed. #define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA MMIO region is an expansion ROM. /// /// ISA ACPI Protocol I/O resource attributes /// #define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA controllers uses a 10-bit address decoder for I/O cycles. #define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA controllers uses a 16-bit address decoder for I/O cycles. /// /// EFI ISA ACPI resource type /// typedef enum { EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list. EfiIsaAcpiResourceIo, ///< ISA I/O port resource range. EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range. EfiIsaAcpiResourceDma, ///< ISA DMA resource. EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource. } EFI_ISA_ACPI_RESOURCE_TYPE; /// /// EFI ISA ACPI generic resource structure /// typedef struct { EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O, MMIO, DMA, Interrupt). UINT32 Attribute; ///< Bit mask of attributes associated with this resource. See EFI_ISA_ACPI_xxx macros for valid combinations. UINT32 StartRange; ///< The start of the resource range. UINT32 EndRange; ///< The end of the resource range. } EFI_ISA_ACPI_RESOURCE; /// /// EFI ISA ACPI resource device identifier /// typedef struct { UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA controller. Matchs ACPI DSDT contents. UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA controller. Matches ACPI DSDT contents. } EFI_ISA_ACPI_DEVICE_ID; /// /// EFI ISA ACPI resource list /// typedef struct { EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with an ISA controller. EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of resources associated with an ISA controller. } EFI_ISA_ACPI_RESOURCE_LIST; /** Enumerates the ISA controllers on an ISA bus. This service allows all the ISA controllers on an ISA bus to be enumerated. If Device is a pointer to a NULL value, then the first ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer to a value that was returned on a prior call to DeviceEnumerate(), then the next ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer to the last ISA controller on the ISA bus, then EFI_NOT_FOUND is returned. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[out] Device The pointer to an ISA controller named by ACPI HID/UID. @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned. @retval EFI_NOT_FOUND No device found. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)( IN EFI_ISA_ACPI_PROTOCOL *This, OUT EFI_ISA_ACPI_DEVICE_ID **Device ); /** Sets the power state of an ISA controller. This services sets the power state of the ISA controller specified by Device to the power state specified by OnOff. TRUE denotes on, FALSE denotes off. If the power state is successfully set on the ISA Controller, then EFI_SUCCESS is returned. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. @param[in] OnOff TRUE denotes on, FALSE denotes off. @retval EFI_SUCCESS Successfully set the power state of the ISA controller. @retval Other The ISA controller could not be placed in the requested power state. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN BOOLEAN OnOff ); /** Retrieves the current set of resources associated with an ISA controller. Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently assigned to the ISA controller specified by Device. These resources are returned in ResourceList. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. @param[out] ResourceList The pointer to the current resource list for Device. @retval EFI_SUCCESS Successfully retrieved the current resource list. @retval EFI_NOT_FOUND The resource list could not be retrieved. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList ); /** Retrieves the set of possible resources that may be assigned to an ISA controller with SetResource(). Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for the ISA controller specified by Device. The sets are returned in ResourceList. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. @param[out] ResourceList The pointer to the returned list of resource lists. @retval EFI_UNSUPPORTED This service is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList ); /** Assigns resources to an ISA controller. Assigns the I/O, MMIO, DMA, and interrupt resources specified by ResourceList to the ISA controller specified by Device. ResourceList must match a resource list returned by GetPosResource() for the same ISA controller. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. @param[in] ResourceList The pointer to a resources list that must be one of the resource lists returned by GetPosResource() for the ISA controller specified by Device. @retval EFI_SUCCESS Successfully set resources on the ISA controller. @retval Other The resources could not be set for the ISA controller. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList ); /** Enables or disables an ISA controller. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to the ISA controller to enable/disable. @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the ISA controller. @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller. @retval Other The ISA controller could not be placed in the requested state. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN BOOLEAN Enable ); /** Initializes an ISA controller, so that it can be used. This service must be called before SetResource(), EnableDevice(), or SetPower() will behave as expected. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @param[in] Device The pointer to an ISA controller named by ACPI HID/UID. @retval EFI_SUCCESS Successfully initialized an ISA controller. @retval Other The ISA controller could not be initialized. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device ); /** Initializes all the HW states required for the ISA controllers on the ISA bus to be enumerated and managed by the rest of the services in this prorotol. This service must be called before any of the other services in this protocol will function as expected. @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance. @retval EFI_SUCCESS Successfully initialized all required hardware states. @retval Other The ISA interface could not be initialized. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)( IN EFI_ISA_ACPI_PROTOCOL *This ); /// /// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and manage /// ISA controllers on an ISA bus. These services include the ability to initialize, /// enable, disable, and manage the power state of ISA controllers. It also /// includes services to query current resources, query possible resources, /// and assign resources to an ISA controller. /// struct _EFI_ISA_ACPI_PROTOCOL { EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate; EFI_ISA_ACPI_SET_DEVICE_POWER SetPower; EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource; EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource; EFI_ISA_ACPI_SET_RESOURCE SetResource; EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice; EFI_ISA_ACPI_INIT_DEVICE InitDevice; EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit; }; extern EFI_GUID gEfiIsaAcpiProtocolGuid; #endif /** @file ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA operations on the ISA controllers they manage. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _EFI_ISA_IO_H_ #define _EFI_ISA_IO_H_ #include /// /// Global ID for the EFI_ISA_IO_PROTOCOL /// #define EFI_ISA_IO_PROTOCOL_GUID \ { \ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } /// /// Forward declaration for the EFI_ISA_IO_PROTOCOL. /// typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL; /// /// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations. /// typedef enum { EfiIsaIoWidthUint8 = 0, ///< 8-bit operation. EfiIsaIoWidthUint16, ///< 16-bit operation. EfiIsaIoWidthUint32, ///< 32-bit operation EfiIsaIoWidthReserved, EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation. EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation. EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation. EfiIsaIoWidthFifoReserved, EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation. EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation. EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation. EfiIsaIoWidthFillReserved, EfiIsaIoWidthMaximum } EFI_ISA_IO_PROTOCOL_WIDTH; /// /// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations. /// #define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///< Map a memory range so write are combined. #define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a memory range so all read and write accesses are cached. #define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range. /// /// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests /// #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001 ///< Set the speed of the DMA transfer in compatible mode. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not supported. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not supported. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not supported. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///< Request 8-bit DMA transfers. Only available on channels 0..3. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///< Request 16-bit DMA transfers. Only available on channels 4..7. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///< Request a single DMA transfer. #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080 ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of Process). #define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///< Automatically reload base and count at the end of the DMA transfer. /// /// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests. /// typedef enum { /// /// A read operation from system memory by a bus master. /// EfiIsaIoOperationBusMasterRead, /// /// A write operation to system memory by a bus master. /// EfiIsaIoOperationBusMasterWrite, /// /// Provides both read and write access to system memory by both the processor /// and a bus master. The buffer is coherent from both the processor's and the /// bus master's point of view. /// EfiIsaIoOperationBusMasterCommonBuffer, /// /// A read operation from system memory by a slave device. /// EfiIsaIoOperationSlaveRead, /// /// A write operation to system memory by a slave master. /// EfiIsaIoOperationSlaveWrite, EfiIsaIoOperationMaximum } EFI_ISA_IO_PROTOCOL_OPERATION; /** Performs ISA I/O and MMIO Read/Write Cycles @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Width Specifies the width of the I/O or MMIO operation. @param[in] Offset The offset into the ISA I/O or MMIO space to start the operation. @param[in] Count The number of I/O or MMIO operations to perform. @param[in, out] Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. @retval EFI_SUCCESS The data was successfully read from or written to the device. @retval EFI_UNSUPPORTED The Offset is not valid for this device. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)( IN EFI_ISA_IO_PROTOCOL *This, IN EFI_ISA_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer ); /// /// Structure of functions for accessing ISA I/O and MMIO space. /// typedef struct { /// /// Read from ISA I/O or MMIO space. /// EFI_ISA_IO_PROTOCOL_IO_MEM Read; /// /// Write to ISA I/O or MMIO space. /// EFI_ISA_IO_PROTOCOL_IO_MEM Write; } EFI_ISA_IO_PROTOCOL_ACCESS; /** Copies data from one region of ISA MMIO space to another region of ISA MMIO space. @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Width Specifies the width of the MMIO copy operation. @param[in] DestOffset The offset of the destination in ISA MMIO space. @param[in] SrcOffset The offset of the source in ISA MMIO space. @param[in] Count The number tranfers to perform for this copy operation. @retval EFI_SUCCESS The data was copied successfully. @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for this device. @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)( IN EFI_ISA_IO_PROTOCOL *This, IN EFI_ISA_IO_PROTOCOL_WIDTH Width, IN UINT32 DestOffset, IN UINT32 SrcOffset, IN UINTN Count ); /** Maps a memory region for DMA. This function returns the device-specific addresses required to access system memory. This function is used to map system memory for ISA DMA operations. All ISA DMA operations must be performed through their mapped addresses, and such mappings must be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is completed. If the DMA operation is a single read or write data transfer through an ISA bus master, then EfiIsaIoOperationBusMasterRead or EfiIsaIoOperationBusMasterWrite is used and the range is unmapped to complete the operation. If the DMA operation is a single read or write data transfer through an ISA slave controller, then EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the range is unmapped to complete the operation. If performing a DMA read operation, all the data must be present in system memory before the Map() is performed. Similarly, if performing a DMA write operation, the data must not be accessed in system memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master operations that require both read and write access or require multiple host device interactions within the same mapped region must use EfiIsaIoOperationBusMasterCommonBuffer. However, only memory allocated via the EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface is guaranteed to be able to be mapped for this operation type. In all mapping requests the NumberOfBytes returned may be less than originally requested. It is the caller's responsibility to make additional requests to complete the entire transfer. @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Operation Indicates the type of DMA (slave or bus master), and if the DMA operation is going to read or write to system memory. @param[in] ChannelNumber The slave channel number to use for this DMA operation. If Operation and ChannelAttributes shows that this device performs bus mastering DMA, then this field is ignored. The legal range for this field is 0..7. @param[in] ChannelAttributes A bitmask of the attributes used to configure the slave DMA channel for this DMA operation. See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the legal bit combinations. @param[in] HostAddress The system memory address to map to the device. @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped. @param[out] DeviceAddress The resulting map address for the bus master device to use to access the hosts HostAddress. @param[out] Mapping A returned value that must be passed to into EFI_ISA_IO_PROTOCOL.Unmap() to free all the the resources associated with this map request. @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_INVALID_PARAMETER The Operation is undefined. @retval EFI_INVALID_PARAMETER The HostAddress is undefined. @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)( IN EFI_ISA_IO_PROTOCOL *This, IN EFI_ISA_IO_PROTOCOL_OPERATION Operation, IN UINT8 ChannelNumber OPTIONAL, IN UINT32 ChannelAttributes, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ); /** Unmaps a memory region that was previously mapped with EFI_ISA_IO_PROTOCOL.Map(). The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any corresponding resources are released. If the operation was EfiIsaIoOperationSlaveWrite or EfiIsaIoOperationBusMasterWrite, the data is committed to system memory. Any resources used for the mapping are freed. @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Mapping The mapping value returned from EFI_ISA_IO_PROTOCOL.Map(). @retval EFI_SUCCESS The memory region was unmapped. @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)( IN EFI_ISA_IO_PROTOCOL *This, IN VOID *Mapping ); /** Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer mapping. @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Type The type allocation to perform. @param[in] MemoryType The type of memory to allocate. @param[in] Pages The number of pages to allocate. @param[out] HostAddress A pointer to store the base address of the allocated range. @param[in] Attributes The requested bit mask of attributes for the allocated range. @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_INVALID_PARAMETER Type is invalid. @retval EFI_INVALID_PARAMETER MemoryType is invalid. @retval EFI_INVALID_PARAMETER HostAddress is NULL. @retval EFI_UNSUPPORTED Attributes is unsupported. @retval EFI_UNSUPPORTED The memory range specified by HostAddress, Pages, and Type is not available for common buffer use. @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)( IN EFI_ISA_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes ); /** Frees a common buffer that was allocated with EFI_ISA_IO_PROTOCOL.AllocateBuffer(). @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @param[in] Pages The number of pages to free from the previously allocated common buffer. @param[in] HostAddress The base address of the previously allocated common buffer. @retval EFI_SUCCESS The requested memory pages were freed. @retval EFI_INVALID_PARAMETER The memory was not allocated with EFI_ISA_IO.AllocateBufer(). **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)( IN EFI_ISA_IO_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress ); /** Flushes a DMA buffer, which forces all DMA posted write transactions to complete. @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. @retval EFI_SUCCESS The DMA buffers were flushed. @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)( IN EFI_ISA_IO_PROTOCOL *This ); /// /// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA interfaces /// used to abstract accesses to ISA controllers. There is one EFI_ISA_IO_PROTOCOL /// instance for each ISA controller on a ISA bus. A device driver that wishes /// to manage an ISA controller in a system will have to retrieve the /// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller. /// struct _EFI_ISA_IO_PROTOCOL { EFI_ISA_IO_PROTOCOL_ACCESS Mem; EFI_ISA_IO_PROTOCOL_ACCESS Io; EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem; EFI_ISA_IO_PROTOCOL_MAP Map; EFI_ISA_IO_PROTOCOL_UNMAP Unmap; EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer; EFI_ISA_IO_PROTOCOL_FLUSH Flush; /// /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL. /// EFI_ISA_ACPI_RESOURCE_LIST *ResourceList; /// /// The size, in bytes, of the ROM image. /// UINT32 RomSize; /// /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is responsible /// for allocating memory for the ROM image, and copying the contents of the ROM to memory /// during ISA Bus initialization. /// VOID *RomImage; }; extern EFI_GUID gEfiIsaIoProtocolGuid; #endif /** @file The Key Management Service (KMS) protocol as defined in the UEFI 2.3.1 specification is to provides services to generate, store, retrieve, and manage cryptographic keys. The intention is to specify a simple generic protocol that could be used for many implementations. A driver implementing the protocol may need to provide basic key service that consists of a key store and cryptographic key generation capability. It may connect to an external key server over the network, or to a Hardware Security Module (HSM) attached to the system it runs on, or anything else that is capable of providing the key management service. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __KMS_H__ #define __KMS_H__ #define EFI_KMS_PROTOCOL_GUID \ { \ 0xEC3A978D, 0x7C4E, 0x48FA, {0x9A, 0xBE, 0x6A, 0xD9, 0x1C, 0xC8, 0xF8, 0x11 } \ } typedef struct _EFI_KMS_PROTOCOL EFI_KMS_PROTOCOL; // // Where appropriate, EFI_KMS_DATA_TYPE values may be combined using a bitwise 'OR' // operation to indicate support for multiple data types. // #define EFI_KMS_DATA_TYPE_NONE 0 #define EFI_KMS_DATA_TYPE_BINARY 1 #define EFI_KMS_DATA_TYPE_ASCII 2 #define EFI_KMS_DATA_TYPE_UNICODE 4 #define EFI_KMS_DATA_TYPE_UTF8 8 // // The key formats recognized by the KMS protocol are defined by an EFI_GUID which specifies // a (key-algorithm, key-size) pair. The names of these GUIDs are in the format // EFI_KMS_KEY_(key-algorithm)_(key-size)_GUID, where the key-size is expressed in bits. // The key formats recognized fall into three categories, generic (no algorithm), hash algorithms, // and encrypted algorithms. // /// /// The following GUIDs define formats that contain generic key data of a specific size in bits, /// but which is not associated with any specific key algorithm(s). ///@{ #define EFI_KMS_FORMAT_GENERIC_128_GUID \ { \ 0xec8a3d69, 0x6ddf, 0x4108, {0x94, 0x76, 0x73, 0x37, 0xfc, 0x52, 0x21, 0x36 } \ } #define EFI_KMS_FORMAT_GENERIC_160_GUID \ { \ 0xa3b3e6f8, 0xefca, 0x4bc1, {0x88, 0xfb, 0xcb, 0x87, 0x33, 0x9b, 0x25, 0x79 } \ } #define EFI_KMS_FORMAT_GENERIC_256_GUID \ { \ 0x70f64793, 0xc323, 0x4261, {0xac, 0x2c, 0xd8, 0x76, 0xf2, 0x7c, 0x53, 0x45 } \ } #define EFI_KMS_FORMAT_GENERIC_512_GUID \ { \ 0x978fe043, 0xd7af, 0x422e, {0x8a, 0x92, 0x2b, 0x48, 0xe4, 0x63, 0xbd, 0xe6 } \ } #define EFI_KMS_FORMAT_GENERIC_1024_GUID \ { \ 0x43be0b44, 0x874b, 0x4ead, {0xb0, 0x9c, 0x24, 0x1a, 0x4f, 0xbd, 0x7e, 0xb3 } \ } #define EFI_KMS_FORMAT_GENERIC_2048_GUID \ { \ 0x40093f23, 0x630c, 0x4626, {0x9c, 0x48, 0x40, 0x37, 0x3b, 0x19, 0xcb, 0xbe } \ } #define EFI_KMS_FORMAT_GENERIC_3072_GUID \ { \ 0xb9237513, 0x6c44, 0x4411, {0xa9, 0x90, 0x21, 0xe5, 0x56, 0xe0, 0x5a, 0xde } \ } #define EFI_KMS_FORMAT_GENERIC_DYNAMIC_GUID \ { \ 0x2156e996, 0x66de, 0x4b27, {0x9c, 0xc9, 0xb0, 0x9f, 0xac, 0x4d, 0x2, 0xbe } \ } ///@} /// /// These GUIDS define key data formats that contain data generated by basic hash algorithms /// with no cryptographic properties. ///@{ #define EFI_KMS_FORMAT_MD2_128_GUID \ { \ 0x78be11c4, 0xee44, 0x4a22, {0x9f, 0x05, 0x03, 0x85, 0x2e, 0xc5, 0xc9, 0x78 } \ } #define EFI_KMS_FORMAT_MDC2_128_GUID \ { \ 0xf7ad60f8, 0xefa8, 0x44a3, {0x91, 0x13, 0x23, 0x1f, 0x39, 0x9e, 0xb4, 0xc7 } \ } #define EFI_KMS_FORMAT_MD4_128_GUID \ { \ 0xd1c17aa1, 0xcac5, 0x400f, {0xbe, 0x17, 0xe2, 0xa2, 0xae, 0x06, 0x67, 0x7c } \ } #define EFI_KMS_FORMAT_MDC4_128_GUID \ { \ 0x3fa4f847, 0xd8eb, 0x4df4, {0xbd, 0x49, 0x10, 0x3a, 0x0a, 0x84, 0x7b, 0xbc } \ } #define EFI_KMS_FORMAT_MD5_128_GUID \ { \ 0xdcbc3662, 0x9cda, 0x4b52, {0xa0, 0x4c, 0x82, 0xeb, 0x1d, 0x23, 0x48, 0xc7 } \ } #define EFI_KMS_FORMAT_MD5SHA_128_GUID \ { \ 0x1c178237, 0x6897, 0x459e, {0x9d, 0x36, 0x67, 0xce, 0x8e, 0xf9, 0x4f, 0x76 } \ } #define EFI_KMS_FORMAT_SHA1_160_GUID \ { \ 0x453c5e5a, 0x482d, 0x43f0, {0x87, 0xc9, 0x59, 0x41, 0xf3, 0xa3, 0x8a, 0xc2 } \ } #define EFI_KMS_FORMAT_SHA256_256_GUID \ { \ 0x6bb4f5cd, 0x8022, 0x448d, {0xbc, 0x6d, 0x77, 0x1b, 0xae, 0x93, 0x5f, 0xc6 } \ } #define EFI_KMS_FORMAT_SHA512_512_GUID \ { \ 0x2f240e12, 0xe14d, 0x475c, {0x83, 0xb0, 0xef, 0xff, 0x22, 0xd7, 0x7b, 0xe7 } \ } ///@} /// /// These GUIDs define key data formats that contain data generated by cryptographic key algorithms. /// There may or may not be a separate data hashing algorithm associated with the key algorithm. ///@{ #define EFI_KMS_FORMAT_AESXTS_128_GUID \ { \ 0x4776e33f, 0xdb47, 0x479a, {0xa2, 0x5f, 0xa1, 0xcd, 0x0a, 0xfa, 0xb3, 0x8b } \ } #define EFI_KMS_FORMAT_AESXTS_256_GUID \ { \ 0xdc7e8613, 0xc4bb, 0x4db0, {0x84, 0x62, 0x13, 0x51, 0x13, 0x57, 0xab, 0xe2 } \ } #define EFI_KMS_FORMAT_AESCBC_128_GUID \ { \ 0xa0e8ee6a, 0x0e92, 0x44d4, {0x86, 0x1b, 0x0e, 0xaa, 0x4a, 0xca, 0x44, 0xa2 } \ } #define EFI_KMS_FORMAT_AESCBC_256_GUID \ { \ 0xd7e69789, 0x1f68, 0x45e8, {0x96, 0xef, 0x3b, 0x64, 0x07, 0xa5, 0xb2, 0xdc } \ } #define EFI_KMS_FORMAT_RSASHA1_1024_GUID \ { \ 0x56417bed, 0x6bbe, 0x4882, {0x86, 0xa0, 0x3a, 0xe8, 0xbb, 0x17, 0xf8, 0xf9 } \ } #define EFI_KMS_FORMAT_RSASHA1_2048_GUID \ { \ 0xf66447d4, 0x75a6, 0x463e, {0xa8, 0x19, 0x07, 0x7f, 0x2d, 0xda, 0x05, 0xe9 } \ } #define EFI_KMS_FORMAT_RSASHA256_2048_GUID \ { \ 0xa477af13, 0x877d, 0x4060, {0xba, 0xa1, 0x25, 0xd1, 0xbe, 0xa0, 0x8a, 0xd3 } \ } #define EFI_KMS_FORMAT_RSASHA256_3072_GUID \ { \ 0x4e1356c2, 0xeed, 0x463f, {0x81, 0x47, 0x99, 0x33, 0xab, 0xdb, 0xc7, 0xd5 } \ } ///@} #define EFI_KMS_ATTRIBUTE_TYPE_NONE 0x00 #define EFI_KMS_ATTRIBUTE_TYPE_INTEGER 0x01 #define EFI_KMS_ATTRIBUTE_TYPE_LONG_INTEGER 0x02 #define EFI_KMS_ATTRIBUTE_TYPE_BIG_INTEGER 0x03 #define EFI_KMS_ATTRIBUTE_TYPE_ENUMERATION 0x04 #define EFI_KMS_ATTRIBUTE_TYPE_BOOLEAN 0x05 #define EFI_KMS_ATTRIBUTE_TYPE_BYTE_STRING 0x06 #define EFI_KMS_ATTRIBUTE_TYPE_TEXT_STRING 0x07 #define EFI_KMS_ATTRIBUTE_TYPE_DATE_TIME 0x08 #define EFI_KMS_ATTRIBUTE_TYPE_INTERVAL 0x09 #define EFI_KMS_ATTRIBUTE_TYPE_STRUCTURE 0x0A #define EFI_KMS_ATTRIBUTE_TYPE_DYNAMIC 0x0B typedef struct { /// /// Length in bytes of the KeyData. /// UINT32 KeySize; /// /// The data of the key. /// UINT8 KeyData[1]; } EFI_KMS_FORMAT_GENERIC_DYNAMIC; typedef struct { /// /// The size in bytes for the client identifier. /// UINT16 ClientIdSize; /// /// Pointer to a valid client identifier. /// VOID *ClientId; /// /// The client name string type used by this client. The string type set here must be one of /// the string types reported in the ClientNameStringTypes field of the KMS protocol. If the /// KMS does not support client names, this field should be set to EFI_KMS_DATA_TYPE_NONE. /// UINT8 ClientNameType; /// /// The size in characters for the client name. This field will be ignored if /// ClientNameStringType is set to EFI_KMS_DATA_TYPE_NONE. Otherwise, it must contain /// number of characters contained in the ClientName field. /// UINT8 ClientNameCount; /// /// Pointer to a client name. This field will be ignored if ClientNameStringType is set to /// EFI_KMS_DATA_TYPE_NONE. Otherwise, it must point to a valid string of the specified type. /// VOID *ClientName; } EFI_KMS_CLIENT_INFO; typedef struct { /// /// The size of the KeyIdentifier field in bytes. This field is limited to the range 0 to 255. /// UINT8 KeyIdentifierSize; /// /// Pointer to an array of KeyIdentifierType elements. /// VOID *KeyIdentifier; /// /// An EFI_GUID which specifies the algorithm and key value size for this key. /// EFI_GUID KeyFormat; /// /// Pointer to a key value for a key specified by the KeyFormat field. A NULL value for this /// field indicates that no key is available. /// VOID *KeyValue; /// /// Specifies the results of KMS operations performed with this descriptor. This field is used /// to indicate the status of individual operations when a KMS function is called with multiple /// EFI_KMS_KEY_DESCRIPTOR structures. /// KeyStatus codes returned for the individual key requests are: /// EFI_SUCCESS Successfully processed this key. /// EFI_WARN_STALE_DATA Successfully processed this key, however, the key's parameters /// exceed internal policies/limits and should be replaced. /// EFI_COMPROMISED_DATA Successfully processed this key, but the key may have been /// compromised and must be replaced. /// EFI_UNSUPPORTED Key format is not supported by the service. /// EFI_OUT_OF_RESOURCES Could not allocate resources for the key processing. /// EFI_TIMEOUT Timed out waiting for device or key server. /// EFI_DEVICE_ERROR Device or key server error. /// EFI_INVALID_PARAMETER KeyFormat is invalid. /// EFI_NOT_FOUND The key does not exist on the KMS. /// EFI_STATUS KeyStatus; } EFI_KMS_KEY_DESCRIPTOR; typedef struct { /// /// Part of a tag-type-length triplet that identifies the KeyAttributeData formatting. The /// definition of the value is outside the scope of this standard and may be defined by the KMS. /// UINT16 Tag; /// /// Part of a tag-type-length triplet that identifies the KeyAttributeData formatting. The /// definition of the value is outside the scope of this standard and may be defined by the KMS. /// UINT16 Type; /// /// Length in bytes of the KeyAttributeData. /// UINT32 Length; /// /// An array of bytes to hold the attribute data associated with the KeyAttributeIdentifier. /// UINT8 KeyAttributeData[1]; } EFI_KMS_DYNAMIC_FIELD; typedef struct { /// /// The number of members in the EFI_KMS_DYNAMIC_ATTRIBUTE structure. /// UINT32 FieldCount; /// /// An array of EFI_KMS_DYNAMIC_FIELD structures. /// EFI_KMS_DYNAMIC_FIELD Field[1]; } EFI_KMS_DYNAMIC_ATTRIBUTE; typedef struct { /// /// The data type used for the KeyAttributeIdentifier field. Values for this field are defined /// by the EFI_KMS_DATA_TYPE constants, except that EFI_KMS_DATA_TYPE_BINARY is not /// valid for this field. /// UINT8 KeyAttributeIdentifierType; /// /// The length of the KeyAttributeIdentifier field in units defined by KeyAttributeIdentifierType /// field. This field is limited to the range 0 to 255. /// UINT8 KeyAttributeIdentifierCount; /// /// Pointer to an array of KeyAttributeIdentifierType elements. For string types, there must /// not be a null-termination element at the end of the array. /// VOID *KeyAttributeIdentifier; /// /// The instance number of this attribute. If there is only one instance, the value is set to /// one. If this value is set to 0xFFFF (all binary 1's) then this field should be ignored if an /// output or treated as a wild card matching any value if it is an input. If the attribute is /// stored with this field, it will match any attribute request regardless of the setting of the /// field in the request. If set to 0xFFFF in the request, it will match any attribute with the /// same KeyAttributeIdentifier. /// UINT16 KeyAttributeInstance; /// /// The data type of the KeyAttributeValue (e.g. struct, bool, etc.). See the list of /// KeyAttributeType definitions. /// UINT16 KeyAttributeType; /// /// The size in bytes of the KeyAttribute field. A value of zero for this field indicates that no /// key attribute value is available. /// UINT16 KeyAttributeValueSize; /// /// Pointer to a key attribute value for the attribute specified by the KeyAttributeIdentifier /// field. If the KeyAttributeValueSize field is zero, then this field must be NULL. /// VOID *KeyAttributeValue; /// /// KeyAttributeStatusSpecifies the results of KMS operations performed with this attribute. /// This field is used to indicate the status of individual operations when a KMS function is /// called with multiple EFI_KMS_KEY_ATTRIBUTE structures. /// KeyAttributeStatus codes returned for the individual key attribute requests are: /// EFI_SUCCESS Successfully processed this request. /// EFI_WARN_STALE_DATA Successfully processed this request, however, the key's /// parameters exceed internal policies/limits and should be replaced. /// EFI_COMPROMISED_DATA Successfully processed this request, but the key may have been /// compromised and must be replaced. /// EFI_UNSUPPORTED Key attribute format is not supported by the service. /// EFI_OUT_OF_RESOURCES Could not allocate resources for the request processing. /// EFI_TIMEOUT Timed out waiting for device or key server. /// EFI_DEVICE_ERROR Device or key server error. /// EFI_INVALID_PARAMETER A field in the EFI_KMS_KEY_ATTRIBUTE structure is invalid. /// EFI_NOT_FOUND The key attribute does not exist on the KMS. /// EFI_STATUS KeyAttributeStatus; } EFI_KMS_KEY_ATTRIBUTE; /** Get the current status of the key management service. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @retval EFI_SUCCESS The KMS is ready for use. @retval EFI_NOT_READY No connection to the KMS is available. @retval EFI_NO_MAPPING No valid connection configuration exists for the KMS. @retval EFI_NO_RESPONSE No response was received from the KMS. @retval EFI_DEVICE_ERROR An error occurred when attempting to access the KMS. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_GET_SERVICE_STATUS)( IN EFI_KMS_PROTOCOL *This ); /** Register client information with the supported KMS. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS The client information has been accepted by the KMS. @retval EFI_NOT_READY No connection to the KMS is available. @retval EFI_NO_RESPONSE There was no response from the device or the key server. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server. @retval EFI_DEVICE_ERROR An error occurred when attempting to access the KMS. @retval EFI_OUT_OF_RESOURCES Required resources were not available to perform the function. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_UNSUPPORTED The KMS does not support the use of client identifiers. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_REGISTER_CLIENT)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Request that the KMS generate one or more new keys and associate them with key identifiers. The key value(s) is returned to the caller. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] KeyDescriptorCount Pointer to a count of the number of key descriptors to be processed by this operation. On return, this number will be updated with the number of key descriptors successfully processed. @param[in, out] KeyDescriptors Pointer to an array of EFI_KMS_KEY_DESCRIPTOR structures which describe the keys to be generated. On input, the KeyIdentifierSize and the KeyIdentifier may specify an identifier to be used for the key, but this is not required. The KeyFormat field must specify a key format GUID reported as supported by the KeyFormats field of the EFI_KMS_PROTOCOL. The value for this field in the first key descriptor will be considered the default value for subsequent key descriptors requested in this operation if those key descriptors have a NULL GUID in the key format field. On output, the KeyIdentifierSize and KeyIdentifier fields will specify an identifier for the key which will be either the original identifier if one was provided, or an identifier generated either by the KMS or the KMS protocol implementation. The KeyFormat field will be updated with the GUID used to generate the key if it was a NULL GUID, and the KeyValue field will contain a pointer to memory containing the key value for the generated key. Memory for both the KeyIdentifier and the KeyValue fields will be allocated with the BOOT_SERVICES_DATA type and must be freed by the caller when it is no longer needed. Also, the KeyStatus field must reflect the result of the request relative to that key. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully generated and retrieved all requested keys. @retval EFI_UNSUPPORTED This function is not supported by the KMS. --OR-- One (or more) of the key requests submitted is not supported by the KMS. Check individual key request(s) to see which ones may have been processed. @retval EFI_OUT_OF_RESOURCES Required resources were not available to perform the function. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key request(s) to see which ones may have been processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either no id was provided or an invalid id was provided. @retval EFI_DEVICE_ERROR An error occurred when attempting to access the KMS. Check individual key request(s) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyDescriptorCount is NULL, or Keys is NULL. @retval EFI_NOT_FOUND One or more EFI_KMS_KEY_DESCRIPTOR structures could not be processed properly. KeyDescriptorCount contains the number of structures which were successfully processed. Individual structures will reflect the status of the processing for that structure. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_CREATE_KEY)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINT16 *KeyDescriptorCount, IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Retrieve an existing key. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] KeyDescriptorCount Pointer to a count of the number of key descriptors to be processed by this operation. On return, this number will be updated with the number of key descriptors successfully processed. @param[in, out] KeyDescriptors Pointer to an array of EFI_KMS_KEY_DESCRIPTOR structures which describe the keys to be retrieved from the KMS. On input, the KeyIdentifierSize and the KeyIdentifier must specify an identifier to be used to retrieve a specific key. All other fields in the descriptor should be NULL. On output, the KeyIdentifierSize and KeyIdentifier fields will be unchanged, while the KeyFormat and KeyValue fields will be updated values associated with this key identifier. Memory for the KeyValue field will be allocated with the BOOT_SERVICES_DATA type and must be freed by the caller when it is no longer needed. Also, the KeyStatus field will reflect the result of the request relative to the individual key descriptor. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully retrieved all requested keys. @retval EFI_OUT_OF_RESOURCES Could not allocate resources for the method processing. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key request(s) to see which ones may have been processed. @retval EFI_BUFFER_TOO_SMALL If multiple keys are associated with a single identifier, and the KeyValue buffer does not contain enough structures (KeyDescriptorCount) to contain all the key data, then the available structures will be filled and KeyDescriptorCount will be updated to indicate the number of keys which could not be processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key request(s) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyDescriptorCount is NULL, or Keys is NULL. @retval EFI_NOT_FOUND One or more EFI_KMS_KEY_DESCRIPTOR structures could not be processed properly. KeyDescriptorCount contains the number of structures which were successfully processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_GET_KEY)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINT16 *KeyDescriptorCount, IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Add a new key. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] KeyDescriptorCount Pointer to a count of the number of key descriptors to be processed by this operation. On normal return, this number will be updated with the number of key descriptors successfully processed. @param[in, out] KeyDescriptors Pointer to an array of EFI_KMS_KEY_DESCRIPTOR structures which describe the keys to be added. On input, the KeyId field for first key must contain valid identifier data to be used for adding a key to the KMS. The values for these fields in this key definition will be considered default values for subsequent keys requested in this operation. A value of 0 in any subsequent KeyId field will be replaced with the current default value. The KeyFormat and KeyValue fields for each key to be added must contain consistent values to be associated with the given KeyId. On return, the KeyStatus field will reflect the result of the operation for each key request. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully added all requested keys. @retval EFI_OUT_OF_RESOURCES Could not allocate required resources. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key request(s) to see which ones may have been processed. @retval EFI_BUFFER_TOO_SMALL If multiple keys are associated with a single identifier, and the KeyValue buffer does not contain enough structures (KeyDescriptorCount) to contain all the key data, then the available structures will be filled and KeyDescriptorCount will be updated to indicate the number of keys which could not be processed @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key request(s) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyDescriptorCount is NULL, or Keys is NULL. @retval EFI_NOT_FOUND One or more EFI_KMS_KEY_DESCRIPTOR structures could not be processed properly. KeyDescriptorCount contains the number of structures which were successfully processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_ADD_KEY)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINT16 *KeyDescriptorCount, IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Delete an existing key from the KMS database. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] KeyDescriptorCount Pointer to a count of the number of key descriptors to be processed by this operation. On normal return, this number will be updated with the number of key descriptors successfully processed. @param[in, out] KeyDescriptors Pointer to an array of EFI_KMS_KEY_DESCRIPTOR structures which describe the keys to be deleted. On input, the KeyId field for first key must contain valid identifier data to be used for adding a key to the KMS. The values for these fields in this key definition will be considered default values for subsequent keys requested in this operation. A value of 0 in any subsequent KeyId field will be replaced with the current default value. The KeyFormat and KeyValue fields are ignored, but should be 0. On return, the KeyStatus field will reflect the result of the operation for each key request. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully deleted all requested keys. @retval EFI_OUT_OF_RESOURCES Could not allocate required resources. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key request(s) to see which ones may have been processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key request(s) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyDescriptorCount is NULL, or Keys is NULL. @retval EFI_NOT_FOUND One or more EFI_KMS_KEY_DESCRIPTOR structures could not be processed properly. KeyDescriptorCount contains the number of structures which were successfully processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_DELETE_KEY)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINT16 *KeyDescriptorCount, IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Get one or more attributes associated with a specified key identifier. If none are found, the returned attributes count contains a value of zero. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in] KeyIdentifierSize Pointer to the size in bytes of the KeyIdentifier variable. @param[in] KeyIdentifier Pointer to the key identifier associated with this key. @param[in, out] KeyAttributesCount Pointer to the number of EFI_KMS_KEY_ATTRIBUTE structures associated with the Key identifier. If none are found, the count value is zero on return. On input this value reflects the number of KeyAttributes that may be returned. On output, the value reflects the number of completed KeyAttributes structures found. @param[in, out] KeyAttributes Pointer to an array of EFI_KMS_KEY_ATTRIBUTE structures associated with the Key Identifier. On input, the fields in the structure should be NULL. On output, the attribute fields will have updated values for attributes associated with this key identifier. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully retrieved all key attributes. @retval EFI_OUT_OF_RESOURCES Could not allocate resources for the method processing. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key attribute request(s) to see which ones may have been processed. @retval EFI_BUFFER_TOO_SMALL If multiple key attributes are associated with a single identifier, and the KeyAttributes buffer does not contain enough structures (KeyAttributesCount) to contain all the key attributes data, then the available structures will be filled and KeyAttributesCount will be updated to indicate the number of key attributes which could not be processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key attribute request(s) (i.e. key attribute status for each) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyIdentifierSize is NULL , or KeyIdentifier is NULL, or KeyAttributes is NULL, or KeyAttributesSize is NULL. @retval EFI_NOT_FOUND The KeyIdentifier could not be found. KeyAttributesCount contains zero. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_GET_KEY_ATTRIBUTES)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN UINT8 *KeyIdentifierSize, IN CONST VOID *KeyIdentifier, IN OUT UINT16 *KeyAttributesCount, IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Add one or more attributes to a key specified by a key identifier. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in] KeyIdentifierSize Pointer to the size in bytes of the KeyIdentifier variable. @param[in] KeyIdentifier Pointer to the key identifier associated with this key. @param[in, out] KeyAttributesCount Pointer to the number of EFI_KMS_KEY_ATTRIBUTE structures to associate with the Key. On normal returns, this number will be updated with the number of key attributes successfully processed. @param[in, out] KeyAttributes Pointer to an array of EFI_KMS_KEY_ATTRIBUTE structures providing the attribute information to associate with the key. On input, the values for the fields in the structure are completely filled in. On return the KeyAttributeStatus field will reflect the result of the operation for each key attribute request. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully added all requested key attributes. @retval EFI_OUT_OF_RESOURCES Could not allocate required resources. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key attribute request(s) to see which ones may have been processed. @retval EFI_BUFFER_TOO_SMALL If multiple keys attributes are associated with a single key identifier, and the attributes buffer does not contain enough structures (KeyAttributesCount) to contain all the data, then the available structures will be filled and KeyAttributesCount will be updated to indicate the number of key attributes which could not be processed. The status of each key attribute is also updated indicating success or failure for that attribute in case there are other errors for those attributes that could be processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key attribute request(s) (i.e. key attribute status for each) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyAttributesCount is NULL, or KeyAttributes is NULL, or KeyIdentifierSize is NULL, or KeyIdentifer is NULL. @retval EFI_NOT_FOUND The KeyIdentifier could not be found. On return the KeyAttributesCount contains the number of attributes processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_ADD_KEY_ATTRIBUTES)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN UINT8 *KeyIdentifierSize, IN CONST VOID *KeyIdentifier, IN OUT UINT16 *KeyAttributesCount, IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Delete attributes to a key specified by a key identifier. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in] KeyIdentifierSize Pointer to the size in bytes of the KeyIdentifier variable. @param[in] KeyIdentifier Pointer to the key identifier associated with this key. @param[in, out] KeyAttributesCount Pointer to the number of EFI_KMS_KEY_ATTRIBUTE structures to associate with the Key. On input, the count value is one or more. On normal returns, this number will be updated with the number of key attributes successfully processed. @param[in, out] KeyAttributes Pointer to an array of EFI_KMS_KEY_ATTRIBUTE structures providing the attribute information to associate with the key. On input, the values for the fields in the structure are completely filled in. On return the KeyAttributeStatus field will reflect the result of the operation for each key attribute request. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully deleted all requested key attributes. @retval EFI_OUT_OF_RESOURCES Could not allocate required resources. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key attribute request(s) to see which ones may have been processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key attribute request(s) (i.e. key attribute status for each) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyAttributesCount is NULL, or KeyAttributes is NULL, or KeyIdentifierSize is NULL, or KeyIdentifer is NULL. @retval EFI_NOT_FOUND The KeyIdentifier could not be found or the attribute could not be found. On return the KeyAttributesCount contains the number of attributes processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_DELETE_KEY_ATTRIBUTES)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN UINT8 *KeyIdentifierSize, IN CONST VOID *KeyIdentifier, IN OUT UINT16 *KeyAttributesCount, IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /** Retrieve one or more key that has matched all of the specified key attributes. @param[in] This Pointer to the EFI_KMS_PROTOCOL instance. @param[in] Client Pointer to a valid EFI_KMS_CLIENT_INFO structure. @param[in, out] KeyAttributesCount Pointer to a count of the number of key attribute structures that must be matched for each returned key descriptor. On input the count value is one or more. On normal returns, this number will be updated with the number of key attributes successfully processed. @param[in, out] KeyAttributes Pointer to an array of EFI_KMS_KEY_ATTRIBUTE structure to search for. On input, the values for the fields in the structure are completely filled in. On return the KeyAttributeStatus field will reflect the result of the operation for each key attribute request. @param[in, out] KeyDescriptorCount Pointer to a count of the number of key descriptors matched by this operation. On entry, this number will be zero. On return, this number will be updated to the number of key descriptors successfully found. @param[in, out] KeyDescriptors Pointer to an array of EFI_KMS_KEY_DESCRIPTOR structures which describe the keys from the KMS having the KeyAttribute(s) specified. On input, this pointer will be NULL. On output, the array will contain an EFI_KMS_KEY_DESCRIPTOR structure for each key meeting the search criteria. Memory for the array and all KeyValue fields will be allocated with the EfiBootServicesData type and must be freed by the caller when it is no longer needed. Also, the KeyStatus field of each descriptor will reflect the result of the request relative to that key descriptor. @param[in, out] ClientDataSize Pointer to the size, in bytes, of an arbitrary block of data specified by the ClientData parameter. This parameter may be NULL, in which case the ClientData parameter will be ignored and no data will be transferred to or from the KMS. If the parameter is not NULL, then ClientData must be a valid pointer. If the value pointed to is 0, no data will be transferred to the KMS, but data may be returned by the KMS. For all non-zero values *ClientData will be transferred to the KMS, which may also return data to the caller. In all cases, the value upon return to the caller will be the size of the data block returned to the caller, which will be zero if no data is returned from the KMS. @param[in, out] ClientData Pointer to a pointer to an arbitrary block of data of *ClientDataSize that is to be passed directly to the KMS if it supports the use of client data. This parameter may be NULL if and only if the ClientDataSize parameter is also NULL. Upon return to the caller, *ClientData points to a block of data of *ClientDataSize that was returned from the KMS. If the returned value for *ClientDataSize is zero, then the returned value for *ClientData must be NULL and should be ignored by the caller. The KMS protocol consumer is responsible for freeing all valid buffers used for client data regardless of whether they are allocated by the caller for input to the function or by the implementation for output back to the caller. @retval EFI_SUCCESS Successfully retrieved all requested keys. @retval EFI_OUT_OF_RESOURCES Could not allocate required resources. @retval EFI_TIMEOUT Timed out waiting for device or key server. Check individual key attribute request(s) to see which ones may have been processed. @retval EFI_BUFFER_TOO_SMALL If multiple keys are associated with the attribute(s), and the KeyValue buffer does not contain enough structures (KeyDescriptorCount) to contain all the key data, then the available structures will be filled and KeyDescriptorCount will be updated to indicate the number of keys which could not be processed. @retval EFI_ACCESS_DENIED Access was denied by the device or the key server; OR a ClientId is required by the server and either none or an invalid id was provided. @retval EFI_DEVICE_ERROR Device or key server error. Check individual key attribute request(s) (i.e. key attribute status for each) to see which ones may have been processed. @retval EFI_INVALID_PARAMETER This is NULL, ClientId is required but it is NULL, KeyDescriptorCount is NULL, or KeyDescriptors is NULL or KeyAttributes is NULL, or KeyAttributesCount is NULL. @retval EFI_NOT_FOUND One or more EFI_KMS_KEY_ATTRIBUTE structures could not be processed properly. KeyAttributeCount contains the number of structures which were successfully processed. Individual structures will reflect the status of the processing for that structure. @retval EFI_UNSUPPORTED The implementation/KMS does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_KMS_GET_KEY_BY_ATTRIBUTES)( IN EFI_KMS_PROTOCOL *This, IN EFI_KMS_CLIENT_INFO *Client, IN OUT UINTN *KeyAttributeCount, IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, IN OUT UINTN *KeyDescriptorCount, IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, IN OUT UINTN *ClientDataSize OPTIONAL, IN OUT VOID **ClientData OPTIONAL ); /// /// The Key Management Service (KMS) protocol provides services to generate, store, retrieve, /// and manage cryptographic keys. /// struct _EFI_KMS_PROTOCOL { /// /// Get the current status of the key management service. If the implementation has not yet /// connected to the KMS, then a call to this function will initiate a connection. This is the /// only function that is valid for use prior to the service being marked available. /// EFI_KMS_GET_SERVICE_STATUS GetServiceStatus; /// /// Register a specific client with the KMS. /// EFI_KMS_REGISTER_CLIENT RegisterClient; /// /// Request the generation of a new key and retrieve it. /// EFI_KMS_CREATE_KEY CreateKey; /// /// Retrieve an existing key. /// EFI_KMS_GET_KEY GetKey; /// /// Add a local key to KMS database. If there is an existing key with this key identifier in the /// KMS database, it will be replaced with the new key. /// EFI_KMS_ADD_KEY AddKey; /// /// Delete an existing key from the KMS database. /// EFI_KMS_DELETE_KEY DeleteKey; /// /// Get attributes for an existing key in the KMS database. /// EFI_KMS_GET_KEY_ATTRIBUTES GetKeyAttributes; /// /// Add attributes to an existing key in the KMS database. /// EFI_KMS_ADD_KEY_ATTRIBUTES AddKeyAttributes; /// /// Delete attributes for an existing key in the KMS database. /// EFI_KMS_DELETE_KEY_ATTRIBUTES DeleteKeyAttributes; /// /// Get existing key(s) with the specified attributes. /// EFI_KMS_GET_KEY_BY_ATTRIBUTES GetKeyByAttributes; /// /// The version of this EFI_KMS_PROTOCOL structure. This must be set to 0x00020040 for /// the initial version of this protocol. /// UINT32 ProtocolVersion; /// /// Optional GUID used to identify a specific KMS. This GUID may be supplied by the provider, /// by the implementation, or may be null. If is null, then the ServiceName must not be null. /// EFI_GUID ServiceId; /// /// Optional pointer to a unicode string which may be used to identify the KMS or provide /// other information about the supplier. /// CHAR16 *ServiceName; /// /// Optional 32-bit value which may be used to indicate the version of the KMS provided by /// the supplier. /// UINT32 ServiceVersion; /// /// TRUE if and only if the service is active and available for use. To avoid unnecessary /// delays in POST, this protocol may be installed without connecting to the service. In this /// case, the first call to the GetServiceStatus () function will cause the implementation to /// connect to the supported service and mark it as available. The capabilities of this service /// as defined in the reminder of this protocol are not guaranteed to be valid until the service /// has been marked available. /// BOOLEAN ServiceAvailable; /// /// TRUE if and only if the service supports client identifiers. Client identifiers may be used /// for auditing, access control or any other purpose specific to the implementation. /// BOOLEAN ClientIdSupported; /// /// TRUE if and only if the service requires a client identifier in order to process key requests. /// FALSE otherwise. /// BOOLEAN ClientIdRequired; /// /// The maximum size in bytes for the client identifier. /// UINT16 ClientIdMaxSize; /// /// The client name string type(s) supported by the KMS service. If client names are not /// supported, this field will be set the EFI_KMS_DATA_TYPE_NONE. Otherwise, it will be set /// to the inclusive 'OR' of all client name formats supported. Client names may be used for /// auditing, access control or any other purpose specific to the implementation. /// UINT8 ClientNameStringTypes; /// /// TRUE if only if the KMS requires a client name to be supplied to the service. /// FALSE otherwise. /// BOOLEAN ClientNameRequired; /// /// The maximum number of characters allowed for the client name. /// UINT16 ClientNameMaxCount; /// /// TRUE if and only if the service supports arbitrary client data requests. The use of client /// data requires the caller to have specific knowledge of the individual KMS service and /// should be used only if absolutely necessary. /// FALSE otherwise. /// BOOLEAN ClientDataSupported; /// /// The maximum size in bytes for the client data. If the maximum data size is not specified /// by the KMS or it is not known, then this field must be filled with all ones. /// UINTN ClientDataMaxSize; /// /// TRUE if variable length key identifiers are supported. /// FALSE if a fixed length key identifier is supported. /// BOOLEAN KeyIdVariableLenSupported; /// /// If KeyIdVariableLenSupported is TRUE, this is the maximum supported key identifier length /// in bytes. Otherwise this is the fixed length of key identifier supported. Key ids shorter /// than the fixed length will be padded on the right with blanks. /// UINTN KeyIdMaxSize; /// /// The number of key format/size GUIDs returned in the KeyFormats field. /// UINTN KeyFormatsCount; /// /// A pointer to an array of EFI_GUID values which specify key formats/sizes supported by /// this KMS. Each format/size pair will be specified by a separate EFI_GUID. At least one /// key format/size must be supported. All formats/sizes with the same hashing algorithm /// must be contiguous in the array, and for each hashing algorithm, the key sizes must be in /// ascending order. See "Related Definitions" for GUIDs which identify supported key formats/sizes. /// This list of GUIDs supported by the KMS is not required to be exhaustive, and the KMS /// may provide support for additional key formats/sizes. Users may request key information /// using an arbitrary GUID, but any GUID not recognized by the implementation or not /// supported by the KMS will return an error code of EFI_UNSUPPORTED /// EFI_GUID *KeyFormats; /// /// TRUE if key attributes are supported. /// FALSE if key attributes are not supported. /// BOOLEAN KeyAttributesSupported; /// /// The key attribute identifier string type(s) supported by the KMS service. If key attributes /// are not supported, this field will be set to EFI_KMS_DATA_TYPE_NONE. Otherwise, it will /// be set to the inclusive 'OR' of all key attribute identifier string types supported. /// EFI_KMS_DATA_TYPE_BINARY is not valid for this field. /// UINT8 KeyAttributeIdStringTypes; UINT16 KeyAttributeIdMaxCount; /// /// The number of predefined KeyAttributes structures returned in the KeyAttributes /// parameter. If the KMS does not support predefined key attributes, or if it does not /// provide a method to obtain predefined key attributes data, then this field must be zero. /// UINTN KeyAttributesCount; /// /// A pointer to an array of KeyAttributes structures which contains the predefined /// attributes supported by this KMS. Each structure must contain a valid key attribute /// identifier and should provide any other information as appropriate for the attribute, /// including a default value if one exists. This variable must be set to NULL if the /// KeyAttributesCount variable is zero. It must point to a valid buffer if the /// KeyAttributesCount variable is non-zero. /// This list of predefined attributes is not required to be exhaustive, and the KMS may /// provide additional predefined attributes not enumerated in this list. The implementation /// does not distinguish between predefined and used defined attributes, and therefore, /// predefined attributes not enumerated will still be processed to the KMS. /// EFI_KMS_KEY_ATTRIBUTE *KeyAttributes; }; extern EFI_GUID gEfiKmsFormatGeneric128Guid; extern EFI_GUID gEfiKmsFormatGeneric160Guid; extern EFI_GUID gEfiKmsFormatGeneric256Guid; extern EFI_GUID gEfiKmsFormatGeneric512Guid; extern EFI_GUID gEfiKmsFormatGeneric1024Guid; extern EFI_GUID gEfiKmsFormatGeneric2048Guid; extern EFI_GUID gEfiKmsFormatGeneric3072Guid; extern EFI_GUID gEfiKmsFormatMd2128Guid; extern EFI_GUID gEfiKmsFormatMdc2128Guid; extern EFI_GUID gEfiKmsFormatMd4128Guid; extern EFI_GUID gEfiKmsFormatMdc4128Guid; extern EFI_GUID gEfiKmsFormatMd5128Guid; extern EFI_GUID gEfiKmsFormatMd5sha128Guid; extern EFI_GUID gEfiKmsFormatSha1160Guid; extern EFI_GUID gEfiKmsFormatSha256256Guid; extern EFI_GUID gEfiKmsFormatSha512512Guid; extern EFI_GUID gEfiKmsFormatAesxts128Guid; extern EFI_GUID gEfiKmsFormatAesxts256Guid; extern EFI_GUID gEfiKmsFormatAescbc128Guid; extern EFI_GUID gEfiKmsFormatAescbc256Guid; extern EFI_GUID gEfiKmsFormatRsasha11024Guid; extern EFI_GUID gEfiKmsFormatRsasha12048Guid; extern EFI_GUID gEfiKmsFormatRsasha2562048Guid; extern EFI_GUID gEfiKmsFormatRsasha2563072Guid; extern EFI_GUID gEfiKmsProtocolGuid; #endif /** @file This protocol abstracts the 8259 interrupt controller. This includes PCI IRQ routing needed to program the PCI Interrupt Line register. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This protocol is defined in Framework for EFI Compatibility Support Module spec Version 0.97. **/ #ifndef _EFI_LEGACY_8259_H_ #define _EFI_LEGACY_8259_H_ #define EFI_LEGACY_8259_PROTOCOL_GUID \ { \ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } \ } typedef struct _EFI_LEGACY_8259_PROTOCOL EFI_LEGACY_8259_PROTOCOL; typedef enum { Efi8259Irq0, Efi8259Irq1, Efi8259Irq2, Efi8259Irq3, Efi8259Irq4, Efi8259Irq5, Efi8259Irq6, Efi8259Irq7, Efi8259Irq8, Efi8259Irq9, Efi8259Irq10, Efi8259Irq11, Efi8259Irq12, Efi8259Irq13, Efi8259Irq14, Efi8259Irq15, Efi8259IrqMax } EFI_8259_IRQ; typedef enum { Efi8259LegacyMode, Efi8259ProtectedMode, Efi8259MaxMode } EFI_8259_MODE; /** Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for the legacy mode mask and the protected mode mask. The base address for the 8259 is different for legacy and protected mode, so two masks are required. @param This The protocol instance pointer. @param MasterBase The base vector for the Master PIC in the 8259 controller. @param SlaveBase The base vector for the Slave PIC in the 8259 controller. @retval EFI_SUCCESS The new bases were programmed. @retval EFI_DEVICE_ERROR A device error occurred programming the vector bases. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)( IN EFI_LEGACY_8259_PROTOCOL *This, IN UINT8 MasterBase, IN UINT8 SlaveBase ); /** Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for the legacy mode mask and the protected mode mask. The base address for the 8259 is different for legacy and protected mode, so two masks are required. @param This The protocol instance pointer. @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15. @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15. @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. @retval EFI_SUCCESS 8259 status returned. @retval EFI_DEVICE_ERROR Error reading 8259. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_GET_MASK)( IN EFI_LEGACY_8259_PROTOCOL *This, OUT UINT16 *LegacyMask OPTIONAL, OUT UINT16 *LegacyEdgeLevel OPTIONAL, OUT UINT16 *ProtectedMask OPTIONAL, OUT UINT16 *ProtectedEdgeLevel OPTIONAL ); /** Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for the legacy mode mask and the protected mode mask. The base address for the 8259 is different for legacy and protected mode, so two masks are required. Also set the edge/level masks. @param This The protocol instance pointer. @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15. @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15. @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15. @retval EFI_SUCCESS 8259 status returned. @retval EFI_DEVICE_ERROR Error writing 8259. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_SET_MASK)( IN EFI_LEGACY_8259_PROTOCOL *This, IN UINT16 *LegacyMask OPTIONAL, IN UINT16 *LegacyEdgeLevel OPTIONAL, IN UINT16 *ProtectedMask OPTIONAL, IN UINT16 *ProtectedEdgeLevel OPTIONAL ); /** Set the 8259 mode of operation. The base address for the 8259 is different for legacy and protected mode. The legacy mode requires the master 8259 to have a master base of 0x08 and the slave base of 0x70. The protected mode base locations are not defined. Interrupts must be masked by the caller before this function is called. The interrupt mask from the current mode is saved. The interrupt mask for the new mode is Mask, or if Mask does not exist the previously saved mask is used. @param This The protocol instance pointer. @param Mode The mode of operation. i.e. the real mode or protected mode. @param Mask Optional interupt mask for the new mode. @param EdgeLevel Optional trigger mask for the new mode. @retval EFI_SUCCESS 8259 programmed. @retval EFI_DEVICE_ERROR Error writing to 8259. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_SET_MODE)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_8259_MODE Mode, IN UINT16 *Mask OPTIONAL, IN UINT16 *EdgeLevel OPTIONAL ); /** Convert from IRQ to processor interrupt vector number. @param This The protocol instance pointer. @param Irq 8259 IRQ0 - IRQ15. @param Vector The processor vector number that matches an Irq. @retval EFI_SUCCESS The Vector matching Irq is returned. @retval EFI_INVALID_PARAMETER The Irq not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_GET_VECTOR)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_8259_IRQ Irq, OUT UINT8 *Vector ); /** Enable Irq by unmasking interrupt in 8259 @param This The protocol instance pointer. @param Irq 8259 IRQ0 - IRQ15. @param LevelTriggered TRUE if level triggered. FALSE if edge triggered. @retval EFI_SUCCESS The Irq was enabled on 8259. @retval EFI_INVALID_PARAMETER The Irq is not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_8259_IRQ Irq, IN BOOLEAN LevelTriggered ); /** Disable Irq by masking interrupt in 8259 @param This The protocol instance pointer. @param Irq 8259 IRQ0 - IRQ15. @retval EFI_SUCCESS The Irq was disabled on 8259. @retval EFI_INVALID_PARAMETER The Irq is not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_8259_IRQ Irq ); /** PciHandle represents a PCI config space of a PCI function. Vector represents Interrupt Pin (from PCI config space) and it is the data that is programmed into the Interrupt Line (from the PCI config space) register. @param This The protocol instance pointer. @param PciHandle The PCI function to return the vector for. @param Vector The vector for the function it matches. @retval EFI_SUCCESS A valid Vector was returned. @retval EFI_INVALID_PARAMETER PciHandle not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_HANDLE PciHandle, OUT UINT8 *Vector ); /** Send an EOI to 8259 @param This The protocol instance pointer. @param Irq 8259 IRQ0 - IRQ15. @retval EFI_SUCCESS EOI was successfully sent to 8259. @retval EFI_INVALID_PARAMETER The Irq isnot valid. **/ typedef EFI_STATUS (EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)( IN EFI_LEGACY_8259_PROTOCOL *This, IN EFI_8259_IRQ Irq ); /** @par Protocol Description: Abstracts the 8259 and APIC hardware control between EFI usage and Compatibility16 usage. @param SetVectorBase Sets the vector bases for master and slave PICs. @param GetMask Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected mode. @param SetMask Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected mode. @param SetMode Sets PIC mode to 16-bit real mode or 32-bit protected mode. @param GetVector Gets the base vector assigned to an IRQ. @param EnableIrq Enables an IRQ. @param DisableIrq Disables an IRQ. @param GetInterruptLine Gets an IRQ that is assigned to a PCI device. @param EndOfInterrupt Issues the end of interrupt command. **/ struct _EFI_LEGACY_8259_PROTOCOL { EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase; EFI_LEGACY_8259_GET_MASK GetMask; EFI_LEGACY_8259_SET_MASK SetMask; EFI_LEGACY_8259_SET_MODE SetMode; EFI_LEGACY_8259_GET_VECTOR GetVector; EFI_LEGACY_8259_ENABLE_IRQ EnableIrq; EFI_LEGACY_8259_DISABLE_IRQ DisableIrq; EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine; EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt; }; extern EFI_GUID gEfiLegacy8259ProtocolGuid; #endif /** @file Load File protocol as defined in the UEFI 2.0 specification. The load file protocol exists to supports the addition of new boot devices, and to support booting from devices that do not map well to file system. Network boot is done via a LoadFile protocol. UEFI 2.0 can boot from any device that produces a LoadFile protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_LOAD_FILE_PROTOCOL_H__ #define __EFI_LOAD_FILE_PROTOCOL_H__ #define EFI_LOAD_FILE_PROTOCOL_GUID \ { \ 0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ } /// /// Protocol Guid defined by EFI1.1. /// #define LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL_GUID typedef struct _EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL; /// /// Backward-compatible with EFI1.1 /// typedef EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_INTERFACE; /** Causes the driver to load a specified file. @param This Protocol instance pointer. @param FilePath The device specific path of the file to load. @param BootPolicy If TRUE, indicates that the request originates from the boot manager is attempting to load FilePath as a boot selection. If FALSE, then FilePath must match as exact file to be loaded. @param BufferSize On input the size of Buffer in bytes. On output with a return code of EFI_SUCCESS, the amount of data transferred to Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, the size of Buffer required to retrieve the requested file. @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL, then the size of the requested file is returned in BufferSize. @retval EFI_SUCCESS The file was loaded. @retval EFI_UNSUPPORTED The device does not support the provided BootPolicy @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or BufferSize is NULL. @retval EFI_NO_MEDIA No medium was present to load the file. @retval EFI_DEVICE_ERROR The file was not loaded due to a device error. @retval EFI_NO_RESPONSE The remote system did not respond. @retval EFI_NOT_FOUND The file was not found. @retval EFI_ABORTED The file load process was manually cancelled. @retval EFI_WARN_FILE_SYSTEM The resulting Buffer contains UEFI-compliant file system. **/ typedef EFI_STATUS (EFIAPI *EFI_LOAD_FILE)( IN EFI_LOAD_FILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN BOOLEAN BootPolicy, IN OUT UINTN *BufferSize, IN VOID *Buffer OPTIONAL ); /// /// The EFI_LOAD_FILE_PROTOCOL is a simple protocol used to obtain files from arbitrary devices. /// struct _EFI_LOAD_FILE_PROTOCOL { EFI_LOAD_FILE LoadFile; }; extern EFI_GUID gEfiLoadFileProtocolGuid; #endif /** @file Load File protocol as defined in the UEFI 2.0 specification. Load file protocol exists to supports the addition of new boot devices, and to support booting from devices that do not map well to file system. Network boot is done via a LoadFile protocol. UEFI 2.0 can boot from any device that produces a LoadFile protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_LOAD_FILE2_PROTOCOL_H__ #define __EFI_LOAD_FILE2_PROTOCOL_H__ #define EFI_LOAD_FILE2_PROTOCOL_GUID \ { \ 0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \ } /// /// Protocol Guid defined by UEFI2.1. /// #define LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL_GUID typedef struct _EFI_LOAD_FILE2_PROTOCOL EFI_LOAD_FILE2_PROTOCOL; /** Causes the driver to load a specified file. @param This Protocol instance pointer. @param FilePath The device specific path of the file to load. @param BootPolicy Should always be FALSE. @param BufferSize On input the size of Buffer in bytes. On output with a return code of EFI_SUCCESS, the amount of data transferred to Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, the size of Buffer required to retrieve the requested file. @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL, then no the size of the requested file is returned in BufferSize. @retval EFI_SUCCESS The file was loaded. @retval EFI_UNSUPPORTED BootPolicy is TRUE. @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or BufferSize is NULL. @retval EFI_NO_MEDIA No medium was present to load the file. @retval EFI_DEVICE_ERROR The file was not loaded due to a device error. @retval EFI_NO_RESPONSE The remote system did not respond. @retval EFI_NOT_FOUND The file was not found @retval EFI_ABORTED The file load process was manually canceled. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. BufferSize has been updated with the size needed to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_LOAD_FILE2)( IN EFI_LOAD_FILE2_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN BOOLEAN BootPolicy, IN OUT UINTN *BufferSize, IN VOID *Buffer OPTIONAL ); /// /// The EFI_LOAD_FILE_PROTOCOL is a simple protocol used to obtain files from arbitrary devices. /// struct _EFI_LOAD_FILE2_PROTOCOL { EFI_LOAD_FILE2 LoadFile; }; extern EFI_GUID gEfiLoadFile2ProtocolGuid; #endif /** @file UEFI 2.0 Loaded image protocol definition. Every EFI driver and application is passed an image handle when it is loaded. This image handle will contain a Loaded Image Protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __LOADED_IMAGE_PROTOCOL_H__ #define __LOADED_IMAGE_PROTOCOL_H__ #define EFI_LOADED_IMAGE_PROTOCOL_GUID \ { \ 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ } #define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ { \ 0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \ } /// /// Protocol GUID defined in EFI1.1. /// #define LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL_GUID /// /// EFI_SYSTEM_TABLE & EFI_IMAGE_UNLOAD are defined in EfiApi.h /// #define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 /// /// Revision defined in EFI1.1. /// #define EFI_LOADED_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION /// /// Can be used on any image handle to obtain information about the loaded image. /// typedef struct { UINT32 Revision; ///< Defines the revision of the EFI_LOADED_IMAGE_PROTOCOL structure. ///< All future revisions will be backward compatible to the current revision. EFI_HANDLE ParentHandle; ///< Parent image's image handle. NULL if the image is loaded directly from ///< the firmware's boot manager. EFI_SYSTEM_TABLE *SystemTable; ///< the image's EFI system table pointer. // // Source location of image // EFI_HANDLE DeviceHandle; ///< The device handle that the EFI Image was loaded from. EFI_DEVICE_PATH_PROTOCOL *FilePath; ///< A pointer to the file path portion specific to DeviceHandle ///< that the EFI Image was loaded from. VOID *Reserved; ///< Reserved. DO NOT USE. // // Images load options // UINT32 LoadOptionsSize; ///< The size in bytes of LoadOptions. VOID *LoadOptions; ///< A pointer to the image's binary load options. // // Location of where image was loaded // VOID *ImageBase; ///< The base address at which the image was loaded. UINT64 ImageSize; ///< The size in bytes of the loaded image. EFI_MEMORY_TYPE ImageCodeType; ///< The memory type that the code sections were loaded as. EFI_MEMORY_TYPE ImageDataType; ///< The memory type that the data sections were loaded as. EFI_IMAGE_UNLOAD Unload; } EFI_LOADED_IMAGE_PROTOCOL; // // For backward-compatible with EFI1.1. // typedef EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE; extern EFI_GUID gEfiLoadedImageProtocolGuid; extern EFI_GUID gEfiLoadedImageDevicePathProtocolGuid; #endif /** @file EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0. EFI_MANAGED_NETWORK_PROTOCOL as defined in UEFI 2.0. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0 **/ #ifndef __EFI_MANAGED_NETWORK_PROTOCOL_H__ #define __EFI_MANAGED_NETWORK_PROTOCOL_H__ #include #define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c } \ } #define EFI_MANAGED_NETWORK_PROTOCOL_GUID \ { \ 0x7ab33a91, 0xace5, 0x4326, { 0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16 } \ } typedef struct _EFI_MANAGED_NETWORK_PROTOCOL EFI_MANAGED_NETWORK_PROTOCOL; typedef struct { /// /// Timeout value for a UEFI one-shot timer event. A packet that has not been removed /// from the MNP receive queue will be dropped if its receive timeout expires. /// UINT32 ReceivedQueueTimeoutValue; /// /// Timeout value for a UEFI one-shot timer event. A packet that has not been removed /// from the MNP transmit queue will be dropped if its receive timeout expires. /// UINT32 TransmitQueueTimeoutValue; /// /// Ethernet type II 16-bit protocol type in host byte order. Valid /// values are zero and 1,500 to 65,535. /// UINT16 ProtocolTypeFilter; /// /// Set to TRUE to receive packets that are sent to the network /// device MAC address. The startup default value is FALSE. /// BOOLEAN EnableUnicastReceive; /// /// Set to TRUE to receive packets that are sent to any of the /// active multicast groups. The startup default value is FALSE. /// BOOLEAN EnableMulticastReceive; /// /// Set to TRUE to receive packets that are sent to the network /// device broadcast address. The startup default value is FALSE. /// BOOLEAN EnableBroadcastReceive; /// /// Set to TRUE to receive packets that are sent to any MAC address. /// The startup default value is FALSE. /// BOOLEAN EnablePromiscuousReceive; /// /// Set to TRUE to drop queued packets when the configuration /// is changed. The startup default value is FALSE. /// BOOLEAN FlushQueuesOnReset; /// /// Set to TRUE to timestamp all packets when they are received /// by the MNP. Note that timestamps may be unsupported in some /// MNP implementations. The startup default value is FALSE. /// BOOLEAN EnableReceiveTimestamps; /// /// Set to TRUE to disable background polling in this MNP /// instance. Note that background polling may not be supported in /// all MNP implementations. The startup default value is FALSE, /// unless background polling is not supported. /// BOOLEAN DisableBackgroundPolling; } EFI_MANAGED_NETWORK_CONFIG_DATA; typedef struct { EFI_TIME Timestamp; EFI_EVENT RecycleEvent; UINT32 PacketLength; UINT32 HeaderLength; UINT32 AddressLength; UINT32 DataLength; BOOLEAN BroadcastFlag; BOOLEAN MulticastFlag; BOOLEAN PromiscuousFlag; UINT16 ProtocolType; VOID *DestinationAddress; VOID *SourceAddress; VOID *MediaHeader; VOID *PacketData; } EFI_MANAGED_NETWORK_RECEIVE_DATA; typedef struct { UINT32 FragmentLength; VOID *FragmentBuffer; } EFI_MANAGED_NETWORK_FRAGMENT_DATA; typedef struct { EFI_MAC_ADDRESS *DestinationAddress; // OPTIONAL EFI_MAC_ADDRESS *SourceAddress; // OPTIONAL UINT16 ProtocolType; // OPTIONAL UINT32 DataLength; UINT16 HeaderLength; // OPTIONAL UINT16 FragmentCount; EFI_MANAGED_NETWORK_FRAGMENT_DATA FragmentTable[1]; } EFI_MANAGED_NETWORK_TRANSMIT_DATA; typedef struct { /// /// This Event will be signaled after the Status field is updated /// by the MNP. The type of Event must be /// EFI_NOTIFY_SIGNAL. The Task Priority Level (TPL) of /// Event must be lower than or equal to TPL_CALLBACK. /// EFI_EVENT Event; /// /// The status that is returned to the caller at the end of the operation /// to indicate whether this operation completed successfully. /// EFI_STATUS Status; union { /// /// When this token is used for receiving, RxData is a pointer to the EFI_MANAGED_NETWORK_RECEIVE_DATA. /// EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData; /// /// When this token is used for transmitting, TxData is a pointer to the EFI_MANAGED_NETWORK_TRANSMIT_DATA. /// EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData; } Packet; } EFI_MANAGED_NETWORK_COMPLETION_TOKEN; /** Returns the operational parameters for the current MNP child driver. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param MnpConfigData The pointer to storage for MNP operational parameters. @param SnpModeData The pointer to storage for SNP operational parameters. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. The default values are returned in MnpConfigData if it is not NULL. @retval Other The mode data could not be read. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_GET_MODE_DATA)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Sets or clears the operational parameters for the MNP child driver. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param MnpConfigData The pointer to configuration data that will be assigned to the MNP child driver instance. If NULL, the MNP child driver instance is reset to startup defaults and all pending transmit and receive requests are flushed. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES Required system resources (usually memory) could not be allocated. @retval EFI_UNSUPPORTED The requested feature is unsupported in this [MNP] implementation. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval Other The MNP child driver instance has been reset to startup defaults. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_CONFIGURE)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL ); /** Translates an IP multicast address to a hardware (MAC) multicast address. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param Ipv6Flag Set to TRUE to if IpAddress is an IPv6 multicast address. Set to FALSE if IpAddress is an IPv4 multicast address. @param IpAddress The pointer to the multicast IP address (in network byte order) to convert. @param MacAddress The pointer to the resulting multicast MAC address. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE: - This is NULL. - IpAddress is NULL. - *IpAddress is not a valid multicast IP address. - MacAddress is NULL. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval Other The address could not be converted. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN BOOLEAN Ipv6Flag, IN EFI_IP_ADDRESS *IpAddress, OUT EFI_MAC_ADDRESS *MacAddress ); /** Enables and disables receive filters for multicast address. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param JoinFlag Set to TRUE to join this multicast group. Set to FALSE to leave this multicast group. @param MacAddress The pointer to the multicast MAC group (address) to join or leave. @retval EFI_SUCCESS The requested operation completed successfully. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - JoinFlag is TRUE and MacAddress is NULL. - *MacAddress is not a valid multicast MAC address. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_ALREADY_STARTED The supplied multicast group is already joined. @retval EFI_NOT_FOUND The supplied multicast group is not joined. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. @retval Other The requested operation could not be completed. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_GROUPS)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_MAC_ADDRESS *MacAddress OPTIONAL ); /** Places asynchronous outgoing data packets into the transmit queue. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param Token The pointer to a token associated with the transmit data descriptor. @retval EFI_SUCCESS The transmit completion token was cached. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_ACCESS_DENIED The transmit completion token is already in the transmit queue. @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY The transmit request could not be queued because the transmit queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_TRANSMIT)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token ); /** Places an asynchronous receiving request into the receiving queue. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param Token The pointer to a token associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_ACCESS_DENIED The receive completion token was already in the receive queue. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_RECEIVE)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token ); /** Aborts an asynchronous transmit or receive request. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @param Token The pointer to a token that has been issued by EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all pending tokens are aborted. @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token.Event was signaled. When Token is NULL, all pending requests were aborted and their events were signaled. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was not found in the transmit or receive queue. It has either completed or was not issued by Transmit() and Receive(). **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_CANCEL)( IN EFI_MANAGED_NETWORK_PROTOCOL *This, IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL ); /** Polls for incoming data packets and processes outgoing data packets. @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY No incoming or outgoing data was processed. Consider increasing the polling rate. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_MANAGED_NETWORK_POLL)( IN EFI_MANAGED_NETWORK_PROTOCOL *This ); /// /// The MNP is used by network applications (and drivers) to /// perform raw (unformatted) asynchronous network packet I/O. /// struct _EFI_MANAGED_NETWORK_PROTOCOL { EFI_MANAGED_NETWORK_GET_MODE_DATA GetModeData; EFI_MANAGED_NETWORK_CONFIGURE Configure; EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC McastIpToMac; EFI_MANAGED_NETWORK_GROUPS Groups; EFI_MANAGED_NETWORK_TRANSMIT Transmit; EFI_MANAGED_NETWORK_RECEIVE Receive; EFI_MANAGED_NETWORK_CANCEL Cancel; EFI_MANAGED_NETWORK_POLL Poll; }; extern EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid; extern EFI_GUID gEfiManagedNetworkProtocolGuid; #endif /** @file Metronome Architectural Protocol as defined in PI SPEC VOLUME 2 DXE This code abstracts the DXE core to provide delay services. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_METRONOME_H__ #define __ARCH_PROTOCOL_METRONOME_H__ /// /// Global ID for the Metronome Architectural Protocol /// #define EFI_METRONOME_ARCH_PROTOCOL_GUID \ { 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } /// /// Declare forward reference for the Metronome Architectural Protocol /// typedef struct _EFI_METRONOME_ARCH_PROTOCOL EFI_METRONOME_ARCH_PROTOCOL; /** The WaitForTick() function waits for the number of ticks specified by TickNumber from a known time source in the platform. If TickNumber of ticks are detected, then EFI_SUCCESS is returned. The actual time passed between entry of this function and the first tick is between 0 and TickPeriod 100 nS units. If you want to guarantee that at least TickPeriod time has elapsed, wait for two ticks. This function waits for a hardware event to determine when a tick occurs. It is possible for interrupt processing, or exception processing to interrupt the execution of the WaitForTick() function. Depending on the hardware source for the ticks, it is possible for a tick to be missed. This function cannot guarantee that ticks will not be missed. If a timeout occurs waiting for the specified number of ticks, then EFI_TIMEOUT is returned. @param This The EFI_METRONOME_ARCH_PROTOCOL instance. @param TickNumber Number of ticks to wait. @retval EFI_SUCCESS The wait for the number of ticks specified by TickNumber succeeded. @retval EFI_TIMEOUT A timeout occurred waiting for the specified number of ticks. **/ typedef EFI_STATUS (EFIAPI *EFI_METRONOME_WAIT_FOR_TICK)( IN EFI_METRONOME_ARCH_PROTOCOL *This, IN UINT32 TickNumber ); /// /// This protocol provides access to a known time source in the platform to the /// core. The core uses this known time source to produce core services that /// require calibrated delays. /// struct _EFI_METRONOME_ARCH_PROTOCOL { EFI_METRONOME_WAIT_FOR_TICK WaitForTick; /// /// The period of platform's known time source in 100 nS units. /// This value on any platform must be at least 10 uS, and must not /// exceed 200 uS. The value in this field is a constant that must /// not be modified after the Metronome architectural protocol is /// installed. All consumers must treat this as a read-only field. /// UINT32 TickPeriod; }; extern EFI_GUID gEfiMetronomeArchProtocolGuid; #endif /** @file Monotonic Counter Architectural Protocol as defined in PI SPEC VOLUME 2 DXE This code provides the services required to access the system's monotonic counter Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_MONTONIC_COUNTER_H__ #define __ARCH_PROTOCOL_MONTONIC_COUNTER_H__ /// /// Global ID for the Monotonic Counter Architectural Protocol. /// #define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \ {0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} } extern EFI_GUID gEfiMonotonicCounterArchProtocolGuid; #endif /** @file When installed, the MP Services Protocol produces a collection of services that are needed for MP management. The MP Services Protocol provides a generalized way of performing following tasks: - Retrieving information of multi-processor environment and MP-related status of specific processors. - Dispatching user-provided function to APs. - Maintain MP-related processor status. The MP Services Protocol must be produced on any system with more than one logical processor. The Protocol is available only during boot time. MP Services Protocol is hardware-independent. Most of the logic of this protocol is architecturally neutral. It abstracts the multi-processor environment and status of processors, and provides interfaces to retrieve information, maintain, and dispatch. MP Services Protocol may be consumed by ACPI module. The ACPI module may use this protocol to retrieve data that are needed for an MP platform and report them to OS. MP Services Protocol may also be used to program and configure processors, such as MTRR synchronization for memory space attributes setting in DXE Services. MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot by taking advantage of the processing capabilities of the APs, for example, using APs to help test system memory in parallel with other device initialization. Diagnostics applications may also use this protocol for multi-processor. Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is defined in the UEFI Platform Initialization Specification 1.2, Volume 2:Driver Execution Environment Core Interface. **/ #ifndef _MP_SERVICE_PROTOCOL_H_ #define _MP_SERVICE_PROTOCOL_H_ /// /// Global ID for the EFI_MP_SERVICES_PROTOCOL. /// #define EFI_MP_SERVICES_PROTOCOL_GUID \ { \ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} \ } /// /// Value used in the NumberProcessors parameter of the GetProcessorInfo function /// #define CPU_V2_EXTENDED_TOPOLOGY BIT24 /// /// Forward declaration for the EFI_MP_SERVICES_PROTOCOL. /// typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL; /// /// Terminator for a list of failed CPUs returned by StartAllAPs(). /// #define END_OF_CPU_LIST 0xffffffff /// /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and /// indicates whether the processor is playing the role of BSP. If the bit is 1, /// then the processor is BSP. Otherwise, it is AP. /// #define PROCESSOR_AS_BSP_BIT 0x00000001 /// /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and /// indicates whether the processor is enabled. If the bit is 1, then the /// processor is enabled. Otherwise, it is disabled. /// #define PROCESSOR_ENABLED_BIT 0x00000002 /// /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and /// indicates whether the processor is healthy. If the bit is 1, then the /// processor is healthy. Otherwise, some fault has been detected for the processor. /// #define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 /// /// Structure that describes the pyhiscal location of a logical CPU. /// typedef struct { /// /// Zero-based physical package number that identifies the cartridge of the processor. /// UINT32 Package; /// /// Zero-based physical core number within package of the processor. /// UINT32 Core; /// /// Zero-based logical thread number within core of the processor. /// UINT32 Thread; } EFI_CPU_PHYSICAL_LOCATION; /// /// Structure that defines the 6-level physical location of the processor /// typedef struct { /// /// Package Zero-based physical package number that identifies the cartridge of the processor. /// UINT32 Package; /// /// Module Zero-based physical module number within package of the processor. /// UINT32 Module; /// /// Tile Zero-based physical tile number within module of the processor. /// UINT32 Tile; /// /// Die Zero-based physical die number within tile of the processor. /// UINT32 Die; /// /// Core Zero-based physical core number within die of the processor. /// UINT32 Core; /// /// Thread Zero-based logical thread number within core of the processor. /// UINT32 Thread; } EFI_CPU_PHYSICAL_LOCATION2; typedef union { /// The 6-level physical location of the processor, including the /// physical package number that identifies the cartridge, the physical /// module number within package, the physical tile number within the module, /// the physical die number within the tile, the physical core number within /// package, and logical thread number within core. EFI_CPU_PHYSICAL_LOCATION2 Location2; } EXTENDED_PROCESSOR_INFORMATION; /// /// Structure that describes information about a logical CPU. /// typedef struct { /// /// The unique processor ID determined by system hardware. For IA32 and X64, /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits /// are used, and higher bits are reserved. For IPF, the lower 16 bits contains /// id/eid, and higher bits are reserved. /// UINT64 ProcessorId; /// /// Flags indicating if the processor is BSP or AP, if the processor is enabled /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and /// must be 0. /// ///
  /// BSP  ENABLED  HEALTH  Description
  /// ===  =======  ======  ===================================================
  ///  0      0       0     Unhealthy Disabled AP.
  ///  0      0       1     Healthy Disabled AP.
  ///  0      1       0     Unhealthy Enabled AP.
  ///  0      1       1     Healthy Enabled AP.
  ///  1      0       0     Invalid. The BSP can never be in the disabled state.
  ///  1      0       1     Invalid. The BSP can never be in the disabled state.
  ///  1      1       0     Unhealthy Enabled BSP.
  ///  1      1       1     Healthy Enabled BSP.
  /// 
/// UINT32 StatusFlag; /// /// The physical location of the processor, including the physical package number /// that identifies the cartridge, the physical core number within package, and /// logical thread number within core. /// EFI_CPU_PHYSICAL_LOCATION Location; /// /// The extended information of the processor. This field is filled only when /// CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber. EXTENDED_PROCESSOR_INFORMATION ExtendedInformation; } EFI_PROCESSOR_INFORMATION; /** This service retrieves the number of logical processor in the platform and the number of those logical processors that are enabled on this boot. This service may only be called from the BSP. This function is used to retrieve the following information: - The number of logical processors that are present in the system. - The number of enabled logical processors in the system at the instant this call is made. Because MP Service Protocol provides services to enable and disable processors dynamically, the number of enabled logical processors may vary during the course of a boot session. If this service is called from an AP, then EFI_DEVICE_ERROR is returned. If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors is returned in NumberOfProcessors, the number of currently enabled processor is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[out] NumberOfProcessors Pointer to the total number of logical processors in the system, including the BSP and disabled APs. @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical processors that exist in system, including the BSP. @retval EFI_SUCCESS The number of logical processors and enabled logical processors was retrieved. @retval EFI_DEVICE_ERROR The calling processor is an AP. @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)( IN EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *NumberOfProcessors, OUT UINTN *NumberOfEnabledProcessors ); /** Gets detailed MP-related information on the requested processor at the instant this call is made. This service may only be called from the BSP. This service retrieves detailed MP-related information about any processor on the platform. Note the following: - The processor information may change during the course of a boot session. - The information presented here is entirely MP related. Information regarding the number of caches and their sizes, frequency of operation, slot numbers is all considered platform-related information and is not provided by this service. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] ProcessorNumber The handle number of processor. @param[out] ProcessorInfoBuffer A pointer to the buffer where information for the requested processor is deposited. @retval EFI_SUCCESS Processor information was returned. @retval EFI_DEVICE_ERROR The calling processor is an AP. @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist in the platform. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)( IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer ); /** This service executes a caller provided function on all enabled APs. APs can run either simultaneously or one at a time in sequence. This service supports both blocking and non-blocking requests. The non-blocking requests use EFI events so the BSP can detect when the APs have finished. This service may only be called from the BSP. This function is used to dispatch all the enabled APs to the function specified by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned immediately and Procedure is not started on any AP. If SingleThread is TRUE, all the enabled APs execute the function specified by Procedure one by one, in ascending order of processor handle number. Otherwise, all the enabled APs execute the function specified by Procedure simultaneously. If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking mode, and the BSP returns from this service without waiting for APs. If a non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, then EFI_UNSUPPORTED must be returned. If the timeout specified by TimeoutInMicroseconds expires before all APs return from Procedure, then Procedure on the failed APs is terminated. All enabled APs are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its content points to the list of processor handle numbers in which Procedure was terminated. Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() to make sure that the nature of the code that is executed on the BSP and the dispatched APs is well controlled. The MP Services Protocol does not guarantee that the Procedure function is MP-safe. Hence, the tasks that can be run in parallel are limited to certain independent tasks and well-controlled exclusive code. EFI services and protocols may not be called by APs unless otherwise specified. In blocking execution mode, BSP waits until all APs finish or TimeoutInMicroSeconds expires. In non-blocking execution mode, BSP is freed to return to the caller and then proceed to the next task without having to wait for APs. The following sequence needs to occur in a non-blocking execution mode: -# The caller that intends to use this MP Services Protocol in non-blocking mode creates WaitEvent by calling the EFI CreateEvent() service. The caller invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests the function specified by Procedure to be started on all the enabled APs, and releases the BSP to continue with other tasks. -# The caller can use the CheckEvent() and WaitForEvent() services to check the state of the WaitEvent created in step 1. -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP Service signals WaitEvent by calling the EFI SignalEvent() function. If FailedCpuList is not NULL, its content is available when WaitEvent is signaled. If all APs returned from Procedure prior to the timeout, then FailedCpuList is set to NULL. If not all APs return from Procedure before the timeout, then FailedCpuList is filled in with the list of the failed APs. The buffer is allocated by MP Service Protocol using AllocatePool(). It is the caller's responsibility to free the buffer with FreePool() service. -# This invocation of SignalEvent() function informs the caller that invoked EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed the specified task or a timeout occurred. The contents of FailedCpuList can be examined to determine which APs did not complete the specified task prior to the timeout. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] Procedure A pointer to the function to be run on enabled APs of the system. See type EFI_AP_PROCEDURE. @param[in] SingleThread If TRUE, then all the enabled APs execute the function specified by Procedure one by one, in ascending order of processor handle number. If FALSE, then all the enabled APs execute the function specified by Procedure simultaneously. @param[in] WaitEvent The event created by the caller with CreateEvent() service. If it is NULL, then execute in blocking mode. BSP waits until all APs finish or TimeoutInMicroSeconds expires. If it's not NULL, then execute in non-blocking mode. BSP requests the function specified by Procedure to be started on all the enabled APs, and go on executing immediately. If all return from Procedure, or TimeoutInMicroSeconds expires, this event is signaled. The BSP can use the CheckEvent() or WaitForEvent() services to check the state of event. Type EFI_EVENT is defined in CreateEvent() in the Unified Extensible Firmware Interface Specification. @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for APs to return from Procedure, either for blocking or non-blocking mode. Zero means infinity. If the timeout expires before all APs return from Procedure, then Procedure on the failed APs is terminated. All enabled APs are available for next function assigned by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If the timeout expires in blocking mode, BSP returns EFI_TIMEOUT. If the timeout expires in non-blocking mode, WaitEvent is signaled with SignalEvent(). @param[in] ProcedureArgument The parameter passed into Procedure for all APs. @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, if all APs finish successfully, then its content is set to NULL. If not all APs finish before timeout expires, then its content is set to address of the buffer holding handle numbers of the failed APs. The buffer is allocated by MP Service Protocol, and it's the caller's responsibility to free the buffer with FreePool() service. In blocking mode, it is ready for consumption when the call returns. In non-blocking mode, it is ready when WaitEvent is signaled. The list of failed CPU is terminated by END_OF_CPU_LIST. @retval EFI_SUCCESS In blocking mode, all APs have finished before the timeout expired. @retval EFI_SUCCESS In non-blocking mode, function has been dispatched to all enabled APs. @retval EFI_UNSUPPORTED A non-blocking mode request was made after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was signaled. @retval EFI_DEVICE_ERROR Caller processor is AP. @retval EFI_NOT_STARTED No enabled APs exist in the system. @retval EFI_NOT_READY Any enabled APs are busy. @retval EFI_TIMEOUT In blocking mode, the timeout expired before all enabled APs have finished. @retval EFI_INVALID_PARAMETER Procedure is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)( IN EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroSeconds, IN VOID *ProcedureArgument OPTIONAL, OUT UINTN **FailedCpuList OPTIONAL ); /** This service lets the caller get one enabled AP to execute a caller-provided function. The caller can request the BSP to either wait for the completion of the AP or just proceed with the next task by using the EFI event mechanism. See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking execution support. This service may only be called from the BSP. This function is used to dispatch one enabled AP to the function specified by Procedure passing in the argument specified by ProcedureArgument. If WaitEvent is NULL, execution is in blocking mode. The BSP waits until the AP finishes or TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode. BSP proceeds to the next task without waiting for the AP. If a non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, then EFI_UNSUPPORTED must be returned. If the timeout specified by TimeoutInMicroseconds expires before the AP returns from Procedure, then execution of Procedure by the AP is terminated. The AP is available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] Procedure A pointer to the function to be run on the designated AP of the system. See type EFI_AP_PROCEDURE. @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @param[in] WaitEvent The event created by the caller with CreateEvent() service. If it is NULL, then execute in blocking mode. BSP waits until this AP finish or TimeoutInMicroSeconds expires. If it's not NULL, then execute in non-blocking mode. BSP requests the function specified by Procedure to be started on this AP, and go on executing immediately. If this AP return from Procedure or TimeoutInMicroSeconds expires, this event is signaled. The BSP can use the CheckEvent() or WaitForEvent() services to check the state of event. Type EFI_EVENT is defined in CreateEvent() in the Unified Extensible Firmware Interface Specification. @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for this AP to finish this Procedure, either for blocking or non-blocking mode. Zero means infinity. If the timeout expires before this AP returns from Procedure, then Procedure on the AP is terminated. The AP is available for next function assigned by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If the timeout expires in blocking mode, BSP returns EFI_TIMEOUT. If the timeout expires in non-blocking mode, WaitEvent is signaled with SignalEvent(). @param[in] ProcedureArgument The parameter passed into Procedure on the specified AP. @param[out] Finished If NULL, this parameter is ignored. In blocking mode, this parameter is ignored. In non-blocking mode, if AP returns from Procedure before the timeout expires, its content is set to TRUE. Otherwise, the value is set to FALSE. The caller can determine if the AP returned from Procedure by evaluating this value. @retval EFI_SUCCESS In blocking mode, specified AP finished before the timeout expires. @retval EFI_SUCCESS In non-blocking mode, the function has been dispatched to specified AP. @retval EFI_UNSUPPORTED A non-blocking mode request was made after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was signaled. @retval EFI_DEVICE_ERROR The calling processor is an AP. @retval EFI_TIMEOUT In blocking mode, the timeout expired before the specified AP has finished. @retval EFI_NOT_READY The specified AP is busy. @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. @retval EFI_INVALID_PARAMETER Procedure is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)( IN EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT BOOLEAN *Finished OPTIONAL ); /** This service switches the requested AP to be the BSP from that point onward. This service changes the BSP for all purposes. This call can only be performed by the current BSP. This service switches the requested AP to be the BSP from that point onward. This service changes the BSP for all purposes. The new BSP can take over the execution of the old BSP and continue seamlessly from where the old one left off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. If the BSP cannot be switched prior to the return from this service, then EFI_UNSUPPORTED must be returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled AP. Otherwise, it will be disabled. @retval EFI_SUCCESS BSP successfully switched. @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this service returning. @retval EFI_UNSUPPORTED Switching the BSP is not supported. @retval EFI_DEVICE_ERROR The calling processor is an AP. @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled AP. @retval EFI_NOT_READY The specified AP is busy. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)( IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableOldBSP ); /** This service lets the caller enable or disable an AP from this point onward. This service may only be called from the BSP. This service allows the caller enable or disable an AP from this point onward. The caller can optionally specify the health status of the AP by Health. If an AP is being disabled, then the state of the disabled AP is implementation dependent. If an AP is enabled, then the implementation must guarantee that a complete initialization sequence is performed on the AP, so the AP is in a state that is compatible with an MP operating system. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. If the enable or disable AP operation cannot be completed prior to the return from this service, then EFI_UNSUPPORTED must be returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] ProcessorNumber The handle number of AP. The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @param[in] EnableAP Specifies the new state for the processor for enabled, FALSE for disabled. @param[in] HealthFlag If not NULL, a pointer to a value that specifies the new health status of the AP. This flag corresponds to StatusFlag defined in EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other bits are ignored. If it is NULL, this parameter is ignored. @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior to this service returning. @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. @retval EFI_DEVICE_ERROR The calling processor is an AP. @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber does not exist. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)( IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL ); /** This return the handle number for the calling processor. This service may be called from the BSP and APs. This service returns the processor handle number for the calling processor. The returned value is in the range from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER is returned. Otherwise, the current processors handle number is returned in ProcessorNumber, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. @param[in] ProcessorNumber Pointer to the handle number of AP. The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @retval EFI_SUCCESS The current processor handle number was returned in ProcessorNumber. @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_WHOAMI)( IN EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *ProcessorNumber ); /// /// When installed, the MP Services Protocol produces a collection of services /// that are needed for MP management. /// /// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module /// that produces this protocol is required to place all APs into an idle state /// whenever the APs are disabled or the APs are not executing code as requested /// through the StartupAllAPs() or StartupThisAP() services. The idle state of /// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is /// implementation dependent. /// /// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs /// must be placed in the OS compatible CPU state as defined by the UEFI /// Specification. Implementations of this protocol may use the UEFI event /// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as /// defined by the UEFI Specification. Modules that use this protocol must /// guarantee that all non-blocking mode requests on all APs have been completed /// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the /// order that event notification functions in the same event group are executed /// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot /// be used to guarantee that APs have completed their non-blocking mode requests. /// /// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs() /// and StartupThisAp() services must no longer support non-blocking mode requests. /// The support for SwitchBSP() and EnableDisableAP() may no longer be supported /// after this event is signaled. Since UEFI Applications and UEFI OS Loaders /// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these /// UEFI images must be aware that the functionality of this protocol may be reduced. /// struct _EFI_MP_SERVICES_PROTOCOL { EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors; EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo; EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs; EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP; EFI_MP_SERVICES_SWITCH_BSP SwitchBSP; EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP; EFI_MP_SERVICES_WHOAMI WhoAmI; }; extern EFI_GUID gEfiMpServiceProtocolGuid; #endif /** @file EFI Multicast Trivial File Transfer Protocol Definition Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0 **/ #ifndef __EFI_MTFTP4_PROTOCOL_H__ #define __EFI_MTFTP4_PROTOCOL_H__ #define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F } \ } #define EFI_MTFTP4_PROTOCOL_GUID \ { \ 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b } \ } typedef struct _EFI_MTFTP4_PROTOCOL EFI_MTFTP4_PROTOCOL; typedef struct _EFI_MTFTP4_TOKEN EFI_MTFTP4_TOKEN; // // MTFTP4 packet opcode definition // #define EFI_MTFTP4_OPCODE_RRQ 1 #define EFI_MTFTP4_OPCODE_WRQ 2 #define EFI_MTFTP4_OPCODE_DATA 3 #define EFI_MTFTP4_OPCODE_ACK 4 #define EFI_MTFTP4_OPCODE_ERROR 5 #define EFI_MTFTP4_OPCODE_OACK 6 #define EFI_MTFTP4_OPCODE_DIR 7 #define EFI_MTFTP4_OPCODE_DATA8 8 #define EFI_MTFTP4_OPCODE_ACK8 9 // // MTFTP4 error code definition // #define EFI_MTFTP4_ERRORCODE_NOT_DEFINED 0 #define EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND 1 #define EFI_MTFTP4_ERRORCODE_ACCESS_VIOLATION 2 #define EFI_MTFTP4_ERRORCODE_DISK_FULL 3 #define EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION 4 #define EFI_MTFTP4_ERRORCODE_UNKNOWN_TRANSFER_ID 5 #define EFI_MTFTP4_ERRORCODE_FILE_ALREADY_EXISTS 6 #define EFI_MTFTP4_ERRORCODE_NO_SUCH_USER 7 #define EFI_MTFTP4_ERRORCODE_REQUEST_DENIED 8 // // MTFTP4 pacekt definitions // #pragma pack(1) typedef struct { UINT16 OpCode; UINT8 Filename[1]; } EFI_MTFTP4_REQ_HEADER; typedef struct { UINT16 OpCode; UINT8 Data[1]; } EFI_MTFTP4_OACK_HEADER; typedef struct { UINT16 OpCode; UINT16 Block; UINT8 Data[1]; } EFI_MTFTP4_DATA_HEADER; typedef struct { UINT16 OpCode; UINT16 Block[1]; } EFI_MTFTP4_ACK_HEADER; typedef struct { UINT16 OpCode; UINT64 Block; UINT8 Data[1]; } EFI_MTFTP4_DATA8_HEADER; typedef struct { UINT16 OpCode; UINT64 Block[1]; } EFI_MTFTP4_ACK8_HEADER; typedef struct { UINT16 OpCode; UINT16 ErrorCode; UINT8 ErrorMessage[1]; } EFI_MTFTP4_ERROR_HEADER; typedef union { /// /// Type of packets as defined by the MTFTPv4 packet opcodes. /// UINT16 OpCode; /// /// Read request packet header. /// EFI_MTFTP4_REQ_HEADER Rrq; /// /// Write request packet header. /// EFI_MTFTP4_REQ_HEADER Wrq; /// /// Option acknowledge packet header. /// EFI_MTFTP4_OACK_HEADER Oack; /// /// Data packet header. /// EFI_MTFTP4_DATA_HEADER Data; /// /// Acknowledgement packet header. /// EFI_MTFTP4_ACK_HEADER Ack; /// /// Data packet header with big block number. /// EFI_MTFTP4_DATA8_HEADER Data8; /// /// Acknowledgement header with big block num. /// EFI_MTFTP4_ACK8_HEADER Ack8; /// /// Error packet header. /// EFI_MTFTP4_ERROR_HEADER Error; } EFI_MTFTP4_PACKET; #pragma pack() /// /// MTFTP4 option definition. /// typedef struct { UINT8 *OptionStr; UINT8 *ValueStr; } EFI_MTFTP4_OPTION; typedef struct { BOOLEAN UseDefaultSetting; EFI_IPv4_ADDRESS StationIp; EFI_IPv4_ADDRESS SubnetMask; UINT16 LocalPort; EFI_IPv4_ADDRESS GatewayIp; EFI_IPv4_ADDRESS ServerIp; UINT16 InitialServerPort; UINT16 TryCount; UINT16 TimeoutValue; } EFI_MTFTP4_CONFIG_DATA; typedef struct { EFI_MTFTP4_CONFIG_DATA ConfigData; UINT8 SupportedOptionCount; UINT8 **SupportedOptoins; UINT8 UnsupportedOptionCount; UINT8 **UnsupportedOptoins; } EFI_MTFTP4_MODE_DATA; typedef struct { EFI_IPv4_ADDRESS GatewayIp; EFI_IPv4_ADDRESS ServerIp; UINT16 ServerPort; UINT16 TryCount; UINT16 TimeoutValue; } EFI_MTFTP4_OVERRIDE_DATA; // // Protocol interfaces definition // /** A callback function that is provided by the caller to intercept the EFI_MTFTP4_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory(). @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The token that the caller provided in the EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory() function. @param PacketLen Indicates the length of the packet. @param Packet The pointer to an MTFTPv4 packet. @retval EFI_SUCCESS The operation was successful. @retval Others Aborts the transfer process. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_CHECK_PACKET)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token, IN UINT16 PacketLen, IN EFI_MTFTP4_PACKET *Paket ); /** Timeout callback function. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The token that is provided in the EFI_MTFTP4_PROTOCOL.ReadFile() or EFI_MTFTP4_PROTOCOL.WriteFile() or EFI_MTFTP4_PROTOCOL.ReadDirectory() functions by the caller. @retval EFI_SUCCESS The operation was successful. @retval Others Aborts download process. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_TIMEOUT_CALLBACK)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token ); /** A callback function that the caller provides to feed data to the EFI_MTFTP4_PROTOCOL.WriteFile() function. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The token provided in the EFI_MTFTP4_PROTOCOL.WriteFile() by the caller. @param Length Indicates the length of the raw data wanted on input, and the length the data available on output. @param Buffer The pointer to the buffer where the data is stored. @retval EFI_SUCCESS The operation was successful. @retval Others Aborts session. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_PACKET_NEEDED)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token, IN OUT UINT16 *Length, OUT VOID **Buffer ); /** Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param ModeData The pointer to storage for the EFI MTFTPv4 Protocol driver mode data. @retval EFI_SUCCESS The configuration data was successfully returned. @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_GET_MODE_DATA)( IN EFI_MTFTP4_PROTOCOL *This, OUT EFI_MTFTP4_MODE_DATA *ModeData ); /** Initializes, changes, or resets the default operational setting for this EFI MTFTPv4 Protocol driver instance. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param MtftpConfigData The pointer to the configuration data structure. @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured successfully. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this time because there is one MTFTP background operation in progress. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) has not finished yet. @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.) could not be located when clients choose to use the default address settings. @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI MTFTPv4 Protocol driver instance is not configured. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_CONFIGURE)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_CONFIG_DATA *MtftpConfigData OPTIONAL ); /** Gets information about a file from an MTFTPv4 server. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param OverrideData Data that is used to override the existing parameters. If NULL, the default parameters that were set in the EFI_MTFTP4_PROTOCOL.Configure() function are used. @param Filename The pointer to null-terminated ASCII file name string. @param ModeStr The pointer to null-terminated ASCII mode string. If NULL, "octet" will be used. @param OptionCount Number of option/value string pairs in OptionList. @param OptionList The pointer to array of option/value string pairs. Ignored if OptionCount is zero. @param PacketLength The number of bytes in the returned packet. @param Packet The pointer to the received packet. This buffer must be freed by the caller. @retval EFI_SUCCESS An MTFTPv4 OACK packet was received and is in the Packet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Filename is NULL. - OptionCount is not zero and OptionList is NULL. - One or more options in OptionList have wrong format. - PacketLength is NULL. - One or more IPv4 addresses in OverrideData are not valid unicast IPv4 addresses if OverrideData is not NULL. @retval EFI_UNSUPPORTED One or more options in the OptionList are in the unsupported list of structure EFI_MTFTP4_MODE_DATA. @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) has not finished yet. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received and is in the Packet. @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received and the Packet is set to NULL. @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received and the Packet is set to NULL. @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received and the Packet is set to NULL. @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received and the Packet is set to NULL. @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received and is in the Buffer. @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv4 packet was received and is in the Packet. @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_GET_INFO)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData OPTIONAL, IN UINT8 *Filename, IN UINT8 *ModeStr OPTIONAL, IN UINT8 OptionCount, IN EFI_MTFTP4_OPTION *OptionList, OUT UINT32 *PacketLength, OUT EFI_MTFTP4_PACKET **Packet OPTIONAL ); /** Parses the options in an MTFTPv4 OACK packet. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param PacketLen Length of the OACK packet to be parsed. @param Packet The pointer to the OACK packet to be parsed. @param OptionCount The pointer to the number of options in following OptionList. @param OptionList The pointer to EFI_MTFTP4_OPTION storage. Call the EFI Boot Service FreePool() to release the OptionList if the options in this OptionList are not needed any more. @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and OptionList parameters have been updated. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - PacketLen is 0. - Packet is NULL or Packet is not a valid MTFTPv4 packet. - OptionCount is NULL. @retval EFI_NOT_FOUND No options were found in the OACK packet. @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated. @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_PARSE_OPTIONS)( IN EFI_MTFTP4_PROTOCOL *This, IN UINT32 PacketLen, IN EFI_MTFTP4_PACKET *Packet, OUT UINT32 *OptionCount, OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL ); /** Downloads a file from an MTFTPv4 server. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The data file has been transferred successfully. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_BUFFER_TOO_SMALL BufferSize is not zero but not large enough to hold the downloaded data in downloading process. @retval EFI_ABORTED Current operation is aborted by user. @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received. @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received. @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received. @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received. @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received. @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_READ_FILE)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token ); /** Sends a file to an MTFTPv4 server. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The upload session has started. @retval EFI_UNSUPPORTED The operation is not supported by this implementation. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the unsupported list of structure EFI_MTFTP4_MODE_DATA. @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 session. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_WRITE_FILE)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token ); /** Downloads a data file "directory" from an MTFTPv4 server. May be unsupported in some EFI implementations. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @param Token The pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The MTFTPv4 related file "directory" has been downloaded. @retval EFI_UNSUPPORTED The operation is not supported by this implementation. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the unsupported list of structure EFI_MTFTP4_MODE_DATA. @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 session. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_READ_DIRECTORY)( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token ); /** Polls for incoming data packets and processes outgoing data packets. @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_NOT_STARTED This EFI MTFTPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP4_POLL)( IN EFI_MTFTP4_PROTOCOL *This ); /// /// The EFI_MTFTP4_PROTOCOL is designed to be used by UEFI drivers and applications /// to transmit and receive data files. The EFI MTFTPv4 Protocol driver uses /// the underlying EFI UDPv4 Protocol driver and EFI IPv4 Protocol driver. /// struct _EFI_MTFTP4_PROTOCOL { EFI_MTFTP4_GET_MODE_DATA GetModeData; EFI_MTFTP4_CONFIGURE Configure; EFI_MTFTP4_GET_INFO GetInfo; EFI_MTFTP4_PARSE_OPTIONS ParseOptions; EFI_MTFTP4_READ_FILE ReadFile; EFI_MTFTP4_WRITE_FILE WriteFile; EFI_MTFTP4_READ_DIRECTORY ReadDirectory; EFI_MTFTP4_POLL Poll; }; struct _EFI_MTFTP4_TOKEN { /// /// The status that is returned to the caller at the end of the operation /// to indicate whether this operation completed successfully. /// EFI_STATUS Status; /// /// The event that will be signaled when the operation completes. If /// set to NULL, the corresponding function will wait until the read or /// write operation finishes. The type of Event must be /// EVT_NOTIFY_SIGNAL. The Task Priority Level (TPL) of /// Event must be lower than or equal to TPL_CALLBACK. /// EFI_EVENT Event; /// /// If not NULL, the data that will be used to override the existing configure data. /// EFI_MTFTP4_OVERRIDE_DATA *OverrideData; /// /// The pointer to the null-terminated ASCII file name string. /// UINT8 *Filename; /// /// The pointer to the null-terminated ASCII mode string. If NULL, "octet" is used. /// UINT8 *ModeStr; /// /// Number of option/value string pairs. /// UINT32 OptionCount; /// /// The pointer to an array of option/value string pairs. Ignored if OptionCount is zero. /// EFI_MTFTP4_OPTION *OptionList; /// /// The size of the data buffer. /// UINT64 BufferSize; /// /// The pointer to the data buffer. Data that is downloaded from the /// MTFTPv4 server is stored here. Data that is uploaded to the /// MTFTPv4 server is read from here. Ignored if BufferSize is zero. /// VOID *Buffer; /// /// The pointer to the context that will be used by CheckPacket, /// TimeoutCallback and PacketNeeded. /// VOID *Context; /// /// The pointer to the callback function to check the contents of the received packet. /// EFI_MTFTP4_CHECK_PACKET CheckPacket; /// /// The pointer to the function to be called when a timeout occurs. /// EFI_MTFTP4_TIMEOUT_CALLBACK TimeoutCallback; /// /// The pointer to the function to provide the needed packet contents. /// EFI_MTFTP4_PACKET_NEEDED PacketNeeded; }; extern EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid; extern EFI_GUID gEfiMtftp4ProtocolGuid; #endif /** @file UEFI Multicast Trivial File Transfer Protocol v6 Definition, which is built upon the EFI UDPv6 Protocol and provides basic services for client-side unicast and/or multicast TFTP operations. Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_MTFTP6_PROTOCOL_H__ #define __EFI_MTFTP6_PROTOCOL_H__ #define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23 } \ } #define EFI_MTFTP6_PROTOCOL_GUID \ { \ 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51 } \ } typedef struct _EFI_MTFTP6_PROTOCOL EFI_MTFTP6_PROTOCOL; typedef struct _EFI_MTFTP6_TOKEN EFI_MTFTP6_TOKEN; /// /// MTFTP Packet OpCodes ///@{ #define EFI_MTFTP6_OPCODE_RRQ 1 ///< The MTFTPv6 packet is a read request. #define EFI_MTFTP6_OPCODE_WRQ 2 ///< The MTFTPv6 packet is a write request. #define EFI_MTFTP6_OPCODE_DATA 3 ///< The MTFTPv6 packet is a data packet. #define EFI_MTFTP6_OPCODE_ACK 4 ///< The MTFTPv6 packet is an acknowledgement packet. #define EFI_MTFTP6_OPCODE_ERROR 5 ///< The MTFTPv6 packet is an error packet. #define EFI_MTFTP6_OPCODE_OACK 6 ///< The MTFTPv6 packet is an option acknowledgement packet. #define EFI_MTFTP6_OPCODE_DIR 7 ///< The MTFTPv6 packet is a directory query packet. #define EFI_MTFTP6_OPCODE_DATA8 8 ///< The MTFTPv6 packet is a data packet with a big block number. #define EFI_MTFTP6_OPCODE_ACK8 9 ///< The MTFTPv6 packet is an acknowledgement packet with a big block number. ///@} /// /// MTFTP ERROR Packet ErrorCodes ///@{ /// /// The error code is not defined. See the error message in the packet (if any) for details. /// #define EFI_MTFTP6_ERRORCODE_NOT_DEFINED 0 /// /// The file was not found. /// #define EFI_MTFTP6_ERRORCODE_FILE_NOT_FOUND 1 /// /// There was an access violation. /// #define EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION 2 /// /// The disk was full or its allocation was exceeded. /// #define EFI_MTFTP6_ERRORCODE_DISK_FULL 3 /// /// The MTFTPv6 operation was illegal. /// #define EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION 4 /// /// The transfer ID is unknown. /// #define EFI_MTFTP6_ERRORCODE_UNKNOWN_TRANSFER_ID 5 /// /// The file already exists. /// #define EFI_MTFTP6_ERRORCODE_FILE_ALREADY_EXISTS 6 /// /// There is no such user. /// #define EFI_MTFTP6_ERRORCODE_NO_SUCH_USER 7 /// /// The request has been denied due to option negotiation. /// #define EFI_MTFTP6_ERRORCODE_REQUEST_DENIED 8 ///@} #pragma pack(1) /// /// EFI_MTFTP6_REQ_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_RRQ for a read request /// or OpCode = EFI_MTFTP6_OPCODE_WRQ for a write request. /// UINT16 OpCode; /// /// The file name to be downloaded or uploaded. /// UINT8 Filename[1]; } EFI_MTFTP6_REQ_HEADER; /// /// EFI_MTFTP6_OACK_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_OACK. /// UINT16 OpCode; /// /// The option strings in the option acknowledgement packet. /// UINT8 Data[1]; } EFI_MTFTP6_OACK_HEADER; /// /// EFI_MTFTP6_DATA_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA. /// UINT16 OpCode; /// /// Block number of this data packet. /// UINT16 Block; /// /// The content of this data packet. /// UINT8 Data[1]; } EFI_MTFTP6_DATA_HEADER; /// /// EFI_MTFTP6_ACK_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK. /// UINT16 OpCode; /// /// The block number of the data packet that is being acknowledged. /// UINT16 Block[1]; } EFI_MTFTP6_ACK_HEADER; /// /// EFI_MTFTP6_DATA8_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA8. /// UINT16 OpCode; /// /// The block number of data packet. /// UINT64 Block; /// /// The content of this data packet. /// UINT8 Data[1]; } EFI_MTFTP6_DATA8_HEADER; /// /// EFI_MTFTP6_ACK8_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK8. /// UINT16 OpCode; /// /// The block number of the data packet that is being acknowledged. /// UINT64 Block[1]; } EFI_MTFTP6_ACK8_HEADER; /// /// EFI_MTFTP6_ERROR_HEADER /// typedef struct { /// /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ERROR. /// UINT16 OpCode; /// /// The error number as defined by the MTFTPv6 packet error codes. /// UINT16 ErrorCode; /// /// Error message string. /// UINT8 ErrorMessage[1]; } EFI_MTFTP6_ERROR_HEADER; /// /// EFI_MTFTP6_PACKET /// typedef union { UINT16 OpCode; ///< Type of packets as defined by the MTFTPv6 packet opcodes. EFI_MTFTP6_REQ_HEADER Rrq; ///< Read request packet header. EFI_MTFTP6_REQ_HEADER Wrq; ///< write request packet header. EFI_MTFTP6_OACK_HEADER Oack; ///< Option acknowledge packet header. EFI_MTFTP6_DATA_HEADER Data; ///< Data packet header. EFI_MTFTP6_ACK_HEADER Ack; ///< Acknowledgement packet header. EFI_MTFTP6_DATA8_HEADER Data8; ///< Data packet header with big block number. EFI_MTFTP6_ACK8_HEADER Ack8; ///< Acknowledgement header with big block number. EFI_MTFTP6_ERROR_HEADER Error; ///< Error packet header. } EFI_MTFTP6_PACKET; #pragma pack() /// /// EFI_MTFTP6_CONFIG_DATA /// typedef struct { /// /// The local IP address to use. Set to zero to let the underlying IPv6 /// driver choose a source address. If not zero it must be one of the /// configured IP addresses in the underlying IPv6 driver. /// EFI_IPv6_ADDRESS StationIp; /// /// Local port number. Set to zero to use the automatically assigned port number. /// UINT16 LocalPort; /// /// The IP address of the MTFTPv6 server. /// EFI_IPv6_ADDRESS ServerIp; /// /// The initial MTFTPv6 server port number. Request packets are /// sent to this port. This number is almost always 69 and using zero /// defaults to 69. UINT16 InitialServerPort; /// /// The number of times to transmit MTFTPv6 request packets and wait for a response. /// UINT16 TryCount; /// /// The number of seconds to wait for a response after sending the MTFTPv6 request packet. /// UINT16 TimeoutValue; } EFI_MTFTP6_CONFIG_DATA; /// /// EFI_MTFTP6_MODE_DATA /// typedef struct { /// /// The configuration data of this instance. /// EFI_MTFTP6_CONFIG_DATA ConfigData; /// /// The number of option strings in the following SupportedOptions array. /// UINT8 SupportedOptionCount; /// /// An array of null-terminated ASCII option strings that are recognized and supported by /// this EFI MTFTPv6 Protocol driver implementation. The buffer is /// read only to the caller and the caller should NOT free the buffer. /// UINT8 **SupportedOptions; } EFI_MTFTP6_MODE_DATA; /// /// EFI_MTFTP_OVERRIDE_DATA /// typedef struct { /// /// IP address of the MTFTPv6 server. If set to all zero, the value that /// was set by the EFI_MTFTP6_PROTOCOL.Configure() function will be used. /// EFI_IPv6_ADDRESS ServerIp; /// /// MTFTPv6 server port number. If set to zero, it will use the value /// that was set by the EFI_MTFTP6_PROTOCOL.Configure() function. /// UINT16 ServerPort; /// /// Number of times to transmit MTFTPv6 request packets and wait /// for a response. If set to zero, the value that was set by /// theEFI_MTFTP6_PROTOCOL.Configure() function will be used. /// UINT16 TryCount; /// /// Number of seconds to wait for a response after sending the /// MTFTPv6 request packet. If set to zero, the value that was set by /// the EFI_MTFTP6_PROTOCOL.Configure() function will be used. /// UINT16 TimeoutValue; } EFI_MTFTP6_OVERRIDE_DATA; /// /// EFI_MTFTP6_OPTION /// typedef struct { UINT8 *OptionStr; ///< Pointer to the null-terminated ASCII MTFTPv6 option string. UINT8 *ValueStr; ///< Pointer to the null-terminated ASCII MTFTPv6 value string. } EFI_MTFTP6_OPTION; /** EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or EFI_MTFTP6_PROTOCOL.ReadDirectory() functions. Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS that is returned from this function will abort the current download process. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token The token that the caller provided in the EFI_MTFTP6_PROTOCOl.ReadFile(), WriteFile() or ReadDirectory() function. @param[in] PacketLen Indicates the length of the packet. @param[in] Packet Pointer to an MTFTPv6 packet. @retval EFI_SUCCESS Operation success. @retval Others Aborts session. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_CHECK_PACKET)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token, IN UINT16 PacketLen, IN EFI_MTFTP6_PACKET *Packet ); /** EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or EFI_MTFTP6_PROTOCOL.ReadDirectory() functions. Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS that is returned from this function will abort the current download process. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token The token that is provided in the EFI_MTFTP6_PROTOCOL.ReadFile() or EFI_MTFTP6_PROTOCOL.WriteFile() or EFI_MTFTP6_PROTOCOL.ReadDirectory() functions by the caller. @retval EFI_SUCCESS Operation success. @retval Others Aborts session. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_TIMEOUT_CALLBACK)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token ); /** EFI_MTFTP6_PACKET_NEEDED is a callback function that the caller provides to feed data to the EFI_MTFTP6_PROTOCOL.WriteFile() function. EFI_MTFTP6_PACKET_NEEDED provides another mechanism for the caller to provide data to upload other than a static buffer. The EFI MTFTP6 Protocol driver always calls EFI_MTFTP6_PACKET_NEEDED to get packet data from the caller if no static buffer was given in the initial call to EFI_MTFTP6_PROTOCOL.WriteFile() function. Setting *Length to zero signals the end of the session. Returning a status code other than EFI_SUCCESS aborts the session. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token The token provided in the EFI_MTFTP6_PROTOCOL.WriteFile() by the caller. @param[in, out] Length Indicates the length of the raw data wanted on input, and the length the data available on output. @param[out] Buffer Pointer to the buffer where the data is stored. @retval EFI_SUCCESS Operation success. @retval Others Aborts session. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_PACKET_NEEDED)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token, IN OUT UINT16 *Length, OUT VOID **Buffer ); struct _EFI_MTFTP6_TOKEN { /// /// The status that is returned to the caller at the end of the operation /// to indicate whether this operation completed successfully. /// Defined Status values are listed below. /// EFI_STATUS Status; /// /// The event that will be signaled when the operation completes. If /// set to NULL, the corresponding function will wait until the read or /// write operation finishes. The type of Event must be EVT_NOTIFY_SIGNAL. /// EFI_EVENT Event; /// /// If not NULL, the data that will be used to override the existing /// configure data. /// EFI_MTFTP6_OVERRIDE_DATA *OverrideData; /// /// Pointer to the null-terminated ASCII file name string. /// UINT8 *Filename; /// /// Pointer to the null-terminated ASCII mode string. If NULL, octet is used. /// UINT8 *ModeStr; /// /// Number of option/value string pairs. /// UINT32 OptionCount; /// /// Pointer to an array of option/value string pairs. Ignored if /// OptionCount is zero. Both a remote server and this driver /// implementation should support these options. If one or more /// options are unrecognized by this implementation, it is sent to the /// remote server without being changed. /// EFI_MTFTP6_OPTION *OptionList; /// /// On input, the size, in bytes, of Buffer. On output, the number /// of bytes transferred. /// UINT64 BufferSize; /// /// Pointer to the data buffer. Data that is downloaded from the /// MTFTPv6 server is stored here. Data that is uploaded to the /// MTFTPv6 server is read from here. Ignored if BufferSize is zero. /// VOID *Buffer; /// /// Pointer to the context that will be used by CheckPacket, /// TimeoutCallback and PacketNeeded. /// VOID *Context; /// /// Pointer to the callback function to check the contents of the /// received packet. /// EFI_MTFTP6_CHECK_PACKET CheckPacket; /// /// Pointer to the function to be called when a timeout occurs. /// EFI_MTFTP6_TIMEOUT_CALLBACK TimeoutCallback; /// /// Pointer to the function to provide the needed packet contents. /// Only used in WriteFile() operation. /// EFI_MTFTP6_PACKET_NEEDED PacketNeeded; }; /** Read the current operational settings. The GetModeData() function reads the current operational settings of this EFI MTFTPv6 Protocol driver instance. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[out] ModeData The buffer in which the EFI MTFTPv6 Protocol driver mode data is returned. @retval EFI_SUCCESS The configuration data was successfully returned. @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_GET_MODE_DATA)( IN EFI_MTFTP6_PROTOCOL *This, OUT EFI_MTFTP6_MODE_DATA *ModeData ); /** Initializes, changes, or resets the default operational setting for this EFI MTFTPv6 Protocol driver instance. The Configure() function is used to set and change the configuration data for this EFI MTFTPv6 Protocol driver instance. The configuration data can be reset to startup defaults by calling Configure() with MtftpConfigData set to NULL. Whenever the instance is reset, any pending operation is aborted. By changing the EFI MTFTPv6 Protocol driver instance configuration data, the client can connect to different MTFTPv6 servers. The configuration parameters in MtftpConfigData are used as the default parameters in later MTFTPv6 operations and can be overridden in later operations. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] MtftpConfigData Pointer to the configuration data structure. @retval EFI_SUCCESS The EFI MTFTPv6 Protocol instance was configured successfully. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: - This is NULL. - MtftpConfigData.StationIp is neither zero nor one of the configured IP addresses in the underlying IPv6 driver. - MtftpCofigData.ServerIp is not a valid IPv6 unicast address. @retval EFI_ACCESS_DENIED - The configuration could not be changed at this time because there is some MTFTP background operation in progress. - MtftpCofigData.LocalPort is already in use. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv6 Protocol driver instance data could not be allocated. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI MTFTPv6 Protocol driver instance is not configured. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_CONFIGURE)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_CONFIG_DATA *MtftpConfigData OPTIONAL ); /** Get information about a file from an MTFTPv6 server. The GetInfo() function assembles an MTFTPv6 request packet with options, sends it to the MTFTPv6 server, and may return an MTFTPv6 OACK, MTFTPv6 ERROR, or ICMP ERROR packet. Retries occur only if no response packets are received from the MTFTPv6 server before the timeout expires. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] OverrideData Data that is used to override the existing parameters. If NULL, the default parameters that were set in the EFI_MTFTP6_PROTOCOL.Configure() function are used. @param[in] Filename Pointer to null-terminated ASCII file name string. @param[in] ModeStr Pointer to null-terminated ASCII mode string. If NULL, octet will be used @param[in] OptionCount Number of option/value string pairs in OptionList. @param[in] OptionList Pointer to array of option/value string pairs. Ignored if OptionCount is zero. @param[out] PacketLength The number of bytes in the returned packet. @param[out] Packet The pointer to the received packet. This buffer must be freed by the caller. @retval EFI_SUCCESS An MTFTPv6 OACK packet was received and is in the Packet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Filename is NULL - OptionCount is not zero and OptionList is NULL. - One or more options in OptionList have wrong format. - PacketLength is NULL. - OverrideData.ServerIp is not valid unicast IPv6 addresses. @retval EFI_UNSUPPORTED One or more options in the OptionList are unsupported by this implementation. @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_TFTP_ERROR An MTFTPv6 ERROR packet was received and is in the Packet. @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received and the Packet is set to NULL. @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received and the Packet is set to NULL. @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received and the Packet is set to NULL. @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received and the Packet is set to NULL. @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received and the Packet is set to NULL. @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv6 packet was received and is in the Packet. @retval EFI_TIMEOUT No responses were received from the MTFTPv6 server. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_GET_INFO)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_OVERRIDE_DATA *OverrideData OPTIONAL, IN UINT8 *Filename, IN UINT8 *ModeStr OPTIONAL, IN UINT8 OptionCount, IN EFI_MTFTP6_OPTION *OptionList OPTIONAL, OUT UINT32 *PacketLength, OUT EFI_MTFTP6_PACKET **Packet OPTIONAL ); /** Parse the options in an MTFTPv6 OACK packet. The ParseOptions() function parses the option fields in an MTFTPv6 OACK packet and returns the number of options that were found and optionally a list of pointers to the options in the packet. If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is returned and *OptionCount and *OptionList stop at the last valid option. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] PacketLen Length of the OACK packet to be parsed. @param[in] Packet Pointer to the OACK packet to be parsed. @param[out] OptionCount Pointer to the number of options in the following OptionList. @param[out] OptionList Pointer to EFI_MTFTP6_OPTION storage. Each pointer in the OptionList points to the corresponding MTFTP option buffer in the Packet. Call the EFI Boot Service FreePool() to release the OptionList if the options in this OptionList are not needed any more. @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and OptionList parameters have been updated. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - PacketLen is 0. - Packet is NULL or Packet is not a valid MTFTPv6 packet. - OptionCount is NULL. @retval EFI_NOT_FOUND No options were found in the OACK packet. @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array can not be allocated. @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_PARSE_OPTIONS)( IN EFI_MTFTP6_PROTOCOL *This, IN UINT32 PacketLen, IN EFI_MTFTP6_PACKET *Packet, OUT UINT32 *OptionCount, OUT EFI_MTFTP6_OPTION **OptionList OPTIONAL ); /** Download a file from an MTFTPv6 server. The ReadFile() function is used to initialize and start an MTFTPv6 download process and optionally wait for completion. When the download operation completes, whether successfully or not, the Token.Status field is updated by the EFI MTFTPv6 Protocol driver and then Token.Event is signaled if it is not NULL. Data can be downloaded from the MTFTPv6 server into either of the following locations: - A fixed buffer that is pointed to by Token.Buffer - A download service function that is pointed to by Token.CheckPacket If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket will be called first. If the call is successful, the packet will be stored in Token.Buffer. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token Pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The data file has been transferred successfully. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_BUFFER_TOO_SMALL BufferSize is not zero but not large enough to hold the downloaded data in downloading process. @retval EFI_ABORTED Current operation is aborted by user. @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received. @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received. @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received. @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received. @retval EFI_ICMP_ERROR An ICMP ERROR packet was received. @retval EFI_TIMEOUT No responses were received from the MTFTPv6 server. @retval EFI_TFTP_ERROR An MTFTPv6 ERROR packet was received. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. @retval EFI_NO_MEDIA There was a media error. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_READ_FILE)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token ); /** Send a file to an MTFTPv6 server. May be unsupported in some implementations. The WriteFile() function is used to initialize an uploading operation with the given option list and optionally wait for completion. If one or more of the options is not supported by the server, the unsupported options are ignored and a standard TFTP process starts instead. When the upload process completes, whether successfully or not, Token.Event is signaled, and the EFI MTFTPv6 Protocol driver updates Token.Status. The caller can supply the data to be uploaded in the following two modes: - Through the user-provided buffer - Through a callback function With the user-provided buffer, the Token.BufferSize field indicates the length of the buffer, and the driver will upload the data in the buffer. With an EFI_MTFTP6_PACKET_NEEDED callback function, the driver will call this callback function to get more data from the user to upload. See the definition of EFI_MTFTP6_PACKET_NEEDED for more information. These two modes cannot be used at the same time. The callback function will be ignored if the user provides the buffer. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token Pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The upload session has started. @retval EFI_UNSUPPORTED The operation is not supported by this implementation. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token.Filename is NULL. - Token.OptionCount is not zero and Token.OptionList is NULL. - One or more options in Token.OptionList have wrong format. - Token.Buffer and Token.PacketNeeded are both NULL. - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses. @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are not supported by this implementation. @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv6 session. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_WRITE_FILE)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token ); /** Download a data file directory from an MTFTPv6 server. May be unsupported in some implementations. The ReadDirectory() function is used to return a list of files on the MTFTPv6 server that are logically (or operationally) related to Token.Filename. The directory request packet that is sent to the server is built with the option list that was provided by caller, if present. The file information that the server returns is put into either of the following locations: - A fixed buffer that is pointed to by Token.Buffer - A download service function that is pointed to by Token.CheckPacket If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket will be called first. If the call is successful, the packet will be stored in Token.Buffer. The returned directory listing in the Token.Buffer or EFI_MTFTP6_PACKET consists of a list of two or three variable-length ASCII strings, each terminated by a null character, for each file in the directory. If the multicast option is involved, the first field of each directory entry is the static multicast IP address and UDP port number that is associated with the file name. The format of the field is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its terminating null character are not present. The next field of each directory entry is the file name and the last field is the file information string. The information string contains the file size and the create/modify timestamp. The format of the information string is filesize yyyy-mm-dd hh:mm:ss:ffff. The timestamp is Coordinated Universal Time (UTC; also known as Greenwich Mean Time [GMT]). @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @param[in] Token Pointer to the token structure to provide the parameters that are used in this operation. @retval EFI_SUCCESS The MTFTPv6 related file "directory" has been downloaded. @retval EFI_UNSUPPORTED The EFI MTFTPv6 Protocol driver does not support this function. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token.Filename is NULL. - Token.OptionCount is not zero and Token.OptionList is NULL. - One or more options in Token.OptionList have wrong format. - Token.Buffer and Token.CheckPacket are both NULL. - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses. @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are not supported by this implementation. @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv6 session. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_ACCESS_DENIED The previous operation has not completed yet. @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_READ_DIRECTORY)( IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token ); /** Polls for incoming data packets and processes outgoing data packets. The Poll() function can be used by network drivers and applications to increase the rate that data packets are moved between the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the Poll() function more often. @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_NOT_STARTED This EFI MTFTPv6 Protocol instance has not been started. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_MTFTP6_POLL)( IN EFI_MTFTP6_PROTOCOL *This ); /// /// The EFI_MTFTP6_PROTOCOL is designed to be used by UEFI drivers and applications to transmit /// and receive data files. The EFI MTFTPv6 Protocol driver uses the underlying EFI UDPv6 Protocol /// driver and EFI IPv6 Protocol driver. /// struct _EFI_MTFTP6_PROTOCOL { EFI_MTFTP6_GET_MODE_DATA GetModeData; EFI_MTFTP6_CONFIGURE Configure; EFI_MTFTP6_GET_INFO GetInfo; EFI_MTFTP6_PARSE_OPTIONS ParseOptions; EFI_MTFTP6_READ_FILE ReadFile; EFI_MTFTP6_WRITE_FILE WriteFile; EFI_MTFTP6_READ_DIRECTORY ReadDirectory; EFI_MTFTP6_POLL Poll; }; extern EFI_GUID gEfiMtftp6ServiceBindingProtocolGuid; extern EFI_GUID gEfiMtftp6ProtocolGuid; #endif /** @file EFI Network Interface Identifier Protocol. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in EFI Specification 1.10. **/ #ifndef __EFI_NETWORK_INTERFACE_IDENTIFER_H__ #define __EFI_NETWORK_INTERFACE_IDENTIFER_H__ // // GUID retired from UEFI Specification 2.1b // #define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID \ { \ 0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29 } \ } // // GUID intruduced in UEFI Specification 2.1b // #define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31 \ { \ 0x1ACED566, 0x76ED, 0x4218, {0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89 } \ } // // Revision defined in UEFI Specification 2.4 // #define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION 0x00020000 /// /// Revision defined in EFI1.1. /// #define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION /// /// Forward reference for pure ANSI compatability. /// typedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL; /// /// Protocol defined in EFI1.1. /// typedef EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE; /// /// An optional protocol that is used to describe details about the software /// layer that is used to produce the Simple Network Protocol. /// struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL { UINT64 Revision; ///< The revision of the EFI_NETWORK_INTERFACE_IDENTIFIER protocol. UINT64 Id; ///< The address of the first byte of the identifying structure for this network ///< interface. This is only valid when the network interface is started ///< (see Start()). When the network interface is not started, this field is set to zero. UINT64 ImageAddr; ///< The address of the first byte of the identifying structure for this ///< network interface. This is set to zero if there is no structure. UINT32 ImageSize; ///< The size of unrelocated network interface image. CHAR8 StringId[4]; ///< A four-character ASCII string that is sent in the class identifier field of ///< option 60 in DHCP. For a Type of EfiNetworkInterfaceUndi, this field is UNDI. UINT8 Type; ///< Network interface type. This will be set to one of the values ///< in EFI_NETWORK_INTERFACE_TYPE. UINT8 MajorVer; ///< Major version number. UINT8 MinorVer; ///< Minor version number. BOOLEAN Ipv6Supported; ///< TRUE if the network interface supports IPv6; otherwise FALSE. UINT16 IfNum; ///< The network interface number that is being identified by this Network ///< Interface Identifier Protocol. This field must be less than or ///< equal to the (IFcnt | IFcntExt <<8 ) fields in the !PXE structure. }; /// /// ******************************************************* /// EFI_NETWORK_INTERFACE_TYPE /// ******************************************************* /// typedef enum { EfiNetworkInterfaceUndi = 1 } EFI_NETWORK_INTERFACE_TYPE; /// /// Forward reference for pure ANSI compatability. /// typedef struct undiconfig_table UNDI_CONFIG_TABLE; /// /// The format of the configuration table for UNDI /// struct undiconfig_table { UINT32 NumberOfInterfaces; ///< The number of NIC devices ///< that this UNDI controls. UINT32 reserved; UNDI_CONFIG_TABLE *nextlink; ///< A pointer to the next UNDI ///< configuration table. /// /// The length of this array is given in the NumberOfInterfaces field. /// struct { VOID *NII_InterfacePointer; ///< Pointer to the NII interface structure. VOID *DevicePathPointer; ///< Pointer to the device path for this NIC. } NII_entry[1]; }; extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid; extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31; #endif /** @file This protocol provides services that allow NVM Express commands to be sent to an NVM Express controller or to a specific namespace in a NVM Express controller. This protocol interface is optimized for storage. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in UEFI Specification 2.5. **/ #ifndef _UEFI_NVM_EXPRESS_PASS_THRU_H_ #define _UEFI_NVM_EXPRESS_PASS_THRU_H_ #define EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID \ { \ 0x52c78312, 0x8edc, 0x4233, { 0x98, 0xf2, 0x1a, 0x1a, 0xa5, 0xe3, 0x88, 0xa5 } \ } typedef struct _EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL; typedef struct { UINT32 Attributes; UINT32 IoAlign; UINT32 NvmeVersion; } EFI_NVM_EXPRESS_PASS_THRU_MODE; // // If this bit is set, then the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL interface is // for directly addressable namespaces. // #define EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 // // If this bit is set, then the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL interface is // for a single volume logical namespace comprised of multiple namespaces. // #define EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 // // If this bit is set, then the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL interface // supports non-blocking I/O. // #define EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 // // If this bit is set, then the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL interface // supports NVM command set. // #define EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM 0x0008 // // FusedOperation // #define NORMAL_CMD 0x00 #define FUSED_FIRST_CMD 0x01 #define FUSED_SECOND_CMD 0x02 typedef struct { UINT32 Opcode : 8; UINT32 FusedOperation : 2; UINT32 Reserved : 22; } NVME_CDW0; // // Flags // #define CDW2_VALID 0x01 #define CDW3_VALID 0x02 #define CDW10_VALID 0x04 #define CDW11_VALID 0x08 #define CDW12_VALID 0x10 #define CDW13_VALID 0x20 #define CDW14_VALID 0x40 #define CDW15_VALID 0x80 // // Queue Type // #define NVME_ADMIN_QUEUE 0x00 #define NVME_IO_QUEUE 0x01 typedef struct { NVME_CDW0 Cdw0; UINT8 Flags; UINT32 Nsid; UINT32 Cdw2; UINT32 Cdw3; UINT32 Cdw10; UINT32 Cdw11; UINT32 Cdw12; UINT32 Cdw13; UINT32 Cdw14; UINT32 Cdw15; } EFI_NVM_EXPRESS_COMMAND; typedef struct { UINT32 DW0; UINT32 DW1; UINT32 DW2; UINT32 DW3; } EFI_NVM_EXPRESS_COMPLETION; typedef struct { UINT64 CommandTimeout; VOID *TransferBuffer; UINT32 TransferLength; VOID *MetadataBuffer; UINT32 MetadataLength; UINT8 QueueType; EFI_NVM_EXPRESS_COMMAND *NvmeCmd; EFI_NVM_EXPRESS_COMPLETION *NvmeCompletion; } EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET; // // Protocol function prototypes // /** Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required, and the non-blocking I/O functionality is optional. @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. @param[in] NamespaceId A 32 bit namespace ID as defined in the NVMe specification to which the NVM Express Command Packet will be sent. A value of 0 denotes the NVM Express controller, a value of all 0xFF's (all bytes are 0xFF) in the namespace ID specifies that the command packet should be sent to all valid namespaces. @param[in,out] Packet A pointer to the NVM Express Command Packet. @param[in] Event If non-blocking I/O is not supported then Event is ignored, and blocking I/O is performed. If Event is NULL, then blocking I/O is performed. If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed, and Event will be signaled when the NVM Express Command Packet completes. @retval EFI_SUCCESS The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred to, or from DataBuffer. @retval EFI_BAD_BUFFER_SIZE The NVM Express Command Packet was not executed. The number of bytes that could be transferred is returned in TransferLength. @retval EFI_NOT_READY The NVM Express Command Packet could not be sent because the controller is not ready. The caller may retry again later. @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the NVM Express Command Packet. @retval EFI_INVALID_PARAMETER NamespaceId or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM Express Command Packet was not sent, so no additional status information is available. @retval EFI_UNSUPPORTED The command described by the NVM Express Command Packet is not supported by the NVM Express controller. The NVM Express Command Packet was not sent so no additional status information is available. @retval EFI_TIMEOUT A timeout occurred while waiting for the NVM Express Command Packet to execute. **/ typedef EFI_STATUS (EFIAPI *EFI_NVM_EXPRESS_PASS_THRU_PASSTHRU)( IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN UINT32 NamespaceId, IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ); /** Used to retrieve the next namespace ID for this NVM Express controller. The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid namespace ID on this NVM Express controller. If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId and a status of EFI_SUCCESS is returned. If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned. If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId, and EFI_SUCCESS is returned. If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM Express controller, then EFI_NOT_FOUND is returned. @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. @param[in,out] NamespaceId On input, a pointer to a legal NamespaceId for an NVM Express namespace present on the NVM Express controller. On output, a pointer to the next NamespaceId of an NVM Express namespace on an NVM Express controller. An input value of 0xFFFFFFFF retrieves the first NamespaceId for an NVM Express namespace present on an NVM Express controller. @retval EFI_SUCCESS The Namespace ID of the next Namespace was returned. @retval EFI_NOT_FOUND There are no more namespaces defined on this controller. @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF. **/ typedef EFI_STATUS (EFIAPI *EFI_NVM_EXPRESS_PASS_THRU_GET_NEXT_NAMESPACE)( IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN OUT UINT32 *NamespaceId ); /** Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller. The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device path node for the NVM Express namespace specified by NamespaceId. If the NamespaceId is not valid, then EFI_NOT_FOUND is returned. If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be allocated and built. Caller must set the NamespaceId to zero if the device path node will contain a valid UUID. @param[out] DevicePath A pointer to a single device path node that describes the NVM Express namespace specified by NamespaceId. This function is responsible for allocating the buffer DevicePath with the boot service AllocatePool(). It is the caller's responsibility to free DevicePath when the caller is finished with DevicePath. @retval EFI_SUCCESS The device path node that describes the NVM Express namespace specified by NamespaceId was allocated and returned in DevicePath. @retval EFI_NOT_FOUND The NamespaceId is not valid. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the DevicePath node. **/ typedef EFI_STATUS (EFIAPI *EFI_NVM_EXPRESS_PASS_THRU_BUILD_DEVICE_PATH)( IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN UINT32 NamespaceId, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ); /** Used to translate a device path node to a namespace ID. The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the namespace described by DevicePath. If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID. If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. @param[in] DevicePath A pointer to the device path node that describes an NVM Express namespace on the NVM Express controller. @param[out] NamespaceId The NVM Express namespace ID contained in the device path node. @retval EFI_SUCCESS DevicePath was successfully translated to NamespaceId. @retval EFI_INVALID_PARAMETER If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned. @retval EFI_UNSUPPORTED If DevicePath is not a device path node type that the NVM Express Pass Thru driver supports, then EFI_UNSUPPORTED is returned. @retval EFI_NOT_FOUND If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, but there is not a valid translation from DevicePath to a namespace ID, then EFI_NOT_FOUND is returned. **/ typedef EFI_STATUS (EFIAPI *EFI_NVM_EXPRESS_PASS_THRU_GET_NAMESPACE)( IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT32 *NamespaceId ); // // Protocol Interface Structure // struct _EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL { EFI_NVM_EXPRESS_PASS_THRU_MODE *Mode; EFI_NVM_EXPRESS_PASS_THRU_PASSTHRU PassThru; EFI_NVM_EXPRESS_PASS_THRU_GET_NEXT_NAMESPACE GetNextNamespace; EFI_NVM_EXPRESS_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; EFI_NVM_EXPRESS_PASS_THRU_GET_NAMESPACE GetNamespace; }; extern EFI_GUID gEfiNvmExpressPassThruProtocolGuid; #endif /** @file Native Platform Configuration Database (PCD) Protocol Different with the EFI_PCD_PROTOCOL defined in PI 1.2 specification, the native PCD protocol provide interfaces for dynamic and dynamic-ex type PCD. The interfaces in dynamic type PCD do not require the token space guid as parameter, but interfaces in dynamic-ex type PCD require token space guid as parameter. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in PI Specification 1.2. **/ #ifndef __PCD_H__ #define __PCD_H__ extern EFI_GUID gPcdProtocolGuid; #define PCD_PROTOCOL_GUID \ { 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7 } } #define PCD_INVALID_TOKEN_NUMBER ((UINTN) 0) /** Sets the SKU value for subsequent calls to set or get PCD token values. SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. SetSku() is normally called only once by the system. For each item (token), the database can hold a single value that applies to all SKUs, or multiple values, where each value is associated with a specific SKU Id. Items with multiple, SKU-specific values are called SKU enabled. The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been set for that Id, the results are unpredictable. @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and set values associated with a PCD token. **/ typedef VOID (EFIAPI *PCD_PROTOCOL_SET_SKU)( IN UINTN SkuId ); /** Retrieves an 8-bit value for a given PCD token. Retrieves the current byte-sized value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The UINT8 value. **/ typedef UINT8 (EFIAPI *PCD_PROTOCOL_GET8)( IN UINTN TokenNumber ); /** Retrieves a 16-bit value for a given PCD token. Retrieves the current 16-bit value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The UINT16 value. **/ typedef UINT16 (EFIAPI *PCD_PROTOCOL_GET16)( IN UINTN TokenNumber ); /** Retrieves a 32-bit value for a given PCD token. Retrieves the current 32-bit value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The UINT32 value. **/ typedef UINT32 (EFIAPI *PCD_PROTOCOL_GET32)( IN UINTN TokenNumber ); /** Retrieves a 64-bit value for a given PCD token. Retrieves the current 64-bit value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The UINT64 value. **/ typedef UINT64 (EFIAPI *PCD_PROTOCOL_GET64)( IN UINTN TokenNumber ); /** Retrieves a pointer to a value for a given PCD token. Retrieves the current pointer to the buffer for a PCD token number. Do not make any assumptions about the alignment of the pointer that is returned by this function call. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The pointer to the buffer to be retrived. **/ typedef VOID * (EFIAPI *PCD_PROTOCOL_GET_POINTER)( IN UINTN TokenNumber ); /** Retrieves a Boolean value for a given PCD token. Retrieves the current boolean value for a PCD token number. Do not make any assumptions about the alignment of the pointer that is returned by this function call. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The Boolean value. **/ typedef BOOLEAN (EFIAPI *PCD_PROTOCOL_GET_BOOLEAN)( IN UINTN TokenNumber ); /** Retrieves the size of the value for a given PCD token. Retrieves the current size of a particular PCD token. If the TokenNumber is invalid, the results are unpredictable. @param[in] TokenNumber The PCD token number. @return The size of the value for the PCD token. **/ typedef UINTN (EFIAPI *PCD_PROTOCOL_GET_SIZE)( IN UINTN TokenNumber ); /** Retrieves an 8-bit value for a given PCD token. Retrieves the 8-bit value of a particular PCD token. If the TokenNumber is invalid or the token space specified by Guid does not exist, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size 8-bit value for the PCD token. **/ typedef UINT8 (EFIAPI *PCD_PROTOCOL_GET_EX_8)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves a 16-bit value for a given PCD token. Retrieves the 16-bit value of a particular PCD token. If the TokenNumber is invalid or the token space specified by Guid does not exist, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size 16-bit value for the PCD token. **/ typedef UINT16 (EFIAPI *PCD_PROTOCOL_GET_EX_16)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves a 32-bit value for a given PCD token. Retrieves the 32-bit value of a particular PCD token. If the TokenNumber is invalid or the token space specified by Guid does not exist, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size 32-bit value for the PCD token. **/ typedef UINT32 (EFIAPI *PCD_PROTOCOL_GET_EX_32)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves an 64-bit value for a given PCD token. Retrieves the 64-bit value of a particular PCD token. If the TokenNumber is invalid or the token space specified by Guid does not exist, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size 64-bit value for the PCD token. **/ typedef UINT64 (EFIAPI *PCD_PROTOCOL_GET_EX_64)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves a pointer to a value for a given PCD token. Retrieves the current pointer to the buffer for a PCD token number. Do not make any assumptions about the alignment of the pointer that is returned by this function call. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The pointer to the buffer to be retrieved. **/ typedef VOID * (EFIAPI *PCD_PROTOCOL_GET_EX_POINTER)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves a Boolean value for a given PCD token. Retrieves the Boolean value of a particular PCD token. If the TokenNumber is invalid or the token space specified by Guid does not exist, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size Boolean value for the PCD token. **/ typedef BOOLEAN (EFIAPI *PCD_PROTOCOL_GET_EX_BOOLEAN)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the size of the value for a given PCD token. Retrieves the current size of a particular PCD token. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The token space for the token number. @param[in] TokenNumber The PCD token number. @return The size of the value for the PCD token. **/ typedef UINTN (EFIAPI *PCD_PROTOCOL_GET_EX_SIZE)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Sets an 8-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET8)( IN UINTN TokenNumber, IN UINT8 Value ); /** Sets a 16-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET16)( IN UINTN TokenNumber, IN UINT16 Value ); /** Sets a 32-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET32)( IN UINTN TokenNumber, IN UINT32 Value ); /** Sets a 64-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET64)( IN UINTN TokenNumber, IN UINT64 Value ); /** Sets a value of a specified size for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. On input, if the SizeOfValue is greater than the maximum size supported for this TokenNumber then the output value of SizeOfValue will reflect the maximum size supported for this TokenNumber. @param[in] Buffer The buffer to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_POINTER)( IN UINTN TokenNumber, IN OUT UINTN *SizeOfBuffer, IN VOID *Buffer ); /** Sets a Boolean value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_BOOLEAN)( IN UINTN TokenNumber, IN BOOLEAN Value ); /** Sets an 8-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_8)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT8 Value ); /** Sets an 16-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_16)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT16 Value ); /** Sets a 32-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_32)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT32 Value ); /** Sets a 64-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_64)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT64 Value ); /** Sets a value of a specified size for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. On input, if the SizeOfValue is greater than the maximum size supported for this TokenNumber then the output value of SizeOfValue will reflect the maximum size supported for this TokenNumber. @param[in] Buffer The buffer to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_POINTER)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN OUT UINTN *SizeOfBuffer, IN VOID *Buffer ); /** Sets a Boolean value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The procedure returned successfully. @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSize() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_SET_EX_BOOLEAN)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN BOOLEAN Value ); /** Callback on SET function prototype definition. This notification function serves two purposes. Firstly, it notifies the module which did the registration that the value of this PCD token has been set. Secondly, it provides a mechanism for the module that did the registration to intercept the set operation and override the value that has been set, if necessary. After the invocation of the callback function, TokenData will be used by PCD service DXE driver to modify the internal data in PCD database. @param[in] CallBackGuid The PCD token GUID being set. @param[in] CallBackToken The PCD token number being set. @param[in, out] TokenData A pointer to the token data being set. @param[in] TokenDataSize The size, in bytes, of the data being set. @retval VOID **/ typedef VOID (EFIAPI *PCD_PROTOCOL_CALLBACK)( IN CONST EFI_GUID *CallBackGuid OPTIONAL, IN UINTN CallBackToken, IN OUT VOID *TokenData, IN UINTN TokenDataSize ); /** Specifies a function to be called anytime the value of a designated token is changed. @param[in] TokenNumber The PCD token number. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_CALLBACK_ONSET)( IN CONST EFI_GUID *Guid OPTIONAL, IN UINTN TokenNumber, IN PCD_PROTOCOL_CALLBACK CallBackFunction ); /** Cancels a previously set callback function for a particular PCD token number. @param[in] TokenNumber The PCD token number. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_CANCEL_CALLBACK)( IN CONST EFI_GUID *Guid OPTIONAL, IN UINTN TokenNumber, IN PCD_PROTOCOL_CALLBACK CallBackFunction ); /** Retrieves the next valid token number in a given namespace. This is useful since the PCD infrastructure contains a sparse list of token numbers, and one cannot a priori know what token numbers are valid in the database. If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned. If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned. If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned. If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned. The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid. If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned. If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned. If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token. This is an optional parameter that may be NULL. If this parameter is NULL, then a request is being made to retrieve tokens from the default token space. @param[in,out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. @retval EFI_SUCCESS The PCD service has retrieved the next valid token number. @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_GET_NEXT_TOKEN)( IN CONST EFI_GUID *Guid OPTIONAL, IN OUT UINTN *TokenNumber ); /** Retrieves the next valid PCD token namespace for a given namespace. Gets the next valid token namespace for a given namespace. This is useful to traverse the valid token namespaces on a platform. @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token namespace from which the search will start. On output, it designates the next valid token namespace on the platform. If *Guid is NULL, then the GUID of the first token space of the current platform is returned. If the search cannot locate the next valid token namespace, an error is returned and the value of *Guid is undefined. @retval EFI_SUCCESS The PCD service retrieved the value requested. @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace. **/ typedef EFI_STATUS (EFIAPI *PCD_PROTOCOL_GET_NEXT_TOKENSPACE)( IN OUT CONST EFI_GUID **Guid ); /// /// This service abstracts the ability to set/get Platform Configuration Database (PCD). /// typedef struct { PCD_PROTOCOL_SET_SKU SetSku; PCD_PROTOCOL_GET8 Get8; PCD_PROTOCOL_GET16 Get16; PCD_PROTOCOL_GET32 Get32; PCD_PROTOCOL_GET64 Get64; PCD_PROTOCOL_GET_POINTER GetPtr; PCD_PROTOCOL_GET_BOOLEAN GetBool; PCD_PROTOCOL_GET_SIZE GetSize; PCD_PROTOCOL_GET_EX_8 Get8Ex; PCD_PROTOCOL_GET_EX_16 Get16Ex; PCD_PROTOCOL_GET_EX_32 Get32Ex; PCD_PROTOCOL_GET_EX_64 Get64Ex; PCD_PROTOCOL_GET_EX_POINTER GetPtrEx; PCD_PROTOCOL_GET_EX_BOOLEAN GetBoolEx; PCD_PROTOCOL_GET_EX_SIZE GetSizeEx; PCD_PROTOCOL_SET8 Set8; PCD_PROTOCOL_SET16 Set16; PCD_PROTOCOL_SET32 Set32; PCD_PROTOCOL_SET64 Set64; PCD_PROTOCOL_SET_POINTER SetPtr; PCD_PROTOCOL_SET_BOOLEAN SetBool; PCD_PROTOCOL_SET_EX_8 Set8Ex; PCD_PROTOCOL_SET_EX_16 Set16Ex; PCD_PROTOCOL_SET_EX_32 Set32Ex; PCD_PROTOCOL_SET_EX_64 Set64Ex; PCD_PROTOCOL_SET_EX_POINTER SetPtrEx; PCD_PROTOCOL_SET_EX_BOOLEAN SetBoolEx; PCD_PROTOCOL_CALLBACK_ONSET CallbackOnSet; PCD_PROTOCOL_CANCEL_CALLBACK CancelCallback; PCD_PROTOCOL_GET_NEXT_TOKEN GetNextToken; PCD_PROTOCOL_GET_NEXT_TOKENSPACE GetNextTokenSpace; } PCD_PROTOCOL; #endif /** @file PCI Enumeration Complete Protocol as defined in the PI 1.1 specification. This protocol indicates that pci enumeration complete Copyright (c) 2009, 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 _PCI_ENUMERATION_COMPLETE_H_ #define _PCI_ENUMERATION_COMPLETE_H_ #define EFI_PCI_ENUMERATION_COMPLETE_GUID \ { \ 0x30cfe3e7, 0x3de1, 0x4586, { 0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93 } \ } extern EFI_GUID gEfiPciEnumerationCompleteProtocolGuid; #endif /** @file EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration, and DMA interfaces that a driver uses to access its PCI controller. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PCI_IO_H__ #define __PCI_IO_H__ /// /// Global ID for the PCI I/O Protocol /// #define EFI_PCI_IO_PROTOCOL_GUID \ { \ 0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a } \ } typedef struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL; /// /// ******************************************************* /// EFI_PCI_IO_PROTOCOL_WIDTH /// ******************************************************* /// typedef enum { EfiPciIoWidthUint8 = 0, EfiPciIoWidthUint16, EfiPciIoWidthUint32, EfiPciIoWidthUint64, EfiPciIoWidthFifoUint8, EfiPciIoWidthFifoUint16, EfiPciIoWidthFifoUint32, EfiPciIoWidthFifoUint64, EfiPciIoWidthFillUint8, EfiPciIoWidthFillUint16, EfiPciIoWidthFillUint32, EfiPciIoWidthFillUint64, EfiPciIoWidthMaximum } EFI_PCI_IO_PROTOCOL_WIDTH; // // Complete PCI address generater // #define EFI_PCI_IO_PASS_THROUGH_BAR 0xff ///< Special BAR that passes a memory or I/O cycle through unchanged #define EFI_PCI_IO_ATTRIBUTE_MASK 0x077f ///< All the following I/O and Memory cycles #define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 ///< I/O cycles 0x0000-0x00FF (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002 ///< I/O cycles 0x0100-0x03FF or greater (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008 ///< MEM cycles 0xA0000-0xBFFFF (24 bit decode) #define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 ///< I/O cycles 0x1F0-0x1F7, 0x3F6, 0x3F7 (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 ///< I/O cycles 0x170-0x177, 0x376, 0x377 (10 bit decode) #define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 ///< Map a memory range so writes are combined #define EFI_PCI_IO_ATTRIBUTE_IO 0x0100 ///< Enable the I/O decode bit in the PCI Config Header #define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200 ///< Enable the Memory decode bit in the PCI Config Header #define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400 ///< Enable the DMA bit in the PCI Config Header #define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800 ///< Map a memory range so all r/w accesses are cached #define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range #define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 ///< Clear for an add-in PCI Device #define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000 ///< Clear for a physical PCI Option ROM accessed through ROM BAR #define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 ///< Clear for PCI controllers that can not genrate a DAC #define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000 ///< I/O cycles 0x0100-0x03FF or greater (16 bit decode) #define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (16 bit decode) #define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode) #define EFI_PCI_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) #define EFI_VGA_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_IO) /// /// ******************************************************* /// EFI_PCI_IO_PROTOCOL_OPERATION /// ******************************************************* /// typedef enum { /// /// A read operation from system memory by a bus master. /// EfiPciIoOperationBusMasterRead, /// /// A write operation from system memory by a bus master. /// EfiPciIoOperationBusMasterWrite, /// /// Provides both read and write access to system memory by both the processor and a /// bus master. The buffer is coherent from both the processor's and the bus master's point of view. /// EfiPciIoOperationBusMasterCommonBuffer, EfiPciIoOperationMaximum } EFI_PCI_IO_PROTOCOL_OPERATION; /// /// ******************************************************* /// EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION /// ******************************************************* /// typedef enum { /// /// Retrieve the PCI controller's current attributes, and return them in Result. /// EfiPciIoAttributeOperationGet, /// /// Set the PCI controller's current attributes to Attributes. /// EfiPciIoAttributeOperationSet, /// /// Enable the attributes specified by the bits that are set in Attributes for this PCI controller. /// EfiPciIoAttributeOperationEnable, /// /// Disable the attributes specified by the bits that are set in Attributes for this PCI controller. /// EfiPciIoAttributeOperationDisable, /// /// Retrieve the PCI controller's supported attributes, and return them in Result. /// EfiPciIoAttributeOperationSupported, EfiPciIoAttributeOperationMaximum } EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; /** Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is satisfied or after a defined duration. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory or I/O operations. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for the memory operation to perform. @param Offset The offset within the selected BAR to start the memory operation. @param Mask Mask used for the polling criteria. @param Value The comparison value used for the polling exit criteria. @param Delay The number of 100 ns units to poll. @param Result Pointer to the last value read from the memory location. @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. @retval EFI_TIMEOUT Delay expired before a match occurred. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result ); /** Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory or I/O operations. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for the memory or I/O operation to perform. @param Offset The offset within the selected BAR to start the memory or I/O operation. @param Count The number of memory or I/O operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. @retval EFI_SUCCESS The data was read from or written to the PCI controller. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not valid for the PCI BAR specified by BarIndex. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer ); typedef struct { /// /// Read PCI controller registers in the PCI memory or I/O space. /// EFI_PCI_IO_PROTOCOL_IO_MEM Read; /// /// Write PCI controller registers in the PCI memory or I/O space. /// EFI_PCI_IO_PROTOCOL_IO_MEM Write; } EFI_PCI_IO_PROTOCOL_ACCESS; /** Enable a PCI driver to access PCI controller registers in PCI configuration space. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory operations. @param Offset The offset within the PCI configuration space for the PCI controller. @param Count The number of PCI configuration operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. @retval EFI_SUCCESS The data was read from or written to the PCI controller. @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not valid for the PCI configuration header of the PCI controller. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer ); typedef struct { /// /// Read PCI controller registers in PCI configuration space. /// EFI_PCI_IO_PROTOCOL_CONFIG Read; /// /// Write PCI controller registers in PCI configuration space. /// EFI_PCI_IO_PROTOCOL_CONFIG Write; } EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS; /** Enables a PCI driver to copy one region of PCI memory space to another region of PCI memory space. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Width Signifies the width of the memory operations. @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the base address for the memory operation to perform. @param DestOffset The destination offset within the BAR specified by DestBarIndex to start the memory writes for the copy operation. @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the base address for the memory operation to perform. @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start the memory reads for the copy operation. @param Count The number of memory operations to perform. Bytes moved is Width size * Count, starting at DestOffset and SrcOffset. @retval EFI_SUCCESS The data was copied from one memory region to another memory region. @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller. @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count is not valid for the PCI BAR specified by DestBarIndex. @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is not valid for the PCI BAR specified by SrcBarIndex. @retval EFI_INVALID_PARAMETER Width is invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 DestBarIndex, IN UINT64 DestOffset, IN UINT8 SrcBarIndex, IN UINT64 SrcOffset, IN UINTN Count ); /** Provides the PCI controller-specific addresses needed to access system memory. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the PCI controller. @param NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped. @param DeviceAddress The resulting map address for the bus master PCI controller to use to access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_MAP)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ); /** Completes the Map() operation and releases any corresponding resources. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Mapping The mapping value returned from Map(). @retval EFI_SUCCESS The range was unmapped. @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP)( IN EFI_PCI_IO_PROTOCOL *This, IN VOID *Mapping ); /** Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer or EfiPciOperationBusMasterCommonBuffer64 mapping. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Type This parameter is not used and must be ignored. @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData. @param Pages The number of pages to allocate. @param HostAddress A pointer to store the base system memory address of the allocated range. @param Attributes The requested bit mask of attributes for the allocated range. @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes ); /** Frees memory that was allocated with AllocateBuffer(). @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Pages The number of pages to free. @param HostAddress The base system memory address of the allocated range. @retval EFI_SUCCESS The requested memory pages were freed. @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages was not allocated with AllocateBuffer(). **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER)( IN EFI_PCI_IO_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress ); /** Flushes all PCI posted write transactions from a PCI host bridge to system memory. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host bridge to system memory. @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI host bridge due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH)( IN EFI_PCI_IO_PROTOCOL *This ); /** Retrieves this PCI controller's current PCI bus number, device number, and function number. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param SegmentNumber The PCI controller's current PCI segment number. @param BusNumber The PCI controller's current PCI bus number. @param DeviceNumber The PCI controller's current PCI device number. @param FunctionNumber The PCI controller's current PCI function number. @retval EFI_SUCCESS The PCI controller location was returned. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION)( IN EFI_PCI_IO_PROTOCOL *This, OUT UINTN *SegmentNumber, OUT UINTN *BusNumber, OUT UINTN *DeviceNumber, OUT UINTN *FunctionNumber ); /** Performs an operation on the attributes that this PCI controller supports. The operations include getting the set of supported attributes, retrieving the current attributes, setting the current attributes, enabling attributes, and disabling attributes. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Operation The operation to perform on the attributes for this PCI controller. @param Attributes The mask of attributes that are used for Set, Enable, and Disable operations. @param Result A pointer to the result mask of attributes that are returned for the Get and Supported operations. @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED one or more of the bits set in Attributes are not supported by this PCI controller or one of its parent bridges when Operation is Set, Enable or Disable. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES)( IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, IN UINT64 Attributes, OUT UINT64 *Result OPTIONAL ); /** Gets the attributes that this PCI controller supports setting on a BAR using SetBarAttributes(), and retrieves the list of resource descriptors for a BAR. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for resource range. The legal range for this field is 0..5. @param Supports A pointer to the mask of attributes that this PCI controller supports setting for this BAR with SetBarAttributes(). @param Resources A pointer to the resource descriptors that describe the current configuration of this BAR of the PCI controller. @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI controller supports are returned in Supports. If Resources is not NULL, then the resource descriptors that the PCI controller is currently using are returned in Resources. @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate Resources. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)( IN EFI_PCI_IO_PROTOCOL *This, IN UINT8 BarIndex, OUT UINT64 *Supports OPTIONAL, OUT VOID **Resources OPTIONAL ); /** Sets the attributes for a range of a BAR on a PCI controller. @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. @param Attributes The mask of attributes to set for the resource range specified by BarIndex, Offset, and Length. @param BarIndex The BAR index of the standard PCI Configuration header to use as the base address for resource range. The legal range for this field is 0..5. @param Offset A pointer to the BAR relative base address of the resource range to be modified by the attributes specified by Attributes. @param Length A pointer to the length of the resource range to be modified by the attributes specified by Attributes. @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource range specified by BarIndex, Offset, and Length were set on the PCI controller, and the actual resource range is returned in Offset and Length. @retval EFI_INVALID_PARAMETER Offset or Length is NULL. @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the resource range specified by BarIndex, Offset, and Length. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)( IN EFI_PCI_IO_PROTOCOL *This, IN UINT64 Attributes, IN UINT8 BarIndex, IN OUT UINT64 *Offset, IN OUT UINT64 *Length ); /// /// The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration, /// and DMA interfaces used to abstract accesses to PCI controllers. /// There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus. /// A device driver that wishes to manage a PCI controller in a system will have to /// retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller. /// struct _EFI_PCI_IO_PROTOCOL { EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem; EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo; EFI_PCI_IO_PROTOCOL_ACCESS Mem; EFI_PCI_IO_PROTOCOL_ACCESS Io; EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci; EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem; EFI_PCI_IO_PROTOCOL_MAP Map; EFI_PCI_IO_PROTOCOL_UNMAP Unmap; EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer; EFI_PCI_IO_PROTOCOL_FLUSH Flush; EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation; EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes; EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes; EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes; /// /// The size, in bytes, of the ROM image. /// UINT64 RomSize; /// /// A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible /// for allocating memory for the ROM image, and copying the contents of the ROM to memory. /// The contents of this buffer are either from the PCI option ROM that can be accessed /// through the ROM BAR of the PCI controller, or it is from a platform-specific location. /// The Attributes() function can be used to determine from which of these two sources /// the RomImage buffer was initialized. /// VOID *RomImage; }; extern EFI_GUID gEfiPciIoProtocolGuid; #endif /** @file PCI Root Bridge I/O protocol as defined in the UEFI 2.0 specification. PCI Root Bridge I/O protocol is used by PCI Bus Driver to perform PCI Memory, PCI I/O, and PCI Configuration cycles on a PCI Root Bridge. It also provides services to perform defferent types of bus mastering DMA. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PCI_ROOT_BRIDGE_IO_H__ #define __PCI_ROOT_BRIDGE_IO_H__ #define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \ { \ 0x2f707ebb, 0x4a1a, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL; /// /// ******************************************************* /// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH /// ******************************************************* /// typedef enum { EfiPciWidthUint8, EfiPciWidthUint16, EfiPciWidthUint32, EfiPciWidthUint64, EfiPciWidthFifoUint8, EfiPciWidthFifoUint16, EfiPciWidthFifoUint32, EfiPciWidthFifoUint64, EfiPciWidthFillUint8, EfiPciWidthFillUint16, EfiPciWidthFillUint32, EfiPciWidthFillUint64, EfiPciWidthMaximum } EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH; /// /// ******************************************************* /// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION /// ******************************************************* /// typedef enum { /// /// A read operation from system memory by a bus master that is not capable of producing /// PCI dual address cycles. /// EfiPciOperationBusMasterRead, /// /// A write operation from system memory by a bus master that is not capable of producing /// PCI dual address cycles. /// EfiPciOperationBusMasterWrite, /// /// Provides both read and write access to system memory by both the processor and a bus /// master that is not capable of producing PCI dual address cycles. /// EfiPciOperationBusMasterCommonBuffer, /// /// A read operation from system memory by a bus master that is capable of producing PCI /// dual address cycles. /// EfiPciOperationBusMasterRead64, /// /// A write operation to system memory by a bus master that is capable of producing PCI /// dual address cycles. /// EfiPciOperationBusMasterWrite64, /// /// Provides both read and write access to system memory by both the processor and a bus /// master that is capable of producing PCI dual address cycles. /// EfiPciOperationBusMasterCommonBuffer64, EfiPciOperationMaximum } EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION; #define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 #define EFI_PCI_ATTRIBUTE_ISA_IO 0x0002 #define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO 0x0004 #define EFI_PCI_ATTRIBUTE_VGA_MEMORY 0x0008 #define EFI_PCI_ATTRIBUTE_VGA_IO 0x0010 #define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 #define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 #define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 #define EFI_PCI_ATTRIBUTE_MEMORY_CACHED 0x0800 #define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE 0x1000 #define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 #define EFI_PCI_ATTRIBUTE_ISA_IO_16 0x10000 #define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 #define EFI_PCI_ATTRIBUTE_VGA_IO_16 0x40000 #define EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) #define EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER (~EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER) #define EFI_PCI_ADDRESS(bus, dev, func, reg) \ (UINT64) ( \ (((UINTN) bus) << 24) | \ (((UINTN) dev) << 16) | \ (((UINTN) func) << 8) | \ (((UINTN) (reg)) < 256 ? ((UINTN) (reg)) : (UINT64) (LShiftU64 ((UINT64) (reg), 32)))) typedef struct { UINT8 Register; UINT8 Function; UINT8 Device; UINT8 Bus; UINT32 ExtendedRegister; } EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS; /** Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is satisfied or after a defined duration. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Width Signifies the width of the memory or I/O operations. @param Address The base address of the memory or I/O operations. @param Mask Mask used for the polling criteria. @param Value The comparison value used for the polling exit criteria. @param Delay The number of 100 ns units to poll. @param Result Pointer to the last value read from the memory location. @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. @retval EFI_TIMEOUT Delay expired before a match occurred. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result ); /** Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Width Signifies the width of the memory operations. @param Address The base address of the memory operations. @param Count The number of memory operations to perform. @param Buffer For read operations, the destination buffer to store the results. For write operations, the source buffer to write data from. @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer ); typedef struct { /// /// Read PCI controller registers in the PCI root bridge memory space. /// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read; /// /// Write PCI controller registers in the PCI root bridge memory space. /// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write; } EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS; /** Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI root bridge memory space. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. @param Width Signifies the width of the memory operations. @param DestAddress The destination address of the memory operation. @param SrcAddress The source address of the memory operation. @param Count The number of memory operations to perform. @retval EFI_SUCCESS The data was copied from one memory region to another memory region. @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 DestAddress, IN UINT64 SrcAddress, IN UINTN Count ); /** Provides the PCI controller-specific addresses required to access system memory from a DMA bus master. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the PCI controller. @param NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped. @param DeviceAddress The resulting map address for the bus master PCI controller to use to access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ); /** Completes the Map() operation and releases any corresponding resources. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Mapping The mapping value returned from Map(). @retval EFI_SUCCESS The range was unmapped. @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN VOID *Mapping ); /** Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or EfiPciOperationBusMasterCommonBuffer64 mapping. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Type This parameter is not used and must be ignored. @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData. @param Pages The number of pages to allocate. @param HostAddress A pointer to store the base system memory address of the allocated range. @param Attributes The requested bit mask of attributes for the allocated range. @retval EFI_SUCCESS The requested memory pages were allocated. @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are MEMORY_WRITE_COMBINE and MEMORY_CACHED. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT VOID **HostAddress, IN UINT64 Attributes ); /** Frees memory that was allocated with AllocateBuffer(). @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Pages The number of pages to free. @param HostAddress The base system memory address of the allocated range. @retval EFI_SUCCESS The requested memory pages were freed. @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages was not allocated with AllocateBuffer(). **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress ); /** Flushes all PCI posted write transactions from a PCI host bridge to system memory. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host bridge to system memory. @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI host bridge due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This ); /** Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the attributes that a PCI root bridge is currently using. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Supports A pointer to the mask of attributes that this PCI root bridge supports setting with SetAttributes(). @param Attributes A pointer to the mask of attributes that this PCI root bridge is currently using. @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root bridge supports is returned in Supports. If Attributes is not NULL, then the attributes that the PCI root bridge is currently using is returned in Attributes. @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, OUT UINT64 *Supports, OUT UINT64 *Attributes ); /** Sets attributes for a resource range on a PCI root bridge. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Attributes The mask of attributes to set. @param ResourceBase A pointer to the base address of the resource range to be modified by the attributes specified by Attributes. @param ResourceLength A pointer to the length of the resource range to be modified by the attributes specified by Attributes. @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource range specified by ResourceBase and ResourceLength were set on the PCI root bridge, and the actual resource range is returned in ResuourceBase and ResourceLength. @retval EFI_UNSUPPORTED A bit is set in Attributes that is not supported by the PCI Root Bridge. @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the resource range specified by BaseAddress and Length. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN UINT64 Attributes, IN OUT UINT64 *ResourceBase, IN OUT UINT64 *ResourceLength ); /** Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI resource descriptors. @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Resources A pointer to the resource descriptors that describe the current configuration of this PCI root bridge. @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources. @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved. **/ typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, OUT VOID **Resources ); /// /// Provides the basic Memory, I/O, PCI configuration, and DMA interfaces that are /// used to abstract accesses to PCI controllers behind a PCI Root Bridge Controller. /// struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL { /// /// The EFI_HANDLE of the PCI Host Bridge of which this PCI Root Bridge is a member. /// EFI_HANDLE ParentHandle; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration; /// /// The segment number that this PCI root bridge resides. /// UINT32 SegmentNumber; }; extern EFI_GUID gEfiPciRootBridgeIoProtocolGuid; #endif /** @file Platform Configuration Database (PCD) Protocol defined in PI 1.2 Vol3 A platform database that contains a variety of current platform settings or directives that can be accessed by a driver or application. PI PCD protocol only provide the accessing interfaces for Dynamic-Ex type PCD. Callers to this protocol must be at a TPL_APPLICATION task priority level. This is the base PCD service API that provides an abstraction for accessing configuration content in the platform. It a seamless mechanism for extracting information regardless of where the information is stored (such as in Read-only data, or an EFI Variable). This protocol allows access to data through size-granular APIs and provides a mechanism for a firmware component to monitor specific settings and be alerted when a setting is changed. Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: PI Version 1.2 Vol 3. **/ #ifndef __PI_PCD_H__ #define __PI_PCD_H__ extern EFI_GUID gEfiPcdProtocolGuid; #define EFI_PCD_PROTOCOL_GUID \ { 0x13a3f0f6, 0x264a, 0x3ef0, { 0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34 } } #define EFI_PCD_INVALID_TOKEN_NUMBER ((UINTN) 0) /** SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. SetSku() is normally called only once by the system. For each item (token), the database can hold a single value that applies to all SKUs, or multiple values, where each value is associated with a specific SKU Id. Items with multiple, SKU-specific values are called SKU enabled. The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been set for that Id, the results are unpredictable. @param[in] SkuId The SKU value to set. **/ typedef VOID (EFIAPI *EFI_PCD_PROTOCOL_SET_SKU)( IN UINTN SkuId ); /** Retrieves an 8-bit value for a given PCD token. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return 8-bit value for a given PCD token. **/ typedef UINT8 (EFIAPI *EFI_PCD_PROTOCOL_GET_8)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the current word-sized value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return word-sized value for a given PCD token. **/ typedef UINT16 (EFIAPI *EFI_PCD_PROTOCOL_GET_16)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the current 32-bit sized value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return 32-bit value for a given PCD token. **/ typedef UINT32 (EFIAPI *EFI_PCD_PROTOCOL_GET_32)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the 64-bit sized value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return 64-bit value for a given PCD token. **/ typedef UINT64 (EFIAPI *EFI_PCD_PROTOCOL_GET_64)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the current pointer to the value for a PCD token number. Do not make any assumptions about the alignment of the pointer that is returned by this function call. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return pointer to a value for a given PCD token. **/ typedef VOID * (EFIAPI *EFI_PCD_PROTOCOL_GET_POINTER)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the current BOOLEAN-sized value for a PCD token number. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return Boolean value for a given PCD token. **/ typedef BOOLEAN (EFIAPI *EFI_PCD_PROTOCOL_GET_BOOLEAN)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Retrieves the current size of a particular PCD token. If the TokenNumber is invalid, the results are unpredictable. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @return the size of the value for a given PCD token. **/ typedef UINTN (EFIAPI *EFI_PCD_PROTOCOL_GET_SIZE)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber ); /** Sets an 8-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_8)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT8 Value ); /** Sets an 16-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_16)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT16 Value ); /** Sets an 32-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_32)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT32 Value ); /** Sets an 64-bit value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_64)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN UINT64 Value ); /** Sets a value of a specified size for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] SizeOfValue The length of the value being set for the PCD token. If too large of a length is specified, upon return from this function the value of SizeOfValue will reflect the maximum size for the PCD token. @param[in] Buffer A pointer to the buffer containing the value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_POINTER)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN OUT UINTN *SizeOfValue, IN VOID *Buffer ); /** Sets a Boolean value for a given PCD token. When the PCD service sets a value, it will check to ensure that the size of the value being set is compatible with the Token's existing definition. If it is not, an error will be returned. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] TokenNumber The PCD token number. @param[in] Value The value to set for the PCD token. @retval EFI_SUCCESS The PCD service has set the value requested @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was incompatible with a call to this function. Use GetSizeEx() to retrieve the size of the target data. @retval EFI_NOT_FOUND The PCD service could not find the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_SET_BOOLEAN)( IN CONST EFI_GUID *Guid, IN UINTN TokenNumber, IN BOOLEAN Value ); typedef VOID (EFIAPI *EFI_PCD_PROTOCOL_CALLBACK)( IN EFI_GUID *Guid OPTIONAL, IN UINTN CallBackToken, IN OUT VOID *TokenData, IN UINTN TokenDataSize ); /** Specifies a function to be called anytime the value of a designated token is changed. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] CallBackToken The PCD token number to monitor. @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_CALLBACK_ON_SET)( IN CONST EFI_GUID *Guid OPTIONAL, IN UINTN CallBackToken, IN EFI_PCD_PROTOCOL_CALLBACK CallBackFunction ); /** Cancels a callback function that was set through a previous call to the CallBackOnSet function. @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. @param[in] CallBackToken The PCD token number to monitor. @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_CANCEL_CALLBACK)( IN CONST EFI_GUID *Guid OPTIONAL, IN UINTN CallBackToken, IN EFI_PCD_PROTOCOL_CALLBACK CallBackFunction ); /** Gets the next valid token number in a given namespace. This is useful since the PCD infrastructure contains a sparse list of token numbers, and one cannot a priori know what token numbers are valid in the database. @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token. @param[in] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. To retrieve the "first" token, have the pointer reference a TokenNumber value of 0. @retval EFI_SUCCESS The PCD service has retrieved the value requested @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_GET_NEXT_TOKEN)( IN CONST EFI_GUID *Guid OPTIONAL, IN UINTN *TokenNumber ); /** Gets the next valid token namespace for a given namespace. This is useful to traverse the valid token namespaces on a platform. @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token namespace from which the search will start. On output, it designates the next valid token namespace on the platform. If *Guid is NULL, then the GUID of the first token space of the current platform is returned. If the search cannot locate the next valid token namespace, an error is returned and the value of *Guid is undefined. @retval EFI_SUCCESS The PCD service retrieved the value requested. @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace. **/ typedef EFI_STATUS (EFIAPI *EFI_PCD_PROTOCOL_GET_NEXT_TOKEN_SPACE)( IN OUT CONST EFI_GUID **Guid ); typedef struct _EFI_PCD_PROTOCOL { EFI_PCD_PROTOCOL_SET_SKU SetSku; EFI_PCD_PROTOCOL_GET_8 Get8; EFI_PCD_PROTOCOL_GET_16 Get16; EFI_PCD_PROTOCOL_GET_32 Get32; EFI_PCD_PROTOCOL_GET_64 Get64; EFI_PCD_PROTOCOL_GET_POINTER GetPtr; EFI_PCD_PROTOCOL_GET_BOOLEAN GetBool; EFI_PCD_PROTOCOL_GET_SIZE GetSize; EFI_PCD_PROTOCOL_SET_8 Set8; EFI_PCD_PROTOCOL_SET_16 Set16; EFI_PCD_PROTOCOL_SET_32 Set32; EFI_PCD_PROTOCOL_SET_64 Set64; EFI_PCD_PROTOCOL_SET_POINTER SetPtr; EFI_PCD_PROTOCOL_SET_BOOLEAN SetBool; EFI_PCD_PROTOCOL_CALLBACK_ON_SET CallbackOnSet; EFI_PCD_PROTOCOL_CANCEL_CALLBACK CancelCallback; EFI_PCD_PROTOCOL_GET_NEXT_TOKEN GetNextToken; EFI_PCD_PROTOCOL_GET_NEXT_TOKEN_SPACE GetNextTokenSpace; } EFI_PCD_PROTOCOL; #endif /** @file Platform Driver Override protocol as defined in the UEFI 2.1 specification. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_H__ #define __EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_H__ /// /// Global ID for the Platform Driver Override Protocol /// #define EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID \ { \ 0x6b30c738, 0xa391, 0x11d4, {0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL; // // Prototypes for the Platform Driver Override Protocol // /** Retrieves the image handle of the platform override driver for a controller in the system. @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_ PROTOCOL instance. @param ControllerHandle The device handle of the controller to check if a driver override exists. @param DriverImageHandle On input, a pointer to the previous driver image handle returned by GetDriver(). On output, a pointer to the next driver image handle. @retval EFI_SUCCESS The driver override for ControllerHandle was returned in DriverImageHandle. @retval EFI_NOT_FOUND A driver override for ControllerHandle was not found. @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a previous call to GetDriver(). **/ typedef EFI_STATUS (EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER)( IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN OUT EFI_HANDLE *DriverImageHandle ); /** Retrieves the device path of the platform override driver for a controller in the system. @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance. @param ControllerHandle The device handle of the controller to check if a driver override exists. @param DriverImagePath On input, a pointer to the previous driver device path returned by GetDriverPath(). On output, a pointer to the next driver device path. Passing in a pointer to NULL will return the first driver device path for ControllerHandle. @retval EFI_SUCCESS The driver override for ControllerHandle was returned in DriverImageHandle. @retval EFI_UNSUPPORTED The operation is not supported. @retval EFI_NOT_FOUND A driver override for ControllerHandle was not found. @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER DriverImagePath is not a device path that was returned on a previous call to GetDriverPath(). **/ typedef EFI_STATUS (EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH)( IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath ); /** Used to associate a driver image handle with a device path that was returned on a prior call to the GetDriverPath() service. This driver image handle will then be available through the GetDriver() service. @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_ PROTOCOL instance. @param ControllerHandle The device handle of the controller. @param DriverImagePath A pointer to the driver device path that was returned in a prior call to GetDriverPath(). @param DriverImageHandle The driver image handle that was returned by LoadImage() when the driver specified by DriverImagePath was loaded into memory. @retval EFI_SUCCESS The association between DriverImagePath and DriverImageHandle was established for the controller specified by ControllerHandle. @retval EFI_UNSUPPORTED The operation is not supported. @retval EFI_NOT_FOUND DriverImagePath is not a device path that was returned on a prior call to GetDriverPath() for the controller specified by ControllerHandle. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER DriverImagePath is not a valid device path. @retval EFI_INVALID_PARAMETER DriverImageHandle is not a valid image handle. **/ typedef EFI_STATUS (EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED)( IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath, IN EFI_HANDLE DriverImageHandle ); /// /// This protocol matches one or more drivers to a controller. A platform driver /// produces this protocol, and it is installed on a separate handle. This protocol /// is used by the ConnectController() boot service to select the best driver /// for a controller. All of the drivers returned by this protocol have a higher /// precedence than drivers found from an EFI Bus Specific Driver Override Protocol /// or drivers found from the general UEFI driver Binding search algorithm. If more /// than one driver is returned by this protocol, then the drivers are returned in /// order from highest precedence to lowest precedence. /// struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL { EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER GetDriver; EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH GetDriverPath; EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED DriverLoaded; }; extern EFI_GUID gEfiPlatformDriverOverrideProtocolGuid; #endif /** @file UEFI Platform to Driver Configuration Protocol is defined in UEFI specification. This is a protocol that is optionally produced by the platform and optionally consumed by a UEFI Driver in its Start() function. This protocol allows the driver to receive configuration information as part of being started. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PLATFORM_TO_DRIVER_CONFIGUARTION_H__ #define __PLATFORM_TO_DRIVER_CONFIGUARTION_H__ #define EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL_GUID \ { 0x642cd590, 0x8059, 0x4c0a, { 0xa9, 0x58, 0xc5, 0xec, 0x7, 0xd2, 0x3c, 0x4b } } typedef struct _EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL; /** The UEFI driver must call Query early in the Start() function before any time consuming operations are performed. If ChildHandle is NULL the driver is requesting information from the platform about the ControllerHandle that is being started. Information returned from Query may lead to the drivers Start() function failing. If the UEFI driver is a bus driver and producing a ChildHandle, the driver must call Query after the child handle has been created and an EFI_DEVICE_PATH_PROTOCOL has been placed on that handle, but before any time consuming operation is performed. If information return by Query may lead the driver to decide to not create the ChildHandle. The driver must then cleanup and remove the ChildHandle from the system. The UEFI driver repeatedly calls Query, processes the information returned by the platform, and calls Response passing in the arguments returned from Query. The Instance value passed into Response must be the same value passed into the corresponding call to Query. The UEFI driver must continuously call Query and Response until EFI_NOT_FOUND is returned by Query. If the UEFI driver does not recognize the ParameterTypeGuid, it calls Response with a ConfigurationAction of EfiPlatformConfigurationActionUnsupportedGuid. The UEFI driver must then continue calling Query and Response until EFI_NOT_FOUND is returned by Query. This gives the platform an opportunity to pass additional configuration settings using a different ParameterTypeGuid that may be supported by the driver. An Instance value of zero means return the first ParameterBlock in the set of unprocessed parameter blocks. The driver should increment the Instance value by one for each successive call to Query. @param This A pointer to the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL instance. @param ControllerHandle The handle the platform will return configuration information about. @param ChildHandle The handle of the child controller to return information on. This is an optional parameter that may be NULL. It will be NULL for device drivers and for bus drivers that attempt to get options for the bus controller. It will not be NULL for a bus driver that attempts to get options for one of its child controllers. @param Instance Pointer to the Instance value. Zero means return the first query data. The caller should increment this value by one each time to retrieve successive data. @param ParameterTypeGuid An EFI_GUID that defines the contents of ParameterBlock. UEFI drivers must use the ParameterTypeGuid to determine how to parse the ParameterBlock. The caller should not attempt to free ParameterTypeGuid. @param ParameterBlock The platform returns a pointer to the ParameterBlock structure which contains details about the configuration parameters specific to the ParameterTypeGuid. This structure is defined based on the protocol and may be different for different protocols. UEFI driver decodes this structure and its contents based on ParameterTypeGuid. ParameterBlock is allocated by the platform and the platform is responsible for freeing the ParameterBlock after Result is called. @param ParameterBlockSize The platform returns the size of the ParameterBlock in bytes. @retval EFI_SUCCESS The platform return parameter information for ControllerHandle. @retval EFI_NOT_FOUND No more unread Instance exists. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER Instance is NULL. @retval EFI_DEVICE_ERROR A device error occurred while attempting to return parameter block information for the controller specified by ControllerHandle and ChildHandle. @retval EFI_OUT_RESOURCES There are not enough resources available to set the configuration options for the controller specified by ControllerHandle and ChildHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_PLATFORM_TO_DRIVER_CONFIGURATION_QUERY)( IN CONST EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL *This, IN CONST EFI_HANDLE ControllerHandle, IN CONST EFI_HANDLE ChildHandle OPTIONAL, IN CONST UINTN *Instance, OUT EFI_GUID **ParameterTypeGuid, OUT VOID **ParameterBlock, OUT UINTN *ParameterBlockSize ); typedef enum { /// /// The controller specified by ControllerHandle is still /// in a usable state, and its configuration has been updated /// via parsing the ParameterBlock. If required by the /// parameter block, and the module supports an NVRAM store, /// the configuration information from PB was successfully /// saved to the NVRAM. No actions are required before /// this controller can be used again with the updated /// configuration settings. /// EfiPlatformConfigurationActionNone = 0, /// /// The driver has detected that the controller specified /// by ControllerHandle is not in a usable state and /// needs to be stopped. The calling agent can use the /// DisconnectControservice to perform this operation, and /// it should be performed as soon as possible. /// EfiPlatformConfigurationActionStopController = 1, /// /// This controller specified by ControllerHandle needs to /// be stopped and restarted before it can be used again. /// The calling agent can use the DisconnectController() /// and ConnectController() services to perform this /// operation. The restart operation can be delayed until /// all of the configuration options have been set. /// EfiPlatformConfigurationActionRestartController = 2, /// /// A configuration change has been made that requires the /// platform to be restarted before the controller /// specified by ControllerHandle can be used again. The /// calling agent can use the ResetSystem() services to /// perform this operation. The restart operation can be /// delayed until all of the configuration options have /// been set. /// EfiPlatformConfigurationActionRestartPlatform = 3, /// /// The controller specified by ControllerHandle is still /// in a usable state; its configuration has been updated /// via parsing the ParameterBlock. The driver tried to /// update the driver's private NVRAM store with /// information from ParameterBlock and failed. No actions /// are required before this controller can be used again /// with the updated configuration settings, but these /// configuration settings are not guaranteed to persist /// after ControllerHandle is stopped. /// EfiPlatformConfigurationActionNvramFailed = 4, /// /// The controller specified by ControllerHandle is still /// in a usable state; its configuration has not been updated /// via parsing the ParameterBlock. The driver did not support /// the ParameterBlock format identified by ParameterTypeGuid. /// No actions are required before this controller can be used /// again. On additional Query calls from this ControllerHandle, /// the platform should stop returning a ParameterBlock /// qualified by this same ParameterTypeGuid. If no other /// ParameterTypeGuid is supported by the platform, Query /// should return EFI_NOT_FOUND. /// EfiPlatformConfigurationActionUnsupportedGuid = 5, EfiPlatformConfigurationActionMaximum } EFI_PLATFORM_CONFIGURATION_ACTION; /** The UEFI driver repeatedly calls Query, processes the information returned by the platform, and calls Response passing in the arguments returned from Query. The UEFI driver must continuously call Query until EFI_NOT_FOUND is returned. For every call to Query that returns EFI_SUCCESS a corrisponding call to Response is required passing in the same ContollerHandle, ChildHandle, Instance, ParameterTypeGuid, ParameterBlock, and ParameterBlockSize. The UEFI driver may update values in ParameterBlock based on rules defined by ParameterTypeGuid. The platform is responsible for freeing ParameterBlock and the UEFI driver must not try to free it. @param This A pointer to the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL instance. @param ControllerHandle The handle the driver is returning configuration information about. @param ChildHandle The handle of the child controller to return information on. This is an optional parameter that may be NULL. It will be NULL for device drivers, and for bus drivers that attempt to get options for the bus controller. It will not be NULL for a bus driver that attempts to get options for one of its child controllers. Instance Instance data returned from Query(). @param Instance Instance data passed to Query(). @param ParameterTypeGuid ParameterTypeGuid returned from Query. @param ParameterBlock ParameterBlock returned from Query. @param ParameterBlockSize The ParameterBlock size returned from Query. @param ConfigurationAction The driver tells the platform what action is required for ParameterBlock to take effect. @retval EFI_SUCCESS The platform return parameter information for ControllerHandle. @retval EFI_NOT_FOUND Instance was not found. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER Instance is zero. **/ typedef EFI_STATUS (EFIAPI *EFI_PLATFORM_TO_DRIVER_CONFIGURATION_RESPONSE)( IN CONST EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL *This, IN CONST EFI_HANDLE ControllerHandle, IN CONST EFI_HANDLE ChildHandle OPTIONAL, IN CONST UINTN *Instance, IN CONST EFI_GUID *ParameterTypeGuid, IN CONST VOID *ParameterBlock, IN CONST UINTN ParameterBlockSize, IN CONST EFI_PLATFORM_CONFIGURATION_ACTION ConfigurationAction ); /// /// The EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL is used by the /// UEFI driver to query the platform for configuration information. /// The UEFI driver calls Query() multiple times to get /// configuration information from the platform. For every call to /// Query() there must be a matching call to Response() so the /// UEFI driver can inform the platform how it used the /// information passed in from Query(). It's legal for a UEFI /// driver to use Response() to inform the platform it does not /// understand the data returned via Query() and thus no action was /// taken. /// struct _EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL { EFI_PLATFORM_TO_DRIVER_CONFIGURATION_QUERY Query; EFI_PLATFORM_TO_DRIVER_CONFIGURATION_RESPONSE Response; }; #define EFI_PLATFORM_TO_DRIVER_CONFIGURATION_CLP_GUID \ {0x345ecc0e, 0xcb6, 0x4b75, { 0xbb, 0x57, 0x1b, 0x12, 0x9c, 0x47, 0x33,0x3e } } /** ParameterTypeGuid provides the support for parameters communicated through the DMTF SM CLP Specification 1.0 Final Standard to be used to configure the UEFI driver. In this section the producer of the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL is platform firmware and the consumer is the UEFI driver. Note: if future versions of the DMTF SM CLP Specification require changes to the parameter block definition, a newer ParameterTypeGuid will be used. **/ typedef struct { CHAR8 *CLPCommand; ///< A pointer to the null-terminated UTF-8 string that specifies the DMTF SM CLP command ///< line that the driver is required to parse and process when this function is called. ///< See the DMTF SM CLP Specification 1.0 Final Standard for details on the ///< format and syntax of the CLP command line string. CLPCommand buffer ///< is allocated by the producer of the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOOL. UINT32 CLPCommandLength; ///< The length of the CLP Command in bytes. CHAR8 *CLPReturnString; ///< A pointer to the null-terminated UTF-8 string that indicates the CLP return status ///< that the driver is required to provide to the calling agent. ///< The calling agent may parse and/ or pass ///< this for processing and user feedback. The SM CLP Command Response string ///< buffer is filled in by the UEFI driver in the "keyword=value" format ///< described in the SM CLP Specification, unless otherwise requested via the SM ///< CLP Coutput option in the Command Line string buffer. UEFI driver's support ///< for this default "keyword=value" output format is required if the UEFI ///< driver supports this protocol, while support for other SM CLP output ///< formats is optional (the UEFI Driver should return an EFI_UNSUPPORTED if ///< the SM CLP Coutput option requested by the caller is not supported by the ///< UEFI Driver). CLPReturnString buffer is allocated by the consumer of the ///< EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOC OL and undefined prior to the call to ///< Response(). UINT32 CLPReturnStringLength; ///< The length of the CLP return status string in bytes. UINT8 CLPCmdStatus; ///< SM CLP Command Status (see DMTF SM CLP Specification 1.0 Final Standard - ///< Table 4) CLPErrorValue SM CLP Processing Error Value (see DMTF SM ///< CLP Specification 1.0 Final Standard - Table 6). This field is filled in by ///< the consumer of the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOC ///< OL and undefined prior to the call to Response(). UINT8 CLPErrorValue; ///< SM CLP Processing Error Value (see DMTF SM CLP Specification 1.0 Final Standard - Table 6). ///< This field is filled in by the consumer of the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL and undefined prior to the call to Response(). UINT16 CLPMsgCode; ///< Bit 15: OEM Message Code Flag 0 = Message Code is an SM CLP Probable ///< Cause Value. (see SM CLP Specification Table 11) 1 = Message Code is OEM ///< Specific Bits 14-0: Message Code This field is filled in by the consumer of ///< the EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOC OL and undefined prior to the call to ///< Response(). } EFI_CONFIGURE_CLP_PARAMETER_BLK; extern EFI_GUID gEfiPlatformToDriverConfigurationClpGuid; extern EFI_GUID gEfiPlatformToDriverConfigurationProtocolGuid; #endif /** @file Produces EFI_PRINT2_PROTOCOL and EFI_PRINT2S_PROTOCOL. These protocols define basic print functions to print the format unicode and ascii string. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PPRINT2_H__ #define __PPRINT2_H__ #define EFI_PRINT2_PROTOCOL_GUID \ { 0xf05976ef, 0x83f1, 0x4f3d, { 0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38 } } // // Forward reference for pure ANSI compatability // typedef struct _EFI_PRINT2_PROTOCOL EFI_PRINT2_PROTOCOL; /** Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated Unicode format string and a BASE_LIST argument list. Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer and BufferSize. The Unicode string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list specified by Marker based on the contents of the format string. The number of Unicode characters in the produced output buffer is returned not including the Null-terminator. If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). If FormatString is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and BufferSize > (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated Unicode string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated Unicode format string. @param Marker BASE_LIST marker for the variable argument list. @return The number of Unicode characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *UNICODE_BS_PRINT)( OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString, IN BASE_LIST Marker ); /** Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated Unicode format string and variable argument list. This function is similar as snprintf_s defined in C11. Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer and BufferSize. The Unicode string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list based on the contents of the format string. The number of Unicode characters in the produced output buffer is returned not including the Null-terminator. If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). If FormatString is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and BufferSize > (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated Unicode string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated Unicode format string. @param ... Variable argument list whose contents are accessed based on the format string specified by FormatString. @return The number of Unicode characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *UNICODE_S_PRINT)( OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString, ... ); /** Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated ASCII format string and a BASE_LIST argument list. Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer and BufferSize. The Unicode string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list specified by Marker based on the contents of the format string. The number of Unicode characters in the produced output buffer is returned not including the Null-terminator. If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and BufferSize > (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated Unicode string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated ASCII format string. @param Marker BASE_LIST marker for the variable argument list. @return The number of Unicode characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *UNICODE_BS_PRINT_ASCII_FORMAT)( OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN BASE_LIST Marker ); /** Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated ASCII format string and variable argument list. This function is similar as snprintf_s defined in C11. Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer and BufferSize. The Unicode string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list based on the contents of the format string. The number of Unicode characters in the produced output buffer is returned not including the Null-terminator. If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and BufferSize > (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated Unicode string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated ASCII format string. @param ... Variable argument list whose contents are accessed based on the format string specified by FormatString. @return The number of Unicode characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *UNICODE_S_PRINT_ASCII_FORMAT)( OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, ... ); /** Converts a decimal value to a Null-terminated Unicode string. Converts the decimal number specified by Value to a Null-terminated Unicode string specified by Buffer containing at most Width characters. No padding of spaces is ever performed. If Width is 0, then a width of MAXIMUM_VALUE_CHARACTERS is assumed. This function returns the number of Unicode characters in Buffer, not including the Null-terminator. If the conversion contains more than Width characters, this function returns the first Width characters in the conversion, along with the total number of characters in the conversion. Additional conversion parameters are specified in Flags. The Flags bit LEFT_JUSTIFY is always ignored. All conversions are left justified in Buffer. If Width is 0, PREFIX_ZERO is ignored in Flags. If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas are inserted every 3rd digit starting from the right. If RADIX_HEX is set in Flags, then the output buffer will be formatted in hexadecimal format. If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer is padded with '0' characters so the combination of the optional '-' sign character, '0' characters, digit characters for Value, and the Null-terminator add up to Width characters. If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). If Buffer is NULL, then ASSERT(). If Buffer is not aligned on a 16-bit boundary, then ASSERT(). If unsupported bits are set in Flags, then ASSERT(). If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() @param Buffer The pointer to the output buffer for the produced Null-terminated Unicode string. @param Flags The bitmask of flags that specify left justification, zero pad, and commas. @param Value The 64-bit signed value to convert to a string. @param Width The maximum number of Unicode characters to place in Buffer, not including the Null-terminator. @return The number of Unicode characters in Buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *UNICODE_VALUE_TO_STRING)( IN OUT CHAR16 *Buffer, IN UINTN Flags, IN INT64 Value, IN UINTN Width ); /** Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated ASCII format string and a BASE_LIST argument list. Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer and BufferSize. The ASCII string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list specified by Marker based on the contents of the format string. The number of ASCII characters in the produced output buffer is returned not including the Null-terminator. If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and BufferSize > (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated ASCII string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated ASCII format string. @param Marker BASE_LIST marker for the variable argument list. @return The number of ASCII characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *ASCII_BS_PRINT)( OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN BASE_LIST Marker ); /** Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated ASCII format string and variable argument list. This function is similar as snprintf_s defined in C11. Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer and BufferSize. The ASCII string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list based on the contents of the format string. The number of ASCII characters in the produced output buffer is returned not including the Null-terminator. If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and BufferSize > (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated ASCII string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated ASCII format string. @param ... Variable argument list whose contents are accessed based on the format string specified by FormatString. @return The number of ASCII characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *ASCII_S_PRINT)( OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, ... ); /** Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated Unicode format string and a BASE_LIST argument list. Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer and BufferSize. The ASCII string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list specified by Marker based on the contents of the format string. The number of ASCII characters in the produced output buffer is returned not including the Null-terminator. If FormatString is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and BufferSize > (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated ASCII string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated Unicode format string. @param Marker BASE_LIST marker for the variable argument list. @return The number of ASCII characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *ASCII_BS_PRINT_UNICODE_FORMAT)( OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString, IN BASE_LIST Marker ); /** Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated Unicode format string and variable argument list. This function is similar as snprintf_s defined in C11. Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer and BufferSize. The ASCII string is produced by parsing the format string specified by FormatString. Arguments are pulled from the variable argument list based on the contents of the format string. The number of ASCII characters in the produced output buffer is returned not including the Null-terminator. If FormatString is not aligned on a 16-bit boundary, then ASSERT(). If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumAsciiStringLength is not zero, and BufferSize > (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then ASSERT(). Also, the output buffer is unmodified and 0 is returned. If BufferSize is 0, then no output buffer is produced and 0 is returned. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated ASCII string. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. @param FormatString A Null-terminated Unicode format string. @param ... Variable argument list whose contents are accessed based on the format string specified by FormatString. @return The number of ASCII characters in the produced output buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *ASCII_S_PRINT_UNICODE_FORMAT)( OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString, ... ); /** Converts a decimal value to a Null-terminated ASCII string. Converts the decimal number specified by Value to a Null-terminated ASCII string specified by Buffer containing at most Width characters. No padding of spaces is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. The number of ASCII characters in Buffer is returned not including the Null-terminator. If the conversion contains more than Width characters, then only the first Width characters are returned, and the total number of characters required to perform the conversion is returned. Additional conversion parameters are specified in Flags. The Flags bit LEFT_JUSTIFY is always ignored. All conversions are left justified in Buffer. If Width is 0, PREFIX_ZERO is ignored in Flags. If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas are inserted every 3rd digit starting from the right. If RADIX_HEX is set in Flags, then the output buffer will be formatted in hexadecimal format. If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer is padded with '0' characters so the combination of the optional '-' sign character, '0' characters, digit characters for Value, and the Null-terminator add up to Width characters. If Buffer is NULL, then ASSERT(). If unsupported bits are set in Flags, then ASSERT(). If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() @param Buffer The pointer to the output buffer for the produced Null-terminated ASCII string. @param Flags The bitmask of flags that specify left justification, zero pad, and commas. @param Value The 64-bit signed value to convert to a string. @param Width The maximum number of ASCII characters to place in Buffer, not including the Null-terminator. @return The number of ASCII characters in Buffer not including the Null-terminator. **/ typedef UINTN (EFIAPI *ASCII_VALUE_TO_STRING)( OUT CHAR8 *Buffer, IN UINTN Flags, IN INT64 Value, IN UINTN Width ); struct _EFI_PRINT2_PROTOCOL { UNICODE_BS_PRINT UnicodeBSPrint; UNICODE_S_PRINT UnicodeSPrint; UNICODE_BS_PRINT_ASCII_FORMAT UnicodeBSPrintAsciiFormat; UNICODE_S_PRINT_ASCII_FORMAT UnicodeSPrintAsciiFormat; UNICODE_VALUE_TO_STRING UnicodeValueToString; ASCII_BS_PRINT AsciiBSPrint; ASCII_S_PRINT AsciiSPrint; ASCII_BS_PRINT_UNICODE_FORMAT AsciiBSPrintUnicodeFormat; ASCII_S_PRINT_UNICODE_FORMAT AsciiSPrintUnicodeFormat; ASCII_VALUE_TO_STRING AsciiValueToString; }; extern EFI_GUID gEfiPrint2ProtocolGuid; #define EFI_PRINT2S_PROTOCOL_GUID \ { 0xcc252d2, 0xc106, 0x4661, { 0xb5, 0xbd, 0x31, 0x47, 0xa4, 0xf8, 0x1f, 0x92 } } // // Forward reference for pure ANSI compatability // typedef struct _EFI_PRINT2S_PROTOCOL EFI_PRINT2S_PROTOCOL; /** Converts a decimal value to a Null-terminated Unicode string. Converts the decimal number specified by Value to a Null-terminated Unicode string specified by Buffer containing at most Width characters. No padding of spaces is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than Width characters, then only the first Width characters are placed in Buffer. Additional conversion parameters are specified in Flags. The Flags bit LEFT_JUSTIFY is always ignored. All conversions are left justified in Buffer. If Width is 0, PREFIX_ZERO is ignored in Flags. If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas are inserted every 3rd digit starting from the right. If RADIX_HEX is set in Flags, then the output buffer will be formatted in hexadecimal format. If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer is padded with '0' characters so the combination of the optional '-' sign character, '0' characters, digit characters for Value, and the Null-terminator add up to Width characters. If Buffer is not aligned on a 16-bit boundary, then ASSERT(). If an error would be returned, then the function will also ASSERT(). @param Buffer The pointer to the output buffer for the produced Null-terminated Unicode string. @param BufferSize The size of Buffer in bytes, including the Null-terminator. @param Flags The bitmask of flags that specify left justification, zero pad, and commas. @param Value The 64-bit signed value to convert to a string. @param Width The maximum number of Unicode characters to place in Buffer, not including the Null-terminator. @retval RETURN_SUCCESS The decimal value is converted. @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted value. @retval RETURN_INVALID_PARAMETER If Buffer is NULL. If PcdMaximumUnicodeStringLength is not zero, and BufferSize is greater than (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1). If unsupported bits are set in Flags. If both COMMA_TYPE and RADIX_HEX are set in Flags. If Width >= MAXIMUM_VALUE_CHARACTERS. **/ typedef RETURN_STATUS (EFIAPI *UNICODE_VALUE_TO_STRING_S)( IN OUT CHAR16 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN INT64 Value, IN UINTN Width ); /** Converts a decimal value to a Null-terminated Ascii string. Converts the decimal number specified by Value to a Null-terminated Ascii string specified by Buffer containing at most Width characters. No padding of spaces is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than Width characters, then only the first Width characters are placed in Buffer. Additional conversion parameters are specified in Flags. The Flags bit LEFT_JUSTIFY is always ignored. All conversions are left justified in Buffer. If Width is 0, PREFIX_ZERO is ignored in Flags. If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas are inserted every 3rd digit starting from the right. If RADIX_HEX is set in Flags, then the output buffer will be formatted in hexadecimal format. If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer is padded with '0' characters so the combination of the optional '-' sign character, '0' characters, digit characters for Value, and the Null-terminator add up to Width characters. If an error would be returned, then the function will ASSERT(). @param Buffer The pointer to the output buffer for the produced Null-terminated Ascii string. @param BufferSize The size of Buffer in bytes, including the Null-terminator. @param Flags The bitmask of flags that specify left justification, zero pad, and commas. @param Value The 64-bit signed value to convert to a string. @param Width The maximum number of Ascii characters to place in Buffer, not including the Null-terminator. @retval RETURN_SUCCESS The decimal value is converted. @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted value. @retval RETURN_INVALID_PARAMETER If Buffer is NULL. If PcdMaximumAsciiStringLength is not zero, and BufferSize is greater than PcdMaximumAsciiStringLength. If unsupported bits are set in Flags. If both COMMA_TYPE and RADIX_HEX are set in Flags. If Width >= MAXIMUM_VALUE_CHARACTERS. **/ typedef RETURN_STATUS (EFIAPI *ASCII_VALUE_TO_STRING_S)( IN OUT CHAR8 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN INT64 Value, IN UINTN Width ); struct _EFI_PRINT2S_PROTOCOL { UNICODE_BS_PRINT UnicodeBSPrint; UNICODE_S_PRINT UnicodeSPrint; UNICODE_BS_PRINT_ASCII_FORMAT UnicodeBSPrintAsciiFormat; UNICODE_S_PRINT_ASCII_FORMAT UnicodeSPrintAsciiFormat; UNICODE_VALUE_TO_STRING_S UnicodeValueToStringS; ASCII_BS_PRINT AsciiBSPrint; ASCII_S_PRINT AsciiSPrint; ASCII_BS_PRINT_UNICODE_FORMAT AsciiBSPrintUnicodeFormat; ASCII_S_PRINT_UNICODE_FORMAT AsciiSPrintUnicodeFormat; ASCII_VALUE_TO_STRING_S AsciiValueToStringS; }; extern EFI_GUID gEfiPrint2SProtocolGuid; #endif /** @file EFI PXE Base Code Protocol definitions, which is used to access PXE-compatible devices for network access and network booting. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in EFI Specification 1.10. **/ #ifndef __PXE_BASE_CODE_PROTOCOL_H__ #define __PXE_BASE_CODE_PROTOCOL_H__ /// /// PXE Base Code protocol. /// #define EFI_PXE_BASE_CODE_PROTOCOL_GUID \ { \ 0x03c4e603, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE_PROTOCOL; /// /// Protocol defined in EFI1.1. /// typedef EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE; /// /// Default IP TTL and ToS. /// #define DEFAULT_TTL 16 #define DEFAULT_ToS 0 /// /// ICMP error format. /// typedef struct { UINT8 Type; UINT8 Code; UINT16 Checksum; union { UINT32 reserved; UINT32 Mtu; UINT32 Pointer; struct { UINT16 Identifier; UINT16 Sequence; } Echo; } u; UINT8 Data[494]; } EFI_PXE_BASE_CODE_ICMP_ERROR; /// /// TFTP error format. /// typedef struct { UINT8 ErrorCode; CHAR8 ErrorString[127]; } EFI_PXE_BASE_CODE_TFTP_ERROR; /// /// IP Receive Filter definitions. /// #define EFI_PXE_BASE_CODE_MAX_IPCNT 8 /// /// IP Receive Filter structure. /// typedef struct { UINT8 Filters; UINT8 IpCnt; UINT16 reserved; EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT]; } EFI_PXE_BASE_CODE_IP_FILTER; #define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001 #define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002 #define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004 #define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008 /// /// ARP cache entries. /// typedef struct { EFI_IP_ADDRESS IpAddr; EFI_MAC_ADDRESS MacAddr; } EFI_PXE_BASE_CODE_ARP_ENTRY; /// /// ARP route table entries. /// typedef struct { EFI_IP_ADDRESS IpAddr; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS GwAddr; } EFI_PXE_BASE_CODE_ROUTE_ENTRY; // // UDP definitions // typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001 #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002 #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004 #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008 #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010 #define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020 // // Discover() definitions // #define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 #define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 #define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 #define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 #define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4 #define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5 #define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6 #define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7 #define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8 #define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9 #define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10 #define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11 #define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12 #define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13 #define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14 #define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15 #define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16 // // 17 through 32767 are reserved // 32768 through 65279 are for vendor use // 65280 through 65534 are reserved // #define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535 #define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF #define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000 // // PXE Tag definition that identifies the processor // and programming environment of the client system. // These identifiers are defined by IETF: // http://www.ietf.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml // #if defined (MDE_CPU_IA32) #define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x0006 #elif defined (MDE_CPU_X64) #define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x0007 #elif defined (MDE_CPU_ARM) #define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x000A #elif defined (MDE_CPU_AARCH64) #define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x000B #elif defined (MDE_CPU_RISCV64) #define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x001B #endif /// /// Discover() server list structure. /// typedef struct { UINT16 Type; BOOLEAN AcceptAnyResponse; UINT8 Reserved; EFI_IP_ADDRESS IpAddr; } EFI_PXE_BASE_CODE_SRVLIST; /// /// Discover() information override structure. /// typedef struct { BOOLEAN UseMCast; BOOLEAN UseBCast; BOOLEAN UseUCast; BOOLEAN MustUseList; EFI_IP_ADDRESS ServerMCastIp; UINT16 IpCnt; EFI_PXE_BASE_CODE_SRVLIST SrvList[1]; } EFI_PXE_BASE_CODE_DISCOVER_INFO; /// /// TFTP opcode definitions. /// typedef enum { EFI_PXE_BASE_CODE_TFTP_FIRST, EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, EFI_PXE_BASE_CODE_TFTP_READ_FILE, EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, EFI_PXE_BASE_CODE_MTFTP_READ_FILE, EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, EFI_PXE_BASE_CODE_MTFTP_LAST } EFI_PXE_BASE_CODE_TFTP_OPCODE; /// /// MTFTP information. This information is required /// to start or join a multicast TFTP session. It is also required to /// perform the "get file size" and "read directory" operations of MTFTP. /// typedef struct { EFI_IP_ADDRESS MCastIp; EFI_PXE_BASE_CODE_UDP_PORT CPort; EFI_PXE_BASE_CODE_UDP_PORT SPort; UINT16 ListenTimeout; UINT16 TransmitTimeout; } EFI_PXE_BASE_CODE_MTFTP_INFO; /// /// DHCPV4 Packet structure. /// typedef struct { UINT8 BootpOpcode; UINT8 BootpHwType; UINT8 BootpHwAddrLen; UINT8 BootpGateHops; UINT32 BootpIdent; UINT16 BootpSeconds; UINT16 BootpFlags; UINT8 BootpCiAddr[4]; UINT8 BootpYiAddr[4]; UINT8 BootpSiAddr[4]; UINT8 BootpGiAddr[4]; UINT8 BootpHwAddr[16]; UINT8 BootpSrvName[64]; UINT8 BootpBootFile[128]; UINT32 DhcpMagik; UINT8 DhcpOptions[56]; } EFI_PXE_BASE_CODE_DHCPV4_PACKET; /// /// DHCPV6 Packet structure. /// typedef struct { UINT32 MessageType : 8; UINT32 TransactionId : 24; UINT8 DhcpOptions[1024]; } EFI_PXE_BASE_CODE_DHCPV6_PACKET; /// /// Packet structure. /// typedef union { UINT8 Raw[1472]; EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6; } EFI_PXE_BASE_CODE_PACKET; // // PXE Base Code Mode structure // #define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 #define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 /// /// EFI_PXE_BASE_CODE_MODE. /// The data values in this structure are read-only and /// are updated by the code that produces the /// EFI_PXE_BASE_CODE_PROTOCOL functions. /// typedef struct { BOOLEAN Started; BOOLEAN Ipv6Available; BOOLEAN Ipv6Supported; BOOLEAN UsingIpv6; BOOLEAN BisSupported; BOOLEAN BisDetected; BOOLEAN AutoArp; BOOLEAN SendGUID; BOOLEAN DhcpDiscoverValid; BOOLEAN DhcpAckReceived; BOOLEAN ProxyOfferReceived; BOOLEAN PxeDiscoverValid; BOOLEAN PxeReplyReceived; BOOLEAN PxeBisReplyReceived; BOOLEAN IcmpErrorReceived; BOOLEAN TftpErrorReceived; BOOLEAN MakeCallbacks; UINT8 TTL; UINT8 ToS; EFI_IP_ADDRESS StationIp; EFI_IP_ADDRESS SubnetMask; EFI_PXE_BASE_CODE_PACKET DhcpDiscover; EFI_PXE_BASE_CODE_PACKET DhcpAck; EFI_PXE_BASE_CODE_PACKET ProxyOffer; EFI_PXE_BASE_CODE_PACKET PxeDiscover; EFI_PXE_BASE_CODE_PACKET PxeReply; EFI_PXE_BASE_CODE_PACKET PxeBisReply; EFI_PXE_BASE_CODE_IP_FILTER IpFilter; UINT32 ArpCacheEntries; EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; UINT32 RouteTableEntries; EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; } EFI_PXE_BASE_CODE_MODE; // // PXE Base Code Interface Function definitions // /** Enables the use of the PXE Base Code Protocol functions. This function enables the use of the PXE Base Code Protocol functions. If the Started field of the EFI_PXE_BASE_CODE_MODE structure is already TRUE, then EFI_ALREADY_STARTED will be returned. If UseIpv6 is TRUE, then IPv6 formatted addresses will be used in this session. If UseIpv6 is FALSE, then IPv4 formatted addresses will be used in this session. If UseIpv6 is TRUE, and the Ipv6Supported field of the EFI_PXE_BASE_CODE_MODE structure is FALSE, then EFI_UNSUPPORTED will be returned. If there is not enough memory or other resources to start the PXE Base Code Protocol, then EFI_OUT_OF_RESOURCES will be returned. Otherwise, the PXE Base Code Protocol will be started, and all of the fields of the EFI_PXE_BASE_CODE_MODE structure will be initialized as follows: StartedSet to TRUE. Ipv6SupportedUnchanged. Ipv6AvailableUnchanged. UsingIpv6Set to UseIpv6. BisSupportedUnchanged. BisDetectedUnchanged. AutoArpSet to TRUE. SendGUIDSet to FALSE. TTLSet to DEFAULT_TTL. ToSSet to DEFAULT_ToS. DhcpCompletedSet to FALSE. ProxyOfferReceivedSet to FALSE. StationIpSet to an address of all zeros. SubnetMaskSet to a subnet mask of all zeros. DhcpDiscoverZero-filled. DhcpAckZero-filled. ProxyOfferZero-filled. PxeDiscoverValidSet to FALSE. PxeDiscoverZero-filled. PxeReplyValidSet to FALSE. PxeReplyZero-filled. PxeBisReplyValidSet to FALSE. PxeBisReplyZero-filled. IpFilterSet the Filters field to 0 and the IpCnt field to 0. ArpCacheEntriesSet to 0. ArpCacheZero-filled. RouteTableEntriesSet to 0. RouteTableZero-filled. IcmpErrorReceivedSet to FALSE. IcmpErrorZero-filled. TftpErroReceivedSet to FALSE. TftpErrorZero-filled. MakeCallbacksSet to TRUE if the PXE Base Code Callback Protocol is available. Set to FALSE if the PXE Base Code Callback Protocol is not available. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param UseIpv6 Specifies the type of IP addresses that are to be used during the session that is being started. Set to TRUE for IPv6 addresses, and FALSE for IPv4 addresses. @retval EFI_SUCCESS The PXE Base Code Protocol was started. @retval EFI_DEVICE_ERROR The network device encountered an error during this oper @retval EFI_UNSUPPORTED UseIpv6 is TRUE, but the Ipv6Supported field of the EFI_PXE_BASE_CODE_MODE structure is FALSE. @retval EFI_ALREADY_STARTED The PXE Base Code Protocol is already in the started state. @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory or other resources to start the PXE Base Code Protocol. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_START)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN BOOLEAN UseIpv6 ); /** Disables the use of the PXE Base Code Protocol functions. This function stops all activity on the network device. All the resources allocated in Start() are released, the Started field of the EFI_PXE_BASE_CODE_MODE structure is set to FALSE and EFI_SUCCESS is returned. If the Started field of the EFI_PXE_BASE_CODE_MODE structure is already FALSE, then EFI_NOT_STARTED will be returned. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @retval EFI_SUCCESS The PXE Base Code Protocol was stopped. @retval EFI_NOT_STARTED The PXE Base Code Protocol is already in the stopped state. @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_STOP)( IN EFI_PXE_BASE_CODE_PROTOCOL *This ); /** Attempts to complete a DHCPv4 D.O.R.A. (discover / offer / request / acknowledge) or DHCPv6 S.A.R.R (solicit / advertise / request / reply) sequence. This function attempts to complete the DHCP sequence. If this sequence is completed, then EFI_SUCCESS is returned, and the DhcpCompleted, ProxyOfferReceived, StationIp, SubnetMask, DhcpDiscover, DhcpAck, and ProxyOffer fields of the EFI_PXE_BASE_CODE_MODE structure are filled in. If SortOffers is TRUE, then the cached DHCP offer packets will be sorted before they are tried. If SortOffers is FALSE, then the cached DHCP offer packets will be tried in the order in which they are received. Please see the Preboot Execution Environment (PXE) Specification for additional details on the implementation of DHCP. This function can take at least 31 seconds to timeout and return control to the caller. If the DHCP sequence does not complete, then EFI_TIMEOUT will be returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then the DHCP sequence will be stopped and EFI_ABORTED will be returned. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param SortOffers TRUE if the offers received should be sorted. Set to FALSE to try the offers in the order that they are received. @retval EFI_SUCCESS Valid DHCP has completed. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete the DHCP Protocol. @retval EFI_ABORTED The callback function aborted the DHCP Protocol. @retval EFI_TIMEOUT The DHCP Protocol timed out. @retval EFI_ICMP_ERROR An ICMP error packet was received during the DHCP session. @retval EFI_NO_RESPONSE Valid PXE offer was not received. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_DHCP)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN BOOLEAN SortOffers ); /** Attempts to complete the PXE Boot Server and/or boot image discovery sequence. This function attempts to complete the PXE Boot Server and/or boot image discovery sequence. If this sequence is completed, then EFI_SUCCESS is returned, and the PxeDiscoverValid, PxeDiscover, PxeReplyReceived, and PxeReply fields of the EFI_PXE_BASE_CODE_MODE structure are filled in. If UseBis is TRUE, then the PxeBisReplyReceived and PxeBisReply fields of the EFI_PXE_BASE_CODE_MODE structure will also be filled in. If UseBis is FALSE, then PxeBisReplyValid will be set to FALSE. In the structure referenced by parameter Info, the PXE Boot Server list, SrvList[], has two uses: It is the Boot Server IP address list used for unicast discovery (if the UseUCast field is TRUE), and it is the list used for Boot Server verification (if the MustUseList field is TRUE). Also, if the MustUseList field in that structure is TRUE and the AcceptAnyResponse field in the SrvList[] array is TRUE, any Boot Server reply of that type will be accepted. If the AcceptAnyResponse field is FALSE, only responses from Boot Servers with matching IP addresses will be accepted. This function can take at least 10 seconds to timeout and return control to the caller. If the Discovery sequence does not complete, then EFI_TIMEOUT will be returned. Please see the Preboot Execution Environment (PXE) Specification for additional details on the implementation of the Discovery sequence. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then the Discovery sequence is stopped and EFI_ABORTED will be returned. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param Type The type of bootstrap to perform. @param Layer The pointer to the boot server layer number to discover, which must be PXE_BOOT_LAYER_INITIAL when a new server type is being discovered. @param UseBis TRUE if Boot Integrity Services are to be used. FALSE otherwise. @param Info The pointer to a data structure that contains additional information on the type of discovery operation that is to be performed. @retval EFI_SUCCESS The Discovery sequence has been completed. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete Discovery. @retval EFI_ABORTED The callback function aborted the Discovery sequence. @retval EFI_TIMEOUT The Discovery sequence timed out. @retval EFI_ICMP_ERROR An ICMP error packet was received during the PXE discovery session. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_DISCOVER)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN UINT16 Type, IN UINT16 *Layer, IN BOOLEAN UseBis, IN EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL ); /** Used to perform TFTP and MTFTP services. This function is used to perform TFTP and MTFTP services. This includes the TFTP operations to get the size of a file, read a directory, read a file, and write a file. It also includes the MTFTP operations to get the size of a file, read a directory, and read a file. The type of operation is specified by Operation. If the callback function that is invoked during the TFTP/MTFTP operation does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will be returned. For read operations, the return data will be placed in the buffer specified by BufferPtr. If BufferSize is too small to contain the entire downloaded file, then EFI_BUFFER_TOO_SMALL will be returned and BufferSize will be set to zero or the size of the requested file (the size of the requested file is only returned if the TFTP server supports TFTP options). If BufferSize is large enough for the read operation, then BufferSize will be set to the size of the downloaded file, and EFI_SUCCESS will be returned. Applications using the PxeBc.Mtftp() services should use the get-file-size operations to determine the size of the downloaded file prior to using the read-file operations--especially when downloading large (greater than 64 MB) files--instead of making two calls to the read-file operation. Following this recommendation will save time if the file is larger than expected and the TFTP server does not support TFTP option extensions. Without TFTP option extension support, the client has to download the entire file, counting and discarding the received packets, to determine the file size. For write operations, the data to be sent is in the buffer specified by BufferPtr. BufferSize specifies the number of bytes to send. If the write operation completes successfully, then EFI_SUCCESS will be returned. For TFTP "get file size" operations, the size of the requested file or directory is returned in BufferSize, and EFI_SUCCESS will be returned. If the TFTP server does not support options, the file will be downloaded into a bit bucket and the length of the downloaded file will be returned. For MTFTP "get file size" operations, if the MTFTP server does not support the "get file size" option, EFI_UNSUPPORTED will be returned. This function can take up to 10 seconds to timeout and return control to the caller. If the TFTP sequence does not complete, EFI_TIMEOUT will be returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then the TFTP sequence is stopped and EFI_ABORTED will be returned. The format of the data returned from a TFTP read directory operation is a null-terminated filename followed by a null-terminated information string, of the form "size year-month-day hour:minute:second" (i.e. %d %d-%d-%d %d:%d:%f - note that the seconds field can be a decimal number), where the date and time are UTC. For an MTFTP read directory command, there is additionally a null-terminated multicast IP address preceding the filename of the form %d.%d.%d.%d for IP v4. The final entry is itself null-terminated, so that the final information string is terminated with two null octets. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param Operation The type of operation to perform. @param BufferPtr A pointer to the data buffer. @param Overwrite Only used on write file operations. TRUE if a file on a remote server can be overwritten. @param BufferSize For get-file-size operations, *BufferSize returns the size of the requested file. @param BlockSize The requested block size to be used during a TFTP transfer. @param ServerIp The TFTP / MTFTP server IP address. @param Filename A Null-terminated ASCII string that specifies a directory name or a file name. @param Info The pointer to the MTFTP information. @param DontUseBuffer Set to FALSE for normal TFTP and MTFTP read file operation. @retval EFI_SUCCESS The TFTP/MTFTP operation was completed. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. @retval EFI_BUFFER_TOO_SMALL The buffer is not large enough to complete the read operation. @retval EFI_ABORTED The callback function aborted the TFTP/MTFTP operation. @retval EFI_TIMEOUT The TFTP/MTFTP operation timed out. @retval EFI_ICMP_ERROR An ICMP error packet was received during the MTFTP session. @retval EFI_TFTP_ERROR A TFTP error packet was received during the MTFTP session. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_MTFTP)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, IN OUT VOID *BufferPtr OPTIONAL, IN BOOLEAN Overwrite, IN OUT UINT64 *BufferSize, IN UINTN *BlockSize OPTIONAL, IN EFI_IP_ADDRESS *ServerIp, IN UINT8 *Filename OPTIONAL, IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, IN BOOLEAN DontUseBuffer ); /** Writes a UDP packet to the network interface. This function writes a UDP packet specified by the (optional HeaderPtr and) BufferPtr parameters to the network interface. The UDP header is automatically built by this routine. It uses the parameters OpFlags, DestIp, DestPort, GatewayIp, SrcIp, and SrcPort to build this header. If the packet is successfully built and transmitted through the network interface, then EFI_SUCCESS will be returned. If a timeout occurs during the transmission of the packet, then EFI_TIMEOUT will be returned. If an ICMP error occurs during the transmission of the packet, then the IcmpErrorReceived field is set to TRUE, the IcmpError field is filled in and EFI_ICMP_ERROR will be returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will be returned. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param OpFlags The UDP operation flags. @param DestIp The destination IP address. @param DestPort The destination UDP port number. @param GatewayIp The gateway IP address. @param SrcIp The source IP address. @param SrcPort The source UDP port number. @param HeaderSize An optional field which may be set to the length of a header at HeaderPtr to be prefixed to the data at BufferPtr. @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the data at BufferPtr. @param BufferSize A pointer to the size of the data at BufferPtr. @param BufferPtr A pointer to the data to be written. @retval EFI_SUCCESS The UDP Write operation was completed. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_BAD_BUFFER_SIZE The buffer is too long to be transmitted. @retval EFI_ABORTED The callback function aborted the UDP Write operation. @retval EFI_TIMEOUT The UDP Write operation timed out. @retval EFI_ICMP_ERROR An ICMP error packet was received during the UDP write session. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN UINT16 OpFlags, IN EFI_IP_ADDRESS *DestIp, IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, IN EFI_IP_ADDRESS *SrcIp OPTIONAL, IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, IN UINTN *HeaderSize OPTIONAL, IN VOID *HeaderPtr OPTIONAL, IN UINTN *BufferSize, IN VOID *BufferPtr ); /** Reads a UDP packet from the network interface. This function reads a UDP packet from a network interface. The data contents are returned in (the optional HeaderPtr and) BufferPtr, and the size of the buffer received is returned in BufferSize. If the input BufferSize is smaller than the UDP packet received (less optional HeaderSize), it will be set to the required size, and EFI_BUFFER_TOO_SMALL will be returned. In this case, the contents of BufferPtr are undefined, and the packet is lost. If a UDP packet is successfully received, then EFI_SUCCESS will be returned, and the information from the UDP header will be returned in DestIp, DestPort, SrcIp, and SrcPort if they are not NULL. Depending on the values of OpFlags and the DestIp, DestPort, SrcIp, and SrcPort input values, different types of UDP packet receive filtering will be performed. The following tables summarize these receive filter operations. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param OpFlags The UDP operation flags. @param DestIp The destination IP address. @param DestPort The destination UDP port number. @param SrcIp The source IP address. @param SrcPort The source UDP port number. @param HeaderSize An optional field which may be set to the length of a header at HeaderPtr to be prefixed to the data at BufferPtr. @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the data at BufferPtr. @param BufferSize A pointer to the size of the data at BufferPtr. @param BufferPtr A pointer to the data to be read. @retval EFI_SUCCESS The UDP Read operation was completed. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. @retval EFI_BUFFER_TOO_SMALL The packet is larger than Buffer can hold. @retval EFI_ABORTED The callback function aborted the UDP Read operation. @retval EFI_TIMEOUT The UDP Read operation timed out. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_UDP_READ)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN UINT16 OpFlags, IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, IN UINTN *HeaderSize OPTIONAL, IN VOID *HeaderPtr OPTIONAL, IN OUT UINTN *BufferSize, IN VOID *BufferPtr ); /** Updates the IP receive filters of a network device and enables software filtering. The NewFilter field is used to modify the network device's current IP receive filter settings and to enable a software filter. This function updates the IpFilter field of the EFI_PXE_BASE_CODE_MODE structure with the contents of NewIpFilter. The software filter is used when the USE_FILTER in OpFlags is set to UdpRead(). The current hardware filter remains in effect no matter what the settings of OpFlags are, so that the meaning of ANY_DEST_IP set in OpFlags to UdpRead() is from those packets whose reception is enabled in hardware - physical NIC address (unicast), broadcast address, logical address or addresses (multicast), or all (promiscuous). UdpRead() does not modify the IP filter settings. Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. If an application or driver wishes to preserve the IP receive filter settings, it will have to preserve the IP receive filter settings before these calls, and use SetIpFilter() to restore them after the calls. If incompatible filtering is requested (for example, PROMISCUOUS with anything else), or if the device does not support a requested filter setting and it cannot be accommodated in software (for example, PROMISCUOUS not supported), EFI_INVALID_PARAMETER will be returned. The IPlist field is used to enable IPs other than the StationIP. They may be multicast or unicast. If IPcnt is set as well as EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP, then both the StationIP and the IPs from the IPlist will be used. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param NewFilter The pointer to the new set of IP receive filters. @retval EFI_SUCCESS The IP receive filter settings were updated. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter ); /** Uses the ARP protocol to resolve a MAC address. This function uses the ARP protocol to resolve a MAC address. The UsingIpv6 field of the EFI_PXE_BASE_CODE_MODE structure is used to determine if IPv4 or IPv6 addresses are being used. The IP address specified by IpAddr is used to resolve a MAC address. If the ARP protocol succeeds in resolving the specified address, then the ArpCacheEntries and ArpCache fields of the EFI_PXE_BASE_CODE_MODE structure are updated, and EFI_SUCCESS is returned. If MacAddr is not NULL, the resolved MAC address is placed there as well. If the PXE Base Code protocol is in the stopped state, then EFI_NOT_STARTED is returned. If the ARP protocol encounters a timeout condition while attempting to resolve an address, then EFI_TIMEOUT is returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED is returned. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param IpAddr The pointer to the IP address that is used to resolve a MAC address. @param MacAddr If not NULL, a pointer to the MAC address that was resolved with the ARP protocol. @retval EFI_SUCCESS The IP or MAC address was resolved. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. @retval EFI_ABORTED The callback function aborted the ARP Protocol. @retval EFI_TIMEOUT The ARP Protocol encountered a timeout condition. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_ARP)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN EFI_IP_ADDRESS *IpAddr, IN EFI_MAC_ADDRESS *MacAddr OPTIONAL ); /** Updates the parameters that affect the operation of the PXE Base Code Protocol. This function sets parameters that affect the operation of the PXE Base Code Protocol. The parameter specified by NewAutoArp is used to control the generation of ARP protocol packets. If NewAutoArp is TRUE, then ARP Protocol packets will be generated as required by the PXE Base Code Protocol. If NewAutoArp is FALSE, then no ARP Protocol packets will be generated. In this case, the only mappings that are available are those stored in the ArpCache of the EFI_PXE_BASE_CODE_MODE structure. If there are not enough mappings in the ArpCache to perform a PXE Base Code Protocol service, then the service will fail. This function updates the AutoArp field of the EFI_PXE_BASE_CODE_MODE structure to NewAutoArp. The SetParameters() call must be invoked after a Callback Protocol is installed to enable the use of callbacks. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param NewAutoArp If not NULL, a pointer to a value that specifies whether to replace the current value of AutoARP. @param NewSendGUID If not NULL, a pointer to a value that specifies whether to replace the current value of SendGUID. @param NewTTL If not NULL, a pointer to be used in place of the current value of TTL, the "time to live" field of the IP header. @param NewToS If not NULL, a pointer to be used in place of the current value of ToS, the "type of service" field of the IP header. @param NewMakeCallback If not NULL, a pointer to a value that specifies whether to replace the current value of the MakeCallback field of the Mode structure. @retval EFI_SUCCESS The new parameters values were updated. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN BOOLEAN *NewAutoArp OPTIONAL, IN BOOLEAN *NewSendGUID OPTIONAL, IN UINT8 *NewTTL OPTIONAL, IN UINT8 *NewToS OPTIONAL, IN BOOLEAN *NewMakeCallback OPTIONAL ); /** Updates the station IP address and/or subnet mask values of a network device. This function updates the station IP address and/or subnet mask values of a network device. The NewStationIp field is used to modify the network device's current IP address. If NewStationIP is NULL, then the current IP address will not be modified. Otherwise, this function updates the StationIp field of the EFI_PXE_BASE_CODE_MODE structure with NewStationIp. The NewSubnetMask field is used to modify the network device's current subnet mask. If NewSubnetMask is NULL, then the current subnet mask will not be modified. Otherwise, this function updates the SubnetMask field of the EFI_PXE_BASE_CODE_MODE structure with NewSubnetMask. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param NewStationIp The pointer to the new IP address to be used by the network device. @param NewSubnetMask The pointer to the new subnet mask to be used by the network device. @retval EFI_SUCCESS The new station IP address and/or subnet mask were updated. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, IN EFI_IP_ADDRESS *NewStationIp OPTIONAL, IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL ); /** Updates the contents of the cached DHCP and Discover packets. The pointers to the new packets are used to update the contents of the cached packets in the EFI_PXE_BASE_CODE_MODE structure. @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. @param NewDhcpDiscoverValid The pointer to a value that will replace the current DhcpDiscoverValid field. @param NewDhcpAckReceived The pointer to a value that will replace the current DhcpAckReceived field. @param NewProxyOfferReceived The pointer to a value that will replace the current ProxyOfferReceived field. @param NewPxeDiscoverValid The pointer to a value that will replace the current ProxyOfferReceived field. @param NewPxeReplyReceived The pointer to a value that will replace the current PxeReplyReceived field. @param NewPxeBisReplyReceived The pointer to a value that will replace the current PxeBisReplyReceived field. @param NewDhcpDiscover The pointer to the new cached DHCP Discover packet contents. @param NewDhcpAck The pointer to the new cached DHCP Ack packet contents. @param NewProxyOffer The pointer to the new cached Proxy Offer packet contents. @param NewPxeDiscover The pointer to the new cached PXE Discover packet contents. @param NewPxeReply The pointer to the new cached PXE Reply packet contents. @param NewPxeBisReply The pointer to the new cached PXE BIS Reply packet contents. @retval EFI_SUCCESS The cached packet contents were updated. @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. @retval EFI_INVALID_PARAMETER This is NULL or not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. **/ typedef EFI_STATUS (EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS)( IN EFI_PXE_BASE_CODE_PROTOCOL *This, BOOLEAN *NewDhcpDiscoverValid OPTIONAL, BOOLEAN *NewDhcpAckReceived OPTIONAL, BOOLEAN *NewProxyOfferReceived OPTIONAL, BOOLEAN *NewPxeDiscoverValid OPTIONAL, BOOLEAN *NewPxeReplyReceived OPTIONAL, BOOLEAN *NewPxeBisReplyReceived OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply OPTIONAL, IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL ); // // PXE Base Code Protocol structure // #define EFI_PXE_BASE_CODE_PROTOCOL_REVISION 0x00010000 // // Revision defined in EFI1.1 // #define EFI_PXE_BASE_CODE_INTERFACE_REVISION EFI_PXE_BASE_CODE_PROTOCOL_REVISION /// /// The EFI_PXE_BASE_CODE_PROTOCOL is used to control PXE-compatible devices. /// An EFI_PXE_BASE_CODE_PROTOCOL will be layered on top of an /// EFI_MANAGED_NETWORK_PROTOCOL protocol in order to perform packet level transactions. /// The EFI_PXE_BASE_CODE_PROTOCOL handle also supports the /// EFI_LOAD_FILE_PROTOCOL protocol. This provides a clean way to obtain control from the /// boot manager if the boot path is from the remote device. /// struct _EFI_PXE_BASE_CODE_PROTOCOL { /// /// The revision of the EFI_PXE_BASE_CODE_PROTOCOL. All future revisions must /// be backwards compatible. If a future version is not backwards compatible /// it is not the same GUID. /// UINT64 Revision; EFI_PXE_BASE_CODE_START Start; EFI_PXE_BASE_CODE_STOP Stop; EFI_PXE_BASE_CODE_DHCP Dhcp; EFI_PXE_BASE_CODE_DISCOVER Discover; EFI_PXE_BASE_CODE_MTFTP Mtftp; EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite; EFI_PXE_BASE_CODE_UDP_READ UdpRead; EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter; EFI_PXE_BASE_CODE_ARP Arp; EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters; EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp; EFI_PXE_BASE_CODE_SET_PACKETS SetPackets; /// /// The pointer to the EFI_PXE_BASE_CODE_MODE data for this device. /// EFI_PXE_BASE_CODE_MODE *Mode; }; extern EFI_GUID gEfiPxeBaseCodeProtocolGuid; #endif /** @file It is invoked when the PXE Base Code Protocol is about to transmit, has received, or is waiting to receive a packet. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in EFI Specification 1.10 **/ #ifndef _PXE_BASE_CODE_CALLBACK_H_ #define _PXE_BASE_CODE_CALLBACK_H_ /// /// Call Back Definitions. /// #define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID \ { \ 0x245dca21, 0xfb7b, 0x11d3, {0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } /// /// UEFI Revision Number Definition. /// #define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION 0x00010000 /// /// EFI 1.1 Revision Number defintion. /// #define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION \ EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION /// /// UEFI Protocol name. /// typedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL; /// /// EFI1.1 Protocol name. /// typedef EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK; /// /// Event type list for PXE Base Code Protocol function. /// typedef enum { EFI_PXE_BASE_CODE_FUNCTION_FIRST, EFI_PXE_BASE_CODE_FUNCTION_DHCP, EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, EFI_PXE_BASE_CODE_FUNCTION_MTFTP, EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, EFI_PXE_BASE_CODE_FUNCTION_ARP, EFI_PXE_BASE_CODE_FUNCTION_IGMP, EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST } EFI_PXE_BASE_CODE_FUNCTION; /// /// Callback status type. /// typedef enum { EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST } EFI_PXE_BASE_CODE_CALLBACK_STATUS; /** Callback function that is invoked when the PXE Base Code Protocol is about to transmit, has received, or is waiting to receive a packet. This function is invoked when the PXE Base Code Protocol is about to transmit, has received, or is waiting to receive a packet. Parameters Function and Received specify the type of event. Parameters PacketLen and Packet specify the packet that generated the event. If these fields are zero and NULL respectively, then this is a status update callback. If the operation specified by Function is to continue, then CALLBACK_STATUS_CONTINUE should be returned. If the operation specified by Function should be aborted, then CALLBACK_STATUS_ABORT should be returned. Due to the polling nature of UEFI device drivers, a callback function should not execute for more than 5 ms. The SetParameters() function must be called after a Callback Protocol is installed to enable the use of callbacks. @param This The pointer to the EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL instance. @param Function The PXE Base Code Protocol function that is waiting for an event. @param Received TRUE if the callback is being invoked due to a receive event. FALSE if the callback is being invoked due to a transmit event. @param PacketLen The length, in bytes, of Packet. This field will have a value of zero if this is a wait for receive event. @param Packet If Received is TRUE, a pointer to the packet that was just received; otherwise a pointer to the packet that is about to be transmitted. @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE if Function specifies a continue operation @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT if Function specifies an abort operation **/ typedef EFI_PXE_BASE_CODE_CALLBACK_STATUS (EFIAPI *EFI_PXE_CALLBACK)( IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *This, IN EFI_PXE_BASE_CODE_FUNCTION Function, IN BOOLEAN Received, IN UINT32 PacketLen, IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL ); /// /// Protocol that is invoked when the PXE Base Code Protocol is about /// to transmit, has received, or is waiting to receive a packet. /// struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL { /// /// The revision of the EFI_PXE_BASE_CODE_PROTOCOL. All future revisions must /// be backwards compatible. If a future version is not backwards compatible /// it is not the same GUID. /// UINT64 Revision; EFI_PXE_CALLBACK Callback; }; extern EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid; #endif /** @file Real Time clock Architectural Protocol as defined in PI Specification VOLUME 2 DXE This code abstracts time and data functions. Used to provide Time and date related EFI runtime services. The GetTime (), SetTime (), GetWakeupTime (), and SetWakeupTime () UEFI 2.0 services are added to the EFI system table and the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer. No CRC of the EFI system table is required, since that is done in the DXE core. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_REAL_TIME_CLOCK_H__ #define __ARCH_PROTOCOL_REAL_TIME_CLOCK_H__ /// /// Global ID for the Real Time Clock Architectural Protocol /// #define EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID \ { 0x27CFAC87, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } extern EFI_GUID gEfiRealTimeClockArchProtocolGuid; #endif /** @file This protocol provide registering and unregistering services to status code consumers while in DXE. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol was introduced in PI Specification 1.2. **/ #ifndef __REPORT_STATUS_CODE_HANDLER_PROTOCOL_H__ #define __REPORT_STATUS_CODE_HANDLER_PROTOCOL_H__ #define EFI_RSC_HANDLER_PROTOCOL_GUID \ { \ 0x86212936, 0xe76, 0x41c8, {0xa0, 0x3a, 0x2a, 0xf2, 0xfc, 0x1c, 0x39, 0xe2} \ } typedef EFI_STATUS (EFIAPI *EFI_RSC_HANDLER_CALLBACK)( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, IN EFI_GUID *CallerId, IN EFI_STATUS_CODE_DATA *Data ); /** Register the callback function for ReportStatusCode() notification. When this function is called the function pointer is added to an internal list and any future calls to ReportStatusCode() will be forwarded to the Callback function. During the bootservices, this is the callback for which this service can be invoked. The report status code router will create an event such that the callback function is only invoked at the TPL for which it was registered. The entity that registers for the callback should also register for an event upon generation of exit boot services and invoke the unregister service. If the handler does not have a TPL dependency, it should register for a callback at TPL high. The router infrastructure will support making callbacks at runtime, but the caller for runtime invocation must meet the following criteria: 1. must be a runtime driver type so that its memory is not reclaimed 2. not unregister at exit boot services so that the router will still have its callback address 3. the caller must be self-contained (eg. Not call out into any boot-service interfaces) and be runtime safe, in general. @param[in] Callback A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is called when a call to ReportStatusCode() occurs. @param[in] Tpl TPL at which callback can be safely invoked. @retval EFI_SUCCESS Function was successfully registered. @retval EFI_INVALID_PARAMETER The callback function was NULL. @retval EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be registered. @retval EFI_ALREADY_STARTED The function was already registered. It can't be registered again. **/ typedef EFI_STATUS (EFIAPI *EFI_RSC_HANDLER_REGISTER)( IN EFI_RSC_HANDLER_CALLBACK Callback, IN EFI_TPL Tpl ); /** Remove a previously registered callback function from the notification list. A callback function must be unregistered before it is deallocated. It is important that any registered callbacks that are not runtime complaint be unregistered when ExitBootServices() is called. @param[in] Callback A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is to be unregistered. @retval EFI_SUCCESS The function was successfully unregistered. @retval EFI_INVALID_PARAMETER The callback function was NULL. @retval EFI_NOT_FOUND The callback function was not found to be unregistered. **/ typedef EFI_STATUS (EFIAPI *EFI_RSC_HANDLER_UNREGISTER)( IN EFI_RSC_HANDLER_CALLBACK Callback ); typedef struct { EFI_RSC_HANDLER_REGISTER Register; EFI_RSC_HANDLER_UNREGISTER Unregister; } EFI_RSC_HANDLER_PROTOCOL; extern EFI_GUID gEfiRscHandlerProtocolGuid; #endif // __REPORT_STATUS_CODE_HANDLER_H__ /** @file Reset Architectural Protocol as defined in PI Specification VOLUME 2 DXE Used to provide ResetSystem runtime services The ResetSystem () UEFI 2.0 service is added to the EFI system table and the EFI_RESET_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_RESET_H__ #define __ARCH_PROTOCOL_RESET_H__ /// /// Global ID for the Reset Architectural Protocol /// #define EFI_RESET_ARCH_PROTOCOL_GUID \ { 0x27CFAC88, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } extern EFI_GUID gEfiResetArchProtocolGuid; #endif /** @file EFI_RNG_PROTOCOL as defined in UEFI 2.4. The UEFI Random Number Generator Protocol is used to provide random bits for use in applications, or entropy for seeding other random number generators. Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_RNG_PROTOCOL_H__ #define __EFI_RNG_PROTOCOL_H__ /// /// Global ID for the Random Number Generator Protocol /// #define EFI_RNG_PROTOCOL_GUID \ { \ 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ } typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL; /// /// A selection of EFI_RNG_PROTOCOL algorithms. /// The algorithms listed are optional, not meant to be exhaustive and be argmented by /// vendors or other industry standards. /// typedef EFI_GUID EFI_RNG_ALGORITHM; /// /// The algorithms corresponds to SP800-90 as defined in /// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random /// Bit Generators", March 2007. /// #define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \ { \ 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \ } #define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \ { \ 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \ } #define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \ { \ 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \ } /// /// The algorithms correspond to X9.31 as defined in /// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using /// the 3-Key Triple DES and AES Algorithm", January 2005. /// #define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \ { \ 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \ } #define EFI_RNG_ALGORITHM_X9_31_AES_GUID \ { \ 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \ } /// /// The "raw" algorithm, when supported, is intended to provide entropy directly from /// the source, without it going through some deterministic random bit generator. /// #define EFI_RNG_ALGORITHM_RAW \ { \ 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \ } /** Returns information about the random number generation implementation. @param[in] This A pointer to the EFI_RNG_PROTOCOL instance. @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList. On output with a return code of EFI_SUCCESS, the size in bytes of the data returned in RNGAlgorithmList. On output with a return code of EFI_BUFFER_TOO_SMALL, the size of RNGAlgorithmList required to obtain the list. @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver with one EFI_RNG_ALGORITHM element for each supported RNG algorithm. The list must not change across multiple calls to the same driver. The first algorithm in the list is the default algorithm for the driver. @retval EFI_SUCCESS The RNG algorithm list was returned successfully. @retval EFI_UNSUPPORTED The services is not supported by this driver. @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a hardware or firmware error. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result. **/ typedef EFI_STATUS (EFIAPI *EFI_RNG_GET_INFO)( IN EFI_RNG_PROTOCOL *This, IN OUT UINTN *RNGAlgorithmListSize, OUT EFI_RNG_ALGORITHM *RNGAlgorithmList ); /** Produces and returns an RNG value using either the default or specified RNG algorithm. @param[in] This A pointer to the EFI_RNG_PROTOCOL instance. @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG algorithm to use. May be NULL in which case the function will use its default RNG algorithm. @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by RNGValue. The driver shall return exactly this numbers of bytes. @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the resulting RNG value. @retval EFI_SUCCESS The RNG value was returned successfully. @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by this driver. @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or firmware error. @retval EFI_NOT_READY There is not enough random data available to satisfy the length requested by RNGValueLength. @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero. **/ typedef EFI_STATUS (EFIAPI *EFI_RNG_GET_RNG)( IN EFI_RNG_PROTOCOL *This, IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL, IN UINTN RNGValueLength, OUT UINT8 *RNGValue ); /// /// The Random Number Generator (RNG) protocol provides random bits for use in /// applications, or entropy for seeding other random number generators. /// struct _EFI_RNG_PROTOCOL { EFI_RNG_GET_INFO GetInfo; EFI_RNG_GET_RNG GetRNG; }; extern EFI_GUID gEfiRngProtocolGuid; extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid; extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid; extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid; extern EFI_GUID gEfiRngAlgorithmX9313DesGuid; extern EFI_GUID gEfiRngAlgorithmX931AesGuid; extern EFI_GUID gEfiRngAlgorithmRaw; #endif /** @file Runtime Architectural Protocol as defined in PI Specification VOLUME 2 DXE Allows the runtime functionality of the DXE Foundation to be contained in a separate driver. It also provides hooks for the DXE Foundation to export information that is needed at runtime. As such, this protocol allows services to the DXE Foundation to manage runtime drivers and events. This protocol also implies that the runtime services required to transition to virtual mode, SetVirtualAddressMap() and ConvertPointer(), have been registered into the UEFI Runtime Table in the UEFI System Table. This protocol must be produced by a runtime DXE driver and may only be consumed by the DXE Foundation. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_RUNTIME_H__ #define __ARCH_PROTOCOL_RUNTIME_H__ /// /// Global ID for the Runtime Architectural Protocol /// #define EFI_RUNTIME_ARCH_PROTOCOL_GUID \ { 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33 } } typedef struct _EFI_RUNTIME_ARCH_PROTOCOL EFI_RUNTIME_ARCH_PROTOCOL; /// /// LIST_ENTRY from BaseType /// typedef LIST_ENTRY EFI_LIST_ENTRY; typedef struct _EFI_RUNTIME_IMAGE_ENTRY EFI_RUNTIME_IMAGE_ENTRY; /// /// EFI_RUNTIME_IMAGE_ENTRY /// struct _EFI_RUNTIME_IMAGE_ENTRY { /// /// Start of image that has been loaded in memory. It is a pointer /// to either the DOS header or PE header of the image. /// VOID *ImageBase; /// /// Size in bytes of the image represented by ImageBase. /// UINT64 ImageSize; /// /// Information about the fix-ups that were performed on ImageBase when it was /// loaded into memory. /// VOID *RelocationData; /// /// The ImageHandle passed into ImageBase when it was loaded. /// EFI_HANDLE Handle; /// /// Entry for this node in the EFI_RUNTIME_ARCHITECTURE_PROTOCOL.ImageHead list. /// EFI_LIST_ENTRY Link; }; typedef struct _EFI_RUNTIME_EVENT_ENTRY EFI_RUNTIME_EVENT_ENTRY; /// /// EFI_RUNTIME_EVENT_ENTRY /// struct _EFI_RUNTIME_EVENT_ENTRY { /// /// The same as Type passed into CreateEvent(). /// UINT32 Type; /// /// The same as NotifyTpl passed into CreateEvent(). /// EFI_TPL NotifyTpl; /// /// The same as NotifyFunction passed into CreateEvent(). /// EFI_EVENT_NOTIFY NotifyFunction; /// /// The same as NotifyContext passed into CreateEvent(). /// VOID *NotifyContext; /// /// The EFI_EVENT returned by CreateEvent(). Event must be in runtime memory. /// EFI_EVENT *Event; /// /// Entry for this node in the /// EFI_RUNTIME_ARCHITECTURE_PROTOCOL.EventHead list. /// EFI_LIST_ENTRY Link; }; /// /// Allows the runtime functionality of the DXE Foundation to be contained in a /// separate driver. It also provides hooks for the DXE Foundation to export /// information that is needed at runtime. As such, this protocol allows the DXE /// Foundation to manage runtime drivers and events. This protocol also implies /// that the runtime services required to transition to virtual mode, /// SetVirtualAddressMap() and ConvertPointer(), have been registered into the /// EFI Runtime Table in the EFI System Partition. This protocol must be produced /// by a runtime DXE driver and may only be consumed by the DXE Foundation. /// struct _EFI_RUNTIME_ARCH_PROTOCOL { EFI_LIST_ENTRY ImageHead; ///< A list of type EFI_RUNTIME_IMAGE_ENTRY. EFI_LIST_ENTRY EventHead; ///< A list of type EFI_RUNTIME_EVENT_ENTRY. UINTN MemoryDescriptorSize; ///< Size of a memory descriptor that is returned by GetMemoryMap(). UINT32 MemoryDesciptorVersion; ///< Version of a memory descriptor that is returned by GetMemoryMap(). UINTN MemoryMapSize; ///< Size of the memory map in bytes contained in MemoryMapPhysical and MemoryMapVirtual. EFI_MEMORY_DESCRIPTOR *MemoryMapPhysical; ///< Pointer to a runtime buffer that contains a copy of ///< the memory map returned via GetMemoryMap(). EFI_MEMORY_DESCRIPTOR *MemoryMapVirtual; ///< Pointer to MemoryMapPhysical that is updated to virtual mode after SetVirtualAddressMap(). BOOLEAN VirtualMode; ///< Boolean that is TRUE if SetVirtualAddressMap() has been called. BOOLEAN AtRuntime; ///< Boolean that is TRUE if ExitBootServices () has been called. }; extern EFI_GUID gEfiRuntimeArchProtocolGuid; #endif /** @file EFI_SCSI_IO_PROTOCOL as defined in UEFI 2.0. This protocol is used by code, typically drivers, running in the EFI boot services environment to access SCSI devices. In particular, functions for managing devices on SCSI buses are defined here. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_SCSI_IO_PROTOCOL_H__ #define __EFI_SCSI_IO_PROTOCOL_H__ #define EFI_SCSI_IO_PROTOCOL_GUID \ { \ 0x932f47e6, 0x2362, 0x4002, {0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ } /// /// Forward reference for pure ANSI compatability /// typedef struct _EFI_SCSI_IO_PROTOCOL EFI_SCSI_IO_PROTOCOL; // // SCSI Device type information, defined in the SCSI Primary Commands standard (e.g., SPC-4) // #define EFI_SCSI_IO_TYPE_DISK 0x00 ///< Disk device #define EFI_SCSI_IO_TYPE_TAPE 0x01 ///< Tape device #define EFI_SCSI_IO_TYPE_PRINTER 0x02 ///< Printer #define EFI_SCSI_IO_TYPE_PROCESSOR 0x03 ///< Processor #define EFI_SCSI_IO_TYPE_WORM 0x04 ///< Write-once read-multiple #define EFI_SCSI_IO_TYPE_CDROM 0x05 ///< CD or DVD device #define EFI_SCSI_IO_TYPE_SCANNER 0x06 ///< Scanner device #define EFI_SCSI_IO_TYPE_OPTICAL 0x07 ///< Optical memory device #define EFI_SCSI_IO_TYPE_MEDIUMCHANGER 0x08 ///< Medium Changer device #define EFI_SCSI_IO_TYPE_COMMUNICATION 0x09 ///< Communications device #define MFI_SCSI_IO_TYPE_A 0x0A ///< Obsolete #define MFI_SCSI_IO_TYPE_B 0x0B ///< Obsolete #define MFI_SCSI_IO_TYPE_RAID 0x0C ///< Storage array controller device (e.g., RAID) #define MFI_SCSI_IO_TYPE_SES 0x0D ///< Enclosure services device #define MFI_SCSI_IO_TYPE_RBC 0x0E ///< Simplified direct-access device (e.g., magnetic disk) #define MFI_SCSI_IO_TYPE_OCRW 0x0F ///< Optical card reader/writer device #define MFI_SCSI_IO_TYPE_BRIDGE 0x10 ///< Bridge Controller Commands #define MFI_SCSI_IO_TYPE_OSD 0x11 ///< Object-based Storage Device #define EFI_SCSI_IO_TYPE_RESERVED_LOW 0x12 ///< Reserved (low) #define EFI_SCSI_IO_TYPE_RESERVED_HIGH 0x1E ///< Reserved (high) #define EFI_SCSI_IO_TYPE_UNKNOWN 0x1F ///< Unknown no device type // // SCSI Data Direction definition // #define EFI_SCSI_IO_DATA_DIRECTION_READ 0 #define EFI_SCSI_IO_DATA_DIRECTION_WRITE 1 #define EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL 2 // // SCSI Host Adapter Status definition // #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK 0x00 #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 ///< timeout when processing the command #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT 0x0b ///< timeout when waiting for the command processing #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d ///< a message reject was received when processing command #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET 0x0e ///< a bus reset was detected #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 ///< the adapter failed in issuing request sense command #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 ///< selection timeout #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 ///< data overrun or data underrun #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE 0x13 ///< Unexepected bus free #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 ///< Target bus phase sequence failure #define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OTHER 0x7f // // SCSI Target Status definition // #define EFI_SCSI_IO_STATUS_TARGET_GOOD 0x00 #define EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION 0x02 ///< check condition #define EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET 0x04 ///< condition met #define EFI_SCSI_IO_STATUS_TARGET_BUSY 0x08 ///< busy #define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE 0x10 ///< intermediate #define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 ///< intermediate-condition met #define EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT 0x18 ///< reservation conflict #define EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED 0x22 ///< command terminated #define EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL 0x28 ///< queue full typedef struct { /// /// The timeout, in 100 ns units, to use for the execution of this SCSI /// Request Packet. A Timeout value of 0 means that this function /// will wait indefinitely for the SCSI Request Packet to execute. If /// Timeout is greater than zero, then this function will return /// EFI_TIMEOUT if the time required to execute the SCSI Request /// Packet is greater than Timeout. /// UINT64 Timeout; /// /// A pointer to the data buffer to transfer between the SCSI /// controller and the SCSI device for SCSI READ command /// VOID *InDataBuffer; /// /// A pointer to the data buffer to transfer between the SCSI /// controller and the SCSI device for SCSI WRITE command. /// VOID *OutDataBuffer; /// /// A pointer to the sense data that was generated by the execution of /// the SCSI Request Packet. /// VOID *SenseData; /// /// A pointer to buffer that contains the Command Data Block to /// send to the SCSI device. /// VOID *Cdb; /// /// On Input, the size, in bytes, of InDataBuffer. On output, the /// number of bytes transferred between the SCSI controller and the SCSI device. /// UINT32 InTransferLength; /// /// On Input, the size, in bytes of OutDataBuffer. On Output, the /// Number of bytes transferred between SCSI Controller and the SCSI device. /// UINT32 OutTransferLength; /// /// The length, in bytes, of the buffer Cdb. The standard values are /// 6, 10, 12, and 16, but other values are possible if a variable length CDB is used. /// UINT8 CdbLength; /// /// The direction of the data transfer. 0 for reads, 1 for writes. A /// value of 2 is Reserved for Bi-Directional SCSI commands. /// UINT8 DataDirection; /// /// The status of the SCSI Host Controller that produces the SCSI /// bus where the SCSI device attached when the SCSI Request /// Packet was executed on the SCSI Controller. /// UINT8 HostAdapterStatus; /// /// The status returned by the SCSI device when the SCSI Request /// Packet was executed. /// UINT8 TargetStatus; /// /// On input, the length in bytes of the SenseData buffer. On /// output, the number of bytes written to the SenseData buffer. /// UINT8 SenseDataLength; } EFI_SCSI_IO_SCSI_REQUEST_PACKET; /** Retrieves the device type information of the SCSI Controller. @param This Protocol instance pointer. @param DeviceType A pointer to the device type information retrieved from the SCSI Controller. @retval EFI_SUCCESS Retrieved the device type information successfully. @retval EFI_INVALID_PARAMETER The DeviceType is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE)( IN EFI_SCSI_IO_PROTOCOL *This, OUT UINT8 *DeviceType ); /** Retrieves the device location in the SCSI channel. @param This Protocol instance pointer. @param Target A pointer to the Target ID of a SCSI device on the SCSI channel. @param Lun A pointer to the LUN of the SCSI device on the SCSI channel. @retval EFI_SUCCESS Retrieves the device location successfully. @retval EFI_INVALID_PARAMETER The Target or Lun is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION)( IN EFI_SCSI_IO_PROTOCOL *This, IN OUT UINT8 **Target, OUT UINT64 *Lun ); /** Resets the SCSI Bus that the SCSI Controller is attached to. @param This Protocol instance pointer. @retval EFI_SUCCESS The SCSI bus is reset successfully. @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus. @retval EFI_UNSUPPORTED The bus reset operation is not supported by the SCSI Host Controller. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI bus. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_BUS)( IN EFI_SCSI_IO_PROTOCOL *This ); /** Resets the SCSI Controller that the device handle specifies. @param This Protocol instance pointer. @retval EFI_SUCCESS Reset the SCSI controller successfully. @retval EFI_DEVICE_ERROR Errors were encountered when resetting the SCSI Controller. @retval EFI_UNSUPPORTED The SCSI bus does not support a device reset operation. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI Controller. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_DEVICE)( IN EFI_SCSI_IO_PROTOCOL *This ); /** Sends a SCSI Request Packet to the SCSI Controller for execution. @param This Protocol instance pointer. @param Packet The SCSI request packet to send to the SCSI Controller specified by the device handle. @param Event If the SCSI bus to which the SCSI device is attached does not support non-blocking I/O, then Event is ignored, and blocking I/O is performed. If Event is NULL, then blocking I/O is performed. If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed, and Event will be signaled when the SCSI Request Packet completes. @retval EFI_SUCCESS The SCSI Request Packet was sent by the host successfully, and TransferLength bytes were transferred to/from DataBuffer. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could not be transferred. The actual number of bytes transferred is returned in TransferLength. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many SCSI Command Packets already queued.The caller may retry again later. @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SCSI Request Packet. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid. The SCSI Request Packet was not sent, so no additional status information is available. @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by the SCSI initiator(i.e., SCSI Host Controller). The SCSI Request Packet was not sent, so no additional status information is available. @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND)( IN EFI_SCSI_IO_PROTOCOL *This, IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ); /// /// Provides services to manage and communicate with SCSI devices. /// struct _EFI_SCSI_IO_PROTOCOL { EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE GetDeviceType; EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION GetDeviceLocation; EFI_SCSI_IO_PROTOCOL_RESET_BUS ResetBus; EFI_SCSI_IO_PROTOCOL_RESET_DEVICE ResetDevice; EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND ExecuteScsiCommand; /// /// Supplies the alignment requirement for any buffer used in a data transfer. /// IoAlign values of 0 and 1 mean that the buffer can be placed anywhere in memory. /// Otherwise, IoAlign must be a power of 2, and the requirement is that the /// start address of a buffer must be evenly divisible by IoAlign with no remainder. /// UINT32 IoAlign; }; extern EFI_GUID gEfiScsiIoProtocolGuid; #endif /** @file SCSI Pass Through protocol as defined in EFI 1.1. This protocol allows information about a SCSI channel to be collected, and allows SCSI Request Packets to be sent to any SCSI devices on a SCSI channel even if those devices are not boot devices. This protocol is attached to the device handle of each SCSI channel in a system that the protocol supports, and can be used for diagnostics. It may also be used to build a Block I/O driver for SCSI hard drives and SCSI CD-ROM or DVD drives to allow those devices to become boot devices. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SCSI_PASS_THROUGH_H__ #define __SCSI_PASS_THROUGH_H__ #define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \ { \ 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77 } \ } /// /// Forward reference for pure ANSI compatability /// typedef struct _EFI_SCSI_PASS_THRU_PROTOCOL EFI_SCSI_PASS_THRU_PROTOCOL; #define EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 #define EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 #define EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 // // SCSI Host Adapter Status definition // #define EFI_SCSI_STATUS_HOST_ADAPTER_OK 0x00 #define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 // timeout when processing the command #define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT 0x0b // timeout when waiting for the command processing #define EFI_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d // a message reject was received when processing command #define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_RESET 0x0e // a bus reset was detected #define EFI_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f #define EFI_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 // the adapter failed in issuing request sense command #define EFI_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 // selection timeout #define EFI_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 // data overrun or data underrun #define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_FREE 0x13 // Unexepected bus free #define EFI_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 // Target bus phase sequence failure #define EFI_SCSI_STATUS_HOST_ADAPTER_OTHER 0x7f // // SCSI Target Status definition // #define EFI_SCSI_STATUS_TARGET_GOOD 0x00 #define EFI_SCSI_STATUS_TARGET_CHECK_CONDITION 0x02 // check condition #define EFI_SCSI_STATUS_TARGET_CONDITION_MET 0x04 // condition met #define EFI_SCSI_STATUS_TARGET_BUSY 0x08 // busy #define EFI_SCSI_STATUS_TARGET_INTERMEDIATE 0x10 // intermediate #define EFI_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 // intermediate-condition met #define EFI_SCSI_STATUS_TARGET_RESERVATION_CONFLICT 0x18 // reservation conflict #define EFI_SCSI_STATUS_TARGET_COMMOND_TERMINATED 0x22 // command terminated #define EFI_SCSI_STATUS_TARGET_QUEUE_FULL 0x28 // queue full typedef struct { /// /// The timeout, in 100 ns units, to use for the execution of this SCSI /// Request Packet. A Timeout value of 0 means that this function /// will wait indefinitely for the SCSI Request Packet to execute. If /// Timeout is greater than zero, then this function will return /// EFI_TIMEOUT if the time required to execute the SCSI Request /// Packet is greater than Timeout. /// UINT64 Timeout; /// /// A pointer to the data buffer to transfer between the SCSI /// controller and the SCSI device. Must be aligned to the boundary /// specified in the IoAlign field of the /// EFI_SCSI_PASS_THRU_MODE structure. /// VOID *DataBuffer; /// /// A pointer to the sense data that was generated by the execution of /// the SCSI Request Packet. /// VOID *SenseData; /// /// A pointer to buffer that contains the Command Data Block to /// send to the SCSI device. /// VOID *Cdb; /// /// On Input, the size, in bytes, of InDataBuffer. On output, the /// number of bytes transferred between the SCSI controller and the SCSI device. /// UINT32 TransferLength; /// /// The length, in bytes, of the buffer Cdb. The standard values are /// 6, 10, 12, and 16, but other values are possible if a variable length CDB is used. /// UINT8 CdbLength; /// /// The direction of the data transfer. 0 for reads, 1 for writes. A /// value of 2 is Reserved for Bi-Directional SCSI commands. /// UINT8 DataDirection; /// /// The status of the SCSI Host Controller that produces the SCSI /// bus where the SCSI device attached when the SCSI Request /// Packet was executed on the SCSI Controller. /// UINT8 HostAdapterStatus; /// /// The status returned by the SCSI device when the SCSI Request /// Packet was executed. /// UINT8 TargetStatus; /// /// On input, the length in bytes of the SenseData buffer. On /// output, the number of bytes written to the SenseData buffer. /// UINT8 SenseDataLength; } EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET; typedef struct { /// /// A Null-terminated Unicode string that represents the printable name of the SCSI controller. /// CHAR16 *ControllerName; /// /// A Null-terminated Unicode string that represents the printable name of the SCSI channel. /// CHAR16 *ChannelName; /// /// The Target ID of the host adapter on the SCSI channel. /// UINT32 AdapterId; /// /// Additional information on the attributes of the SCSI channel. /// UINT32 Attributes; /// /// Supplies the alignment requirement for any buffer used in a data transfer. /// UINT32 IoAlign; } EFI_SCSI_PASS_THRU_MODE; /** Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required, and the non-blocking I/O functionality is optional. @param This Protocol instance pointer. @param Target The Target ID of the SCSI device to send the SCSI Request Packet. @param Lun The LUN of the SCSI device to send the SCSI Request Packet. @param Packet A pointer to the SCSI Request Packet to send to the SCSI device specified by Target and Lun. @param Event If non-blocking I/O is not supported then Event is ignored, and blocking I/O is performed. If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O is supported, then non-blocking I/O is performed, and Event will be signaled when the SCSI Request Packet completes @retval EFI_SUCCESS The SCSI Request Packet was sent by the host, and TransferLength bytes were transferred to/from DataBuffer. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could not be transferred. The actual number of bytes transferred is returned in TransferLength. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many SCSI Request Packets already queued. The caller may retry again later. @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SCSI Request Packet. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid. The SCSI Request Packet was not sent, so no additional status information is available. @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by the host adapter. The SCSI Request Packet was not sent, so no additional status information is available. @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute. See HostAdapterStatus, TargetStatus, SenseDataLength, and SenseData in that order for additional status information. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_PASSTHRU)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This, IN UINT32 Target, IN UINT64 Lun, IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ); /** Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. @param This Protocol instance pointer. @param Target On input, a pointer to the Target ID of a SCSI device present on the SCSI channel. On output, a pointer to the Target ID of the next SCSI device present on a SCSI channel. An input value of 0xFFFFFFFF retrieves the Target ID of the first SCSI device present on a SCSI channel. @param Lun On input, a pointer to the LUN of a SCSI device present on the SCSI channel. On output, a pointer to the LUN of the next SCSI device present on a SCSI channel. @retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI channel was returned in Target and Lun. @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. @retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF, and Target and Lun were not returned on a previous call to GetNextDevice(). **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This, IN OUT UINT32 *Target, IN OUT UINT64 *Lun ); /** Used to allocate and build a device path node for a SCSI device on a SCSI channel. @param This Protocol instance pointer. @param Target The Target ID of the SCSI device for which a device path node is to be allocated and built. @param Lun The LUN of the SCSI device for which a device path node is to be allocated and built. @param DevicePath A pointer to a single device path node that describes the SCSI device specified by Target and Lun. This function is responsible for allocating the buffer DevicePath with the boot service AllocatePool(). It is the caller's responsibility to free DevicePath when the caller is finished with DevicePath. @retval EFI_SUCCESS The device path node that describes the SCSI device specified by Target and Lun was allocated and returned in DevicePath. @retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does not exist on the SCSI channel. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate DevicePath. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This, IN UINT32 Target, IN UINT64 Lun, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ); /** Used to translate a device path node to a Target ID and LUN. @param This Protocol instance pointer. @param DevicePath A pointer to the device path node that describes a SCSI device on the SCSI channel. @param Target A pointer to the Target ID of a SCSI device on the SCSI channel. @param Lun A pointer to the LUN of a SCSI device on the SCSI channel. @retval EFI_SUCCESS DevicePath was successfully translated to a Target ID and LUN, and they were returned in Target and Lun. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_INVALID_PARAMETER Target is NULL. @retval EFI_INVALID_PARAMETER Lun is NULL. @retval EFI_UNSUPPORTED This driver does not support the device path node type in DevicePath. @retval EFI_NOT_FOUND A valid translation from DevicePath to a Target ID and LUN does not exist. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_GET_TARGET_LUN)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT32 *Target, OUT UINT64 *Lun ); /** Resets a SCSI channel.This operation resets all the SCSI devices connected to the SCSI channel. @param This Protocol instance pointer. @retval EFI_SUCCESS The SCSI channel was reset. @retval EFI_UNSUPPORTED The SCSI channel does not support a channel reset operation. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI channel. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_RESET_CHANNEL)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This ); /** Resets a SCSI device that is connected to a SCSI channel. @param This Protocol instance pointer. @param Target The Target ID of the SCSI device to reset. @param Lun The LUN of the SCSI device to reset. @retval EFI_SUCCESS The SCSI device specified by Target and Lun was reset. @retval EFI_UNSUPPORTED The SCSI channel does not support a target reset operation. @retval EFI_INVALID_PARAMETER Target or Lun are invalid. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI device specified by Target and Lun. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI device specified by Target and Lun. **/ typedef EFI_STATUS (EFIAPI *EFI_SCSI_PASS_THRU_RESET_TARGET)( IN EFI_SCSI_PASS_THRU_PROTOCOL *This, IN UINT32 Target, IN UINT64 Lun ); /// /// The EFI_SCSI_PASS_THRU_PROTOCOL provides information about a SCSI channel and /// the ability to send SCSI Request Packets to any SCSI device attached to that SCSI channel. The /// information includes the Target ID of the host controller on the SCSI channel, the attributes of /// the SCSI channel, the printable name for the SCSI controller, and the printable name of the /// SCSI channel. /// struct _EFI_SCSI_PASS_THRU_PROTOCOL { /// /// A pointer to the EFI_SCSI_PASS_THRU_MODE data for this SCSI channel. /// EFI_SCSI_PASS_THRU_MODE *Mode; EFI_SCSI_PASS_THRU_PASSTHRU PassThru; EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE GetNextDevice; EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; EFI_SCSI_PASS_THRU_GET_TARGET_LUN GetTargetLun; EFI_SCSI_PASS_THRU_RESET_CHANNEL ResetChannel; EFI_SCSI_PASS_THRU_RESET_TARGET ResetTarget; }; extern EFI_GUID gEfiScsiPassThruProtocolGuid; #endif /** @file EFI_EXT_SCSI_PASS_THRU_PROTOCOL as defined in UEFI 2.0. This protocol provides services that allow SCSI Pass Thru commands to be sent to SCSI devices attached to a SCSI channel. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__ #define __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__ #define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \ { \ 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe } \ } typedef struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL EFI_EXT_SCSI_PASS_THRU_PROTOCOL; #define TARGET_MAX_BYTES 0x10 #define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 #define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 #define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 // // DataDirection // #define EFI_EXT_SCSI_DATA_DIRECTION_READ 0 #define EFI_EXT_SCSI_DATA_DIRECTION_WRITE 1 #define EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL 2 // // HostAdapterStatus // #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK 0x00 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT 0x0b #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET 0x0e #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE 0x13 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 #define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER 0x7f // // TargetStatus // #define EFI_EXT_SCSI_STATUS_TARGET_GOOD 0x00 #define EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION 0x02 #define EFI_EXT_SCSI_STATUS_TARGET_CONDITION_MET 0x04 #define EFI_EXT_SCSI_STATUS_TARGET_BUSY 0x08 #define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE 0x10 #define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 #define EFI_EXT_SCSI_STATUS_TARGET_RESERVATION_CONFLICT 0x18 #define EFI_EXT_SCSI_STATUS_TARGET_TASK_SET_FULL 0x28 #define EFI_EXT_SCSI_STATUS_TARGET_ACA_ACTIVE 0x30 #define EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED 0x40 typedef struct { /// /// The Target ID of the host adapter on the SCSI channel. /// UINT32 AdapterId; /// /// Additional information on the attributes of the SCSI channel. /// UINT32 Attributes; /// /// Supplies the alignment requirement for any buffer used in a data transfer. /// UINT32 IoAlign; } EFI_EXT_SCSI_PASS_THRU_MODE; typedef struct { /// /// The timeout, in 100 ns units, to use for the execution of this SCSI /// Request Packet. A Timeout value of 0 means that this function /// will wait indefinitely for the SCSI Request Packet to execute. If /// Timeout is greater than zero, then this function will return /// EFI_TIMEOUT if the time required to execute the SCSI /// Request Packet is greater than Timeout. /// UINT64 Timeout; /// /// A pointer to the data buffer to transfer between the SCSI /// controller and the SCSI device for read and bidirectional commands. /// VOID *InDataBuffer; /// /// A pointer to the data buffer to transfer between the SCSI /// controller and the SCSI device for write or bidirectional commands. /// VOID *OutDataBuffer; /// /// A pointer to the sense data that was generated by the execution of /// the SCSI Request Packet. /// VOID *SenseData; /// /// A pointer to buffer that contains the Command Data Block to /// send to the SCSI device specified by Target and Lun. /// VOID *Cdb; /// /// On Input, the size, in bytes, of InDataBuffer. On output, the /// number of bytes transferred between the SCSI controller and the SCSI device. /// UINT32 InTransferLength; /// /// On Input, the size, in bytes of OutDataBuffer. On Output, the /// Number of bytes transferred between SCSI Controller and the SCSI device. /// UINT32 OutTransferLength; /// /// The length, in bytes, of the buffer Cdb. The standard values are 6, /// 10, 12, and 16, but other values are possible if a variable length CDB is used. /// UINT8 CdbLength; /// /// The direction of the data transfer. 0 for reads, 1 for writes. A /// value of 2 is Reserved for Bi-Directional SCSI commands. /// UINT8 DataDirection; /// /// The status of the host adapter specified by This when the SCSI /// Request Packet was executed on the target device. /// UINT8 HostAdapterStatus; /// /// The status returned by the device specified by Target and Lun /// when the SCSI Request Packet was executed. /// UINT8 TargetStatus; /// /// On input, the length in bytes of the SenseData buffer. On /// output, the number of bytes written to the SenseData buffer. /// UINT8 SenseDataLength; } EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET; /** Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking I/O functionality is optional. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param Target The Target is an array of size TARGET_MAX_BYTES and it represents the id of the SCSI device to send the SCSI Request Packet. Each transport driver may choose to utilize a subset of this size to suit the needs of transport target representation. For example, a Fibre Channel driver may use only 8 bytes (WWN) to represent an FC target. @param Lun The LUN of the SCSI device to send the SCSI Request Packet. @param Packet A pointer to the SCSI Request Packet to send to the SCSI device specified by Target and Lun. @param Event If nonblocking I/O is not supported then Event is ignored, and blocking I/O is performed. If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O is supported, then nonblocking I/O is performed, and Event will be signaled when the SCSI Request Packet completes. @retval EFI_SUCCESS The SCSI Request Packet was sent by the host. For bi-directional commands, InTransferLength bytes were transferred from InDataBuffer. For write and bi-directional commands, OutTransferLength bytes were transferred by OutDataBuffer. @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was not executed. The number of bytes that could be transferred is returned in InTransferLength. For write and bi-directional commands, OutTransferLength bytes were transferred by OutDataBuffer. @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many SCSI Request Packets already queued. The caller may retry again later. @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SCSI Request Packet. @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid. @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by the host adapter. This includes the case of Bi-directional SCSI commands not supported by the implementation. The SCSI Request Packet was not sent, so no additional status information is available. @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_PASSTHRU)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ); /** Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on a SCSI channel. These can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI channel. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param Target On input, a pointer to the Target ID (an array of size TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel. On output, a pointer to the Target ID (an array of TARGET_MAX_BYTES) of the next SCSI device present on a SCSI channel. An input value of 0xF(all bytes in the array are 0xF) in the Target array retrieves the Target ID of the first SCSI device present on a SCSI channel. @param Lun On input, a pointer to the LUN of a SCSI device present on the SCSI channel. On output, a pointer to the LUN of the next SCSI device present on a SCSI channel. @retval EFI_SUCCESS The Target ID and LUN of the next SCSI device on the SCSI channel was returned in Target and Lun. @retval EFI_INVALID_PARAMETER Target array is not all 0xF, and Target and Lun were not returned on a previous call to GetNextTargetLun(). @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN OUT UINT8 **Target, IN OUT UINT64 *Lun ); /** Used to allocate and build a device path node for a SCSI device on a SCSI channel. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param Target The Target is an array of size TARGET_MAX_BYTES and it specifies the Target ID of the SCSI device for which a device path node is to be allocated and built. Transport drivers may chose to utilize a subset of this size to suit the representation of targets. For example, a Fibre Channel driver may use only 8 bytes (WWN) in the array to represent a FC target. @param Lun The LUN of the SCSI device for which a device path node is to be allocated and built. @param DevicePath A pointer to a single device path node that describes the SCSI device specified by Target and Lun. This function is responsible for allocating the buffer DevicePath with the boot service AllocatePool(). It is the caller's responsibility to free DevicePath when the caller is finished with DevicePath. @retval EFI_SUCCESS The device path node that describes the SCSI device specified by Target and Lun was allocated and returned in DevicePath. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does not exist on the SCSI channel. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate DevicePath. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ); /** Used to translate a device path node to a Target ID and LUN. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param DevicePath A pointer to a single device path node that describes the SCSI device on the SCSI channel. @param Target A pointer to the Target Array which represents the ID of a SCSI device on the SCSI channel. @param Lun A pointer to the LUN of a SCSI device on the SCSI channel. @retval EFI_SUCCESS DevicePath was successfully translated to a Target ID and LUN, and they were returned in Target and Lun. @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL. @retval EFI_NOT_FOUND A valid translation from DevicePath to a Target ID and LUN does not exist. @retval EFI_UNSUPPORTED This driver does not support the device path node type in DevicePath. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT8 **Target, OUT UINT64 *Lun ); /** Resets a SCSI channel. This operation resets all the SCSI devices connected to the SCSI channel. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @retval EFI_SUCCESS The SCSI channel was reset. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI channel. @retval EFI_UNSUPPORTED The SCSI channel does not support a channel reset operation. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This ); /** Resets a SCSI logical unit that is connected to a SCSI channel. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param Target The Target is an array of size TARGET_MAX_BYTE and it represents the target port ID of the SCSI device containing the SCSI logical unit to reset. Transport drivers may chose to utilize a subset of this array to suit the representation of their targets. @param Lun The LUN of the SCSI device to reset. @retval EFI_SUCCESS The SCSI device specified by Target and Lun was reset. @retval EFI_INVALID_PARAMETER Target or Lun is NULL. @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI device specified by Target and Lun. @retval EFI_UNSUPPORTED The SCSI channel does not support a target reset operation. @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI device specified by Target and Lun. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun ); /** Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target IDs for the SCSI channel. Regardless, the caller of this function must probe the Target ID returned to see if a SCSI device is actually present at that location on the SCSI channel. @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. @param Target (TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel. On output, a pointer to the Target ID (an array of TARGET_MAX_BYTES) of the next SCSI device present on a SCSI channel. An input value of 0xF(all bytes in the array are 0xF) in the Target array retrieves the Target ID of the first SCSI device present on a SCSI channel. @retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI channel was returned in Target. @retval EFI_INVALID_PARAMETER Target or Lun is NULL. @retval EFI_TIMEOUT Target array is not all 0xF, and Target was not returned on a previous call to GetNextTarget(). @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. **/ typedef EFI_STATUS (EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET)( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN OUT UINT8 **Target ); /// /// The EFI_EXT_SCSI_PASS_THRU_PROTOCOL provides information about a SCSI channel /// and the ability to send SCI Request Packets to any SCSI device attached to /// that SCSI channel. The information includes the Target ID of the host controller /// on the SCSI channel and the attributes of the SCSI channel. /// struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL { /// /// A pointer to the EFI_EXT_SCSI_PASS_THRU_MODE data for this SCSI channel. /// EFI_EXT_SCSI_PASS_THRU_MODE *Mode; EFI_EXT_SCSI_PASS_THRU_PASSTHRU PassThru; EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN GetNextTargetLun; EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN GetTargetLun; EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL ResetChannel; EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN ResetTargetLun; EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET GetNextTarget; }; extern EFI_GUID gEfiExtScsiPassThruProtocolGuid; #endif /** @file Security Architectural Protocol as defined in PI Specification VOLUME 2 DXE Used to provide Security services. Specifically, dependening upon the authentication state of a discovered driver in a Firmware Volume, the portable DXE Core Dispatcher will call into the Security Architectural Protocol (SAP) with the authentication state of the driver. This call-out allows for OEM-specific policy decisions to be made, such as event logging for attested boots, locking flash in response to discovering an unsigned driver or failed signature check, or other exception response. The SAP can also change system behavior by having the DXE core put a driver in the Schedule-On-Request (SOR) state. This will allow for later disposition of the driver by platform agent, such as Platform BDS. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_SECURITY_H__ #define __ARCH_PROTOCOL_SECURITY_H__ /// /// Global ID for the Security Code Architectural Protocol /// #define EFI_SECURITY_ARCH_PROTOCOL_GUID \ { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } } typedef struct _EFI_SECURITY_ARCH_PROTOCOL EFI_SECURITY_ARCH_PROTOCOL; /** The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific policy from the DXE core response to an attempt to use a file that returns a given status for the authentication check from the section extraction protocol. The possible responses in a given SAP implementation may include locking flash upon failure to authenticate, attestation logging for all signed drivers, and other exception operations. The File parameter allows for possible logging within the SAP of the driver. If File is NULL, then EFI_INVALID_PARAMETER is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is not safe for the DXE Core to use under any circumstances, then EFI_ACCESS_DENIED is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is not safe for the DXE Core to use right now, but it might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is returned. @param This The EFI_SECURITY_ARCH_PROTOCOL instance. @param AuthenticationStatus This is the authentication type returned from the Section Extraction protocol. See the Section Extraction Protocol Specification for details on this type. @param File This is a pointer to the device path of the file that is being dispatched. This will optionally be used for logging. @retval EFI_SUCCESS The file specified by File did authenticate, and the platform policy dictates that the DXE Core may use File. @retval EFI_INVALID_PARAMETER Driver is NULL. @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and the platform policy dictates that File should be placed in the untrusted state. A file may be promoted from the untrusted to the trusted state at a future time with a call to the Trust() DXE Service. @retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and the platform policy dictates that File should not be used for any purpose. **/ typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE)( IN CONST EFI_SECURITY_ARCH_PROTOCOL *This, IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File ); /// /// The EFI_SECURITY_ARCH_PROTOCOL is used to abstract platform-specific policy /// from the DXE core. This includes locking flash upon failure to authenticate, /// attestation logging, and other exception operations. /// struct _EFI_SECURITY_ARCH_PROTOCOL { EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState; }; extern EFI_GUID gEfiSecurityArchProtocolGuid; #endif /** @file Security2 Architectural Protocol as defined in PI Specification1.2.1 VOLUME 2 DXE Abstracts security-specific functions from the DXE Foundation of UEFI Image Verification, Trusted Computing Group (TCG) measured boot, and User Identity policy for image loading and consoles. This protocol must be produced by a boot service or runtime DXE driver. This protocol is optional and must be published prior to the EFI_SECURITY_ARCH_PROTOCOL. As a result, the same driver must publish both of these interfaces. When both Security and Security2 Architectural Protocols are published, LoadImage must use them in accordance with the following rules: The Security2 protocol must be used on every image being loaded. The Security protocol must be used after the Securiy2 protocol and only on images that have been read using Firmware Volume protocol. When only Security architectural protocol is published, LoadImage must use it on every image being loaded. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_SECURITY2_H__ #define __ARCH_PROTOCOL_SECURITY2_H__ /// /// Global ID for the Security2 Code Architectural Protocol /// #define EFI_SECURITY2_ARCH_PROTOCOL_GUID \ { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } } typedef struct _EFI_SECURITY2_ARCH_PROTOCOL EFI_SECURITY2_ARCH_PROTOCOL; /** The DXE Foundation uses this service to measure and/or verify a UEFI image. This service abstracts the invocation of Trusted Computing Group (TCG) measured boot, UEFI Secure boot, and UEFI User Identity infrastructure. For the former two, the DXE Foundation invokes the FileAuthentication() with a DevicePath and corresponding image in FileBuffer memory. The TCG measurement code will record the FileBuffer contents into the appropriate PCR. The image verification logic will confirm the integrity and provenance of the image in FileBuffer of length FileSize . The origin of the image will be DevicePath in these cases. If the FileBuffer is NULL, the interface will determine if the DevicePath can be connected in order to support the User Identification policy. @param This The EFI_SECURITY2_ARCH_PROTOCOL instance. @param File A pointer to the device path of the file that is being dispatched. This will optionally be used for logging. @param FileBuffer A pointer to the buffer with the UEFI file image. @param FileSize The size of the file. @param BootPolicy A boot policy that was used to call LoadImage() UEFI service. If FileAuthentication() is invoked not from the LoadImage(), BootPolicy must be set to FALSE. @retval EFI_SUCCESS The file specified by DevicePath and non-NULL FileBuffer did authenticate, and the platform policy dictates that the DXE Foundation may use the file. @retval EFI_SUCCESS The device path specified by NULL device path DevicePath and non-NULL FileBuffer did authenticate, and the platform policy dictates that the DXE Foundation may execute the image in FileBuffer. @retval EFI_SUCCESS FileBuffer is NULL and current user has permission to start UEFI device drivers on the device path specified by DevicePath. @retval EFI_SECURITY_VIOLATION The file specified by DevicePath and FileBuffer did not authenticate, and the platform policy dictates that the file should be placed in the untrusted state. The image has been added to the file execution table. @retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not authenticate, and the platform policy dictates that the DXE Foundation may not use File. @retval EFI_SECURITY_VIOLATION FileBuffer is NULL and the user has no permission to start UEFI device drivers on the device path specified by DevicePath. @retval EFI_SECURITY_VIOLATION FileBuffer is not NULL and the user has no permission to load drivers from the device path specified by DevicePath. The image has been added into the list of the deferred images. **/ typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION)( IN CONST EFI_SECURITY2_ARCH_PROTOCOL *This, IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL, IN VOID *FileBuffer, IN UINTN FileSize, IN BOOLEAN BootPolicy ); /// /// The EFI_SECURITY2_ARCH_PROTOCOL is used to abstract platform-specific policy from the /// DXE Foundation. This includes measuring the PE/COFF image prior to invoking, comparing the /// image against a policy (whether a white-list/black-list of public image verification keys /// or registered hashes). /// struct _EFI_SECURITY2_ARCH_PROTOCOL { EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication; }; extern EFI_GUID gEfiSecurity2ArchProtocolGuid; #endif /** @file Security Policy protocol as defined in PI Specification VOLUME 2 DXE Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _SECURITY_POLICY_H_ #define _SECURITY_POLICY_H_ /// /// Security policy protocol GUID definition /// #define EFI_SECURITY_POLICY_PROTOCOL_GUID \ {0x78E4D245, 0xCD4D, 0x4a05, {0xA2, 0xBA, 0x47, 0x43, 0xE8, 0x6C, 0xFC, 0xAB} } extern EFI_GUID gEfiSecurityPolicyProtocolGuid; #endif /** @file Serial IO protocol as defined in the UEFI 2.0 specification. Abstraction of a basic serial device. Targeted at 16550 UART, but could be much more generic. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SERIAL_IO_PROTOCOL_H__ #define __SERIAL_IO_PROTOCOL_H__ #define EFI_SERIAL_IO_PROTOCOL_GUID \ { \ 0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } \ } #define EFI_SERIAL_TERMINAL_DEVICE_TYPE_GUID \ { \ 0X6AD9A60F, 0X5815, 0X4C7C, { 0X8A, 0X10, 0X50, 0X53, 0XD2, 0XBF, 0X7A, 0X1B } \ } /// /// Protocol GUID defined in EFI1.1. /// #define SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL_GUID typedef struct _EFI_SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL; /// /// Backward-compatible with EFI1.1. /// typedef EFI_SERIAL_IO_PROTOCOL SERIAL_IO_INTERFACE; /// /// Parity type that is computed or checked as each character is transmitted or received. If the /// device does not support parity, the value is the default parity value. /// typedef enum { DefaultParity, NoParity, EvenParity, OddParity, MarkParity, SpaceParity } EFI_PARITY_TYPE; /// /// Stop bits type /// typedef enum { DefaultStopBits, OneStopBit, OneFiveStopBits, TwoStopBits } EFI_STOP_BITS_TYPE; // // define for Control bits, grouped by read only, write only, and read write // // // Read Only // #define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 #define EFI_SERIAL_DATA_SET_READY 0x00000020 #define EFI_SERIAL_RING_INDICATE 0x00000040 #define EFI_SERIAL_CARRIER_DETECT 0x00000080 #define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 #define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 // // Write Only // #define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 #define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 // // Read Write // #define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 #define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 #define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 // // Serial IO Member Functions // /** Reset the serial device. @param This Protocol instance pointer. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The serial device could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_RESET)( IN EFI_SERIAL_IO_PROTOCOL *This ); /** Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, data bits, and stop bits on a serial device. @param This Protocol instance pointer. @param BaudRate The requested baud rate. A BaudRate value of 0 will use the device's default interface speed. @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the serial interface. A ReceiveFifoDepth value of 0 will use the device's default FIFO depth. @param Timeout The requested time out for a single character in microseconds. This timeout applies to both the transmit and receive side of the interface. A Timeout value of 0 will use the device's default time out value. @param Parity The type of parity to use on this serial device. A Parity value of DefaultParity will use the device's default parity value. @param DataBits The number of data bits to use on the serial device. A DataBits vaule of 0 will use the device's default data bit setting. @param StopBits The number of stop bits to use on this serial device. A StopBits value of DefaultStopBits will use the device's default number of stop bits. @retval EFI_SUCCESS The device was reset. @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value. @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_SET_ATTRIBUTES)( IN EFI_SERIAL_IO_PROTOCOL *This, IN UINT64 BaudRate, IN UINT32 ReceiveFifoDepth, IN UINT32 Timeout, IN EFI_PARITY_TYPE Parity, IN UINT8 DataBits, IN EFI_STOP_BITS_TYPE StopBits ); /** Set the control bits on a serial device @param This Protocol instance pointer. @param Control Set the bits of Control that are settable. @retval EFI_SUCCESS The new control bits were set on the serial device. @retval EFI_UNSUPPORTED The serial device does not support this operation. @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_SET_CONTROL_BITS)( IN EFI_SERIAL_IO_PROTOCOL *This, IN UINT32 Control ); /** Retrieves the status of thecontrol bits on a serial device @param This Protocol instance pointer. @param Control A pointer to return the current Control signals from the serial device. @retval EFI_SUCCESS The control bits were read from the serial device. @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_GET_CONTROL_BITS)( IN EFI_SERIAL_IO_PROTOCOL *This, OUT UINT32 *Control ); /** Writes data to a serial device. @param This Protocol instance pointer. @param BufferSize On input, the size of the Buffer. On output, the amount of data actually written. @param Buffer The buffer of data to write @retval EFI_SUCCESS The data was written. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The data write was stopped due to a timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_WRITE)( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer ); /** Writes data to a serial device. @param This Protocol instance pointer. @param BufferSize On input, the size of the Buffer. On output, the amount of data returned in Buffer. @param Buffer The buffer to return the data into. @retval EFI_SUCCESS The data was read. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_TIMEOUT The data write was stopped due to a timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_SERIAL_READ)( IN EFI_SERIAL_IO_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ); /** @par Data Structure Description: The data values in SERIAL_IO_MODE are read-only and are updated by the code that produces the SERIAL_IO_PROTOCOL member functions. @param ControlMask A mask for the Control bits that the device supports. The device must always support the Input Buffer Empty control bit. @param TimeOut If applicable, the number of microseconds to wait before timing out a Read or Write operation. @param BaudRate If applicable, the current baud rate setting of the device; otherwise, baud rate has the value of zero to indicate that device runs at the device's designed speed. @param ReceiveFifoDepth The number of characters the device will buffer on input @param DataBits The number of characters the device will buffer on input @param Parity If applicable, this is the EFI_PARITY_TYPE that is computed or checked as each character is transmitted or reveived. If the device does not support parity the value is the default parity value. @param StopBits If applicable, the EFI_STOP_BITS_TYPE number of stop bits per character. If the device does not support stop bits the value is the default stop bit values. **/ typedef struct { UINT32 ControlMask; // // current Attributes // UINT32 Timeout; UINT64 BaudRate; UINT32 ReceiveFifoDepth; UINT32 DataBits; UINT32 Parity; UINT32 StopBits; } EFI_SERIAL_IO_MODE; #define EFI_SERIAL_IO_PROTOCOL_REVISION 0x00010000 #define EFI_SERIAL_IO_PROTOCOL_REVISION1p1 0x00010001 #define SERIAL_IO_INTERFACE_REVISION EFI_SERIAL_IO_PROTOCOL_REVISION /// /// The Serial I/O protocol is used to communicate with UART-style serial devices. /// These can be standard UART serial ports in PC-AT systems, serial ports attached /// to a USB interface, or potentially any character-based I/O device. /// struct _EFI_SERIAL_IO_PROTOCOL { /// /// The revision to which the EFI_SERIAL_IO_PROTOCOL adheres. All future revisions /// must be backwards compatible. If a future version is not backwards compatible, /// it is not the same GUID. /// UINT32 Revision; EFI_SERIAL_RESET Reset; EFI_SERIAL_SET_ATTRIBUTES SetAttributes; EFI_SERIAL_SET_CONTROL_BITS SetControl; EFI_SERIAL_GET_CONTROL_BITS GetControl; EFI_SERIAL_WRITE Write; EFI_SERIAL_READ Read; /// /// Pointer to SERIAL_IO_MODE data. /// EFI_SERIAL_IO_MODE *Mode; /// /// Pointer to a GUID identifying the device connected to the serial port. /// This field is NULL when the protocol is installed by the serial port /// driver and may be populated by a platform driver for a serial port /// with a known device attached. The field will remain NULL if there is /// no platform serial device identification information available. /// CONST EFI_GUID *DeviceTypeGuid; // Revision 1.1 }; extern EFI_GUID gEfiSerialIoProtocolGuid; extern EFI_GUID gEfiSerialTerminalDeviceTypeGuid; #endif /** @file SimpleFileSystem protocol as defined in the UEFI 2.0 specification. The SimpleFileSystem protocol is the programmatic access to the FAT (12,16,32) file system specified in UEFI 2.0. It can also be used to abstract a file system other than FAT. UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SIMPLE_FILE_SYSTEM_H__ #define __SIMPLE_FILE_SYSTEM_H__ #define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ { \ 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL; typedef struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL; typedef struct _EFI_FILE_PROTOCOL *EFI_FILE_HANDLE; /// /// Protocol GUID name defined in EFI1.1. /// #define SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID /// /// Protocol name defined in EFI1.1. /// typedef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_FILE_IO_INTERFACE; typedef EFI_FILE_PROTOCOL EFI_FILE; /** Open the root directory on a volume. @param This A pointer to the volume to open the root directory. @param Root A pointer to the location to return the opened file handle for the root directory. @retval EFI_SUCCESS The device was opened. @retval EFI_UNSUPPORTED This volume does not support the requested file system type. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_ACCESS_DENIED The service denied access to the file. @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no longer supported. Any existing file handles for this volume are no longer valid. To access the files on the new medium, the volume must be reopened with OpenVolume(). **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **Root ); #define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 /// /// Revision defined in EFI1.1 /// #define EFI_FILE_IO_INTERFACE_REVISION EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { /// /// The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. The version /// specified by this specification is 0x00010000. All future revisions /// must be backwards compatible. /// UINT64 Revision; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume; }; /** Opens a new file relative to the source file's location. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to the source location. This would typically be an open handle to a directory. @param NewHandle A pointer to the location to return the opened handle for the new file. @param FileName The Null-terminated string of the name of the file to be opened. The file name may contain the following path modifiers: "\", ".", and "..". @param OpenMode The mode to open the file. The only valid combinations that the file may be opened with are: Read, Read/Write, or Create/Read/Write. @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the attribute bits for the newly created file. @retval EFI_SUCCESS The file was opened. @retval EFI_NOT_FOUND The specified file could not be found on the device. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no longer supported. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write when the media is write-protected. @retval EFI_ACCESS_DENIED The service denied access to the file. @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. @retval EFI_VOLUME_FULL The volume is full. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_OPEN)( IN EFI_FILE_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes ); // // Open modes // #define EFI_FILE_MODE_READ 0x0000000000000001ULL #define EFI_FILE_MODE_WRITE 0x0000000000000002ULL #define EFI_FILE_MODE_CREATE 0x8000000000000000ULL // // File attributes // #define EFI_FILE_READ_ONLY 0x0000000000000001ULL #define EFI_FILE_HIDDEN 0x0000000000000002ULL #define EFI_FILE_SYSTEM 0x0000000000000004ULL #define EFI_FILE_RESERVED 0x0000000000000008ULL #define EFI_FILE_DIRECTORY 0x0000000000000010ULL #define EFI_FILE_ARCHIVE 0x0000000000000020ULL #define EFI_FILE_VALID_ATTR 0x0000000000000037ULL /** Closes a specified file handle. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to close. @retval EFI_SUCCESS The file was closed. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_CLOSE)( IN EFI_FILE_PROTOCOL *This ); /** Close and delete the file handle. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the handle to the file to delete. @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_DELETE)( IN EFI_FILE_PROTOCOL *This ); /** Reads data from a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to read data from. @param BufferSize On input, the size of the Buffer. On output, the amount of data returned in Buffer. In both cases, the size is measured in bytes. @param Buffer The buffer into which the data is read. @retval EFI_SUCCESS Data was read. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. BufferSize has been updated with the size needed to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_READ)( IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ); /** Writes data to a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to write data to. @param BufferSize On input, the size of the Buffer. On output, the amount of data actually written. In both cases, the size is measured in bytes. @param Buffer The buffer of data to write. @retval EFI_SUCCESS Data was written. @retval EFI_UNSUPPORTED Writes to open directory files are not supported. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED The file or medium is write-protected. @retval EFI_ACCESS_DENIED The file was opened read only. @retval EFI_VOLUME_FULL The volume is full. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_WRITE)( IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer ); /** Sets a file's current position. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to set the requested position on. @param Position The byte position from the start of the file to set. @retval EFI_SUCCESS The position was set. @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open directories. @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_SET_POSITION)( IN EFI_FILE_PROTOCOL *This, IN UINT64 Position ); /** Returns a file's current position. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to get the current position on. @param Position The address to return the file's current position value. @retval EFI_SUCCESS The position was returned. @retval EFI_UNSUPPORTED The request is not valid on open directories. @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_GET_POSITION)( IN EFI_FILE_PROTOCOL *This, OUT UINT64 *Position ); /** Returns information about a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle the requested information is for. @param InformationType The type identifier for the information being requested. @param BufferSize On input, the size of Buffer. On output, the amount of data returned in Buffer. In both cases, the size is measured in bytes. @param Buffer A pointer to the data buffer to return. The buffer's type is indicated by InformationType. @retval EFI_SUCCESS The information was returned. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. BufferSize has been updated with the size needed to complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_GET_INFO)( IN EFI_FILE_PROTOCOL *This, IN EFI_GUID *InformationType, IN OUT UINTN *BufferSize, OUT VOID *Buffer ); /** Sets information about a file. @param File A pointer to the EFI_FILE_PROTOCOL instance that is the file handle the information is for. @param InformationType The type identifier for the information being set. @param BufferSize The size, in bytes, of Buffer. @param Buffer A pointer to the data buffer to write. The buffer's type is indicated by InformationType. @retval EFI_SUCCESS The information was set. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is read-only. @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media is read only. @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media is read-only. @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a file that is already present. @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY Attribute. @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory. @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened read-only and an attempt is being made to modify a field other than Attribute. @retval EFI_VOLUME_FULL The volume is full. @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated by InformationType. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_SET_INFO)( IN EFI_FILE_PROTOCOL *This, IN EFI_GUID *InformationType, IN UINTN BufferSize, IN VOID *Buffer ); /** Flushes all modified data associated with a file to a device. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to flush. @retval EFI_SUCCESS The data was flushed. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED The file or medium is write-protected. @retval EFI_ACCESS_DENIED The file was opened read-only. @retval EFI_VOLUME_FULL The volume is full. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_FLUSH)( IN EFI_FILE_PROTOCOL *This ); typedef struct { // // If Event is NULL, then blocking I/O is performed. // If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed, // and Event will be signaled when the read request is completed. // The caller must be prepared to handle the case where the callback associated with Event // occurs before the original asynchronous I/O request call returns. // EFI_EVENT Event; // // Defines whether or not the signaled event encountered an error. // EFI_STATUS Status; // // For OpenEx(): Not Used, ignored. // For ReadEx(): On input, the size of the Buffer. On output, the amount of data returned in Buffer. // In both cases, the size is measured in bytes. // For WriteEx(): On input, the size of the Buffer. On output, the amount of data actually written. // In both cases, the size is measured in bytes. // For FlushEx(): Not used, ignored. // UINTN BufferSize; // // For OpenEx(): Not Used, ignored. // For ReadEx(): The buffer into which the data is read. // For WriteEx(): The buffer of data to write. // For FlushEx(): Not Used, ignored. // VOID *Buffer; } EFI_FILE_IO_TOKEN; /** Opens a new file relative to the source directory's location. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to the source location. @param NewHandle A pointer to the location to return the opened handle for the new file. @param FileName The Null-terminated string of the name of the file to be opened. The file name may contain the following path modifiers: "\", ".", and "..". @param OpenMode The mode to open the file. The only valid combinations that the file may be opened with are: Read, Read/Write, or Create/Read/Write. @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the attribute bits for the newly created file. @param Token A pointer to the token associated with the transaction. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. @retval EFI_NOT_FOUND The specified file could not be found on the device. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no longer supported. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write when the media is write-protected. @retval EFI_ACCESS_DENIED The service denied access to the file. @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. @retval EFI_VOLUME_FULL The volume is full. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_OPEN_EX)( IN EFI_FILE_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes, IN OUT EFI_FILE_IO_TOKEN *Token ); /** Reads data from a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to read data from. @param Token A pointer to the token associated with the transaction. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_READ_EX)( IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token ); /** Writes data to a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to write data to. @param Token A pointer to the token associated with the transaction. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. @retval EFI_UNSUPPORTED Writes to open directory files are not supported. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED The file or medium is write-protected. @retval EFI_ACCESS_DENIED The file was opened read only. @retval EFI_VOLUME_FULL The volume is full. @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_WRITE_EX)( IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token ); /** Flushes all modified data associated with a file to a device. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to flush. @param Token A pointer to the token associated with the transaction. @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. If Event is not NULL (asynchronous I/O): The request was successfully queued for processing. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_WRITE_PROTECTED The file or medium is write-protected. @retval EFI_ACCESS_DENIED The file was opened read-only. @retval EFI_VOLUME_FULL The volume is full. @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_FLUSH_EX)( IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token ); #define EFI_FILE_PROTOCOL_REVISION 0x00010000 #define EFI_FILE_PROTOCOL_REVISION2 0x00020000 #define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 // // Revision defined in EFI1.1. // #define EFI_FILE_REVISION EFI_FILE_PROTOCOL_REVISION /// /// The EFI_FILE_PROTOCOL provides file IO access to supported file systems. /// An EFI_FILE_PROTOCOL provides access to a file's or directory's contents, /// and is also a reference to a location in the directory tree of the file system /// in which the file resides. With any given file handle, other files may be opened /// relative to this file's location, yielding new file handles. /// struct _EFI_FILE_PROTOCOL { /// /// The version of the EFI_FILE_PROTOCOL interface. The version specified /// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION. /// Future versions are required to be backward compatible to version 1.0. /// UINT64 Revision; EFI_FILE_OPEN Open; EFI_FILE_CLOSE Close; EFI_FILE_DELETE Delete; EFI_FILE_READ Read; EFI_FILE_WRITE Write; EFI_FILE_GET_POSITION GetPosition; EFI_FILE_SET_POSITION SetPosition; EFI_FILE_GET_INFO GetInfo; EFI_FILE_SET_INFO SetInfo; EFI_FILE_FLUSH Flush; EFI_FILE_OPEN_EX OpenEx; EFI_FILE_READ_EX ReadEx; EFI_FILE_WRITE_EX WriteEx; EFI_FILE_FLUSH_EX FlushEx; }; extern EFI_GUID gEfiSimpleFileSystemProtocolGuid; #endif /** @file The EFI_SIMPLE_NETWORK_PROTOCOL provides services to initialize a network interface, transmit packets, receive packets, and close a network interface. Basic network device abstraction. Rx - Received Tx - Transmit MCast - MultiCast ... Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in EFI Specification 1.10. **/ #ifndef __SIMPLE_NETWORK_H__ #define __SIMPLE_NETWORK_H__ #define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ { \ 0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } \ } typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL; /// /// Protocol defined in EFI1.1. /// typedef EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK; /// /// Simple Network Protocol data structures. /// typedef struct { /// /// Total number of frames received. Includes frames with errors and /// dropped frames. /// UINT64 RxTotalFrames; /// /// Number of valid frames received and copied into receive buffers. /// UINT64 RxGoodFrames; /// /// Number of frames below the minimum length for the media. /// This would be <64 for ethernet. /// UINT64 RxUndersizeFrames; /// /// Number of frames longer than the maxminum length for the /// media. This would be >1500 for ethernet. /// UINT64 RxOversizeFrames; /// /// Valid frames that were dropped because receive buffers were full. /// UINT64 RxDroppedFrames; /// /// Number of valid unicast frames received and not dropped. /// UINT64 RxUnicastFrames; /// /// Number of valid broadcast frames received and not dropped. /// UINT64 RxBroadcastFrames; /// /// Number of valid mutlicast frames received and not dropped. /// UINT64 RxMulticastFrames; /// /// Number of frames w/ CRC or alignment errors. /// UINT64 RxCrcErrorFrames; /// /// Total number of bytes received. Includes frames with errors /// and dropped frames. // UINT64 RxTotalBytes; /// /// Transmit statistics. /// UINT64 TxTotalFrames; UINT64 TxGoodFrames; UINT64 TxUndersizeFrames; UINT64 TxOversizeFrames; UINT64 TxDroppedFrames; UINT64 TxUnicastFrames; UINT64 TxBroadcastFrames; UINT64 TxMulticastFrames; UINT64 TxCrcErrorFrames; UINT64 TxTotalBytes; /// /// Number of collisions detection on this subnet. /// UINT64 Collisions; /// /// Number of frames destined for unsupported protocol. /// UINT64 UnsupportedProtocol; /// /// Number of valid frames received that were duplicated. /// UINT64 RxDuplicatedFrames; /// /// Number of encrypted frames received that failed to decrypt. /// UINT64 RxDecryptErrorFrames; /// /// Number of frames that failed to transmit after exceeding the retry limit. /// UINT64 TxErrorFrames; /// /// Number of frames transmitted successfully after more than one attempt. /// UINT64 TxRetryFrames; } EFI_NETWORK_STATISTICS; /// /// The state of the network interface. /// When an EFI_SIMPLE_NETWORK_PROTOCOL driver initializes a /// network interface, the network interface is left in the EfiSimpleNetworkStopped state. /// typedef enum { EfiSimpleNetworkStopped, EfiSimpleNetworkStarted, EfiSimpleNetworkInitialized, EfiSimpleNetworkMaxState } EFI_SIMPLE_NETWORK_STATE; #define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 #define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 #define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 #define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 #define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 #define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 #define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 #define MAX_MCAST_FILTER_CNT 16 typedef struct { /// /// Reports the current state of the network interface. /// UINT32 State; /// /// The size, in bytes, of the network interface's HW address. /// UINT32 HwAddressSize; /// /// The size, in bytes, of the network interface's media header. /// UINT32 MediaHeaderSize; /// /// The maximum size, in bytes, of the packets supported by the network interface. /// UINT32 MaxPacketSize; /// /// The size, in bytes, of the NVRAM device attached to the network interface. /// UINT32 NvRamSize; /// /// The size that must be used for all NVRAM reads and writes. The /// start address for NVRAM read and write operations and the total /// length of those operations, must be a multiple of this value. The /// legal values for this field are 0, 1, 2, 4, and 8. /// UINT32 NvRamAccessSize; /// /// The multicast receive filter settings supported by the network interface. /// UINT32 ReceiveFilterMask; /// /// The current multicast receive filter settings. /// UINT32 ReceiveFilterSetting; /// /// The maximum number of multicast address receive filters supported by the driver. /// UINT32 MaxMCastFilterCount; /// /// The current number of multicast address receive filters. /// UINT32 MCastFilterCount; /// /// Array containing the addresses of the current multicast address receive filters. /// EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]; /// /// The current HW MAC address for the network interface. /// EFI_MAC_ADDRESS CurrentAddress; /// /// The current HW MAC address for broadcast packets. /// EFI_MAC_ADDRESS BroadcastAddress; /// /// The permanent HW MAC address for the network interface. /// EFI_MAC_ADDRESS PermanentAddress; /// /// The interface type of the network interface. /// UINT8 IfType; /// /// TRUE if the HW MAC address can be changed. /// BOOLEAN MacAddressChangeable; /// /// TRUE if the network interface can transmit more than one packet at a time. /// BOOLEAN MultipleTxSupported; /// /// TRUE if the presence of media can be determined; otherwise FALSE. /// BOOLEAN MediaPresentSupported; /// /// TRUE if media are connected to the network interface; otherwise FALSE. /// BOOLEAN MediaPresent; } EFI_SIMPLE_NETWORK_MODE; // // Protocol Member Functions // /** Changes the state of a network interface from "stopped" to "started". @param This Protocol instance pointer. @retval EFI_SUCCESS The network interface was started. @retval EFI_ALREADY_STARTED The network interface is already in the started state. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_START)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ); /** Changes the state of a network interface from "started" to "stopped". @param This Protocol instance pointer. @retval EFI_SUCCESS The network interface was stopped. @retval EFI_ALREADY_STARTED The network interface is already in the stopped state. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STOP)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ); /** Resets a network adapter and allocates the transmit and receive buffers required by the network interface; optionally, also requests allocation of additional transmit and receive buffers. @param This The protocol instance pointer. @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space that the driver should allocate for the network interface. Some network interfaces will not be able to use the extra buffer, and the caller will not know if it is actually being used. @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space that the driver should allocate for the network interface. Some network interfaces will not be able to use the extra buffer, and the caller will not know if it is actually being used. @retval EFI_SUCCESS The network interface was initialized. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINTN ExtraRxBufferSize OPTIONAL, IN UINTN ExtraTxBufferSize OPTIONAL ); /** Resets a network adapter and re-initializes it with the parameters that were provided in the previous call to Initialize(). @param This The protocol instance pointer. @param ExtendedVerification Indicates that the driver may perform a more exhaustive verification operation of the device during reset. @retval EFI_SUCCESS The network interface was reset. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RESET)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Resets a network adapter and leaves it in a state that is safe for another driver to initialize. @param This Protocol instance pointer. @retval EFI_SUCCESS The network interface was shutdown. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ); /** Manages the multicast receive filters of a network interface. @param This The protocol instance pointer. @param Enable A bit mask of receive filters to enable on the network interface. @param Disable A bit mask of receive filters to disable on the network interface. @param ResetMCastFilter Set to TRUE to reset the contents of the multicast receive filters on the network interface to their default values. @param McastFilterCnt Number of multicast HW MAC addresses in the new MCastFilter list. This value must be less than or equal to the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This field is optional if ResetMCastFilter is TRUE. @param MCastFilter A pointer to a list of new multicast receive filter HW MAC addresses. This list will replace any existing multicast HW MAC address list. This field is optional if ResetMCastFilter is TRUE. @retval EFI_SUCCESS The multicast receive filter list was updated. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINT32 Enable, IN UINT32 Disable, IN BOOLEAN ResetMCastFilter, IN UINTN MCastFilterCnt OPTIONAL, IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL ); /** Modifies or resets the current station address, if supported. @param This The protocol instance pointer. @param Reset Flag used to reset the station address to the network interfaces permanent address. @param New The new station address to be used for the network interface. @retval EFI_SUCCESS The network interfaces station address was updated. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN BOOLEAN Reset, IN EFI_MAC_ADDRESS *New OPTIONAL ); /** Resets or collects the statistics on a network interface. @param This Protocol instance pointer. @param Reset Set to TRUE to reset the statistics for the network interface. @param StatisticsSize On input the size, in bytes, of StatisticsTable. On output the size, in bytes, of the resulting table of statistics. @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that contains the statistics. @retval EFI_SUCCESS The statistics were collected from the network interface. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer size needed to hold the statistics is returned in StatisticsSize. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN BOOLEAN Reset, IN OUT UINTN *StatisticsSize OPTIONAL, OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL ); /** Converts a multicast IP address to a multicast HW MAC address. @param This The protocol instance pointer. @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set to FALSE if the multicast IP address is IPv4 [RFC 791]. @param IP The multicast IP address that is to be converted to a multicast HW MAC address. @param MAC The multicast HW MAC address that is to be generated from IP. @retval EFI_SUCCESS The multicast IP address was mapped to the multicast HW MAC address. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer size needed to hold the statistics is returned in StatisticsSize. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN BOOLEAN IPv6, IN EFI_IP_ADDRESS *IP, OUT EFI_MAC_ADDRESS *MAC ); /** Performs read and write operations on the NVRAM device attached to a network interface. @param This The protocol instance pointer. @param ReadWrite TRUE for read operations, FALSE for write operations. @param Offset Byte offset in the NVRAM device at which to start the read or write operation. This must be a multiple of NvRamAccessSize and less than NvRamSize. @param BufferSize The number of bytes to read or write from the NVRAM device. This must also be a multiple of NvramAccessSize. @param Buffer A pointer to the data buffer. @retval EFI_SUCCESS The NVRAM access was performed. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_NVDATA)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN BOOLEAN ReadWrite, IN UINTN Offset, IN UINTN BufferSize, IN OUT VOID *Buffer ); /** Reads the current interrupt status and recycled transmit buffer status from a network interface. @param This The protocol instance pointer. @param InterruptStatus A pointer to the bit mask of the currently active interrupts If this is NULL, the interrupt status will not be read from the device. If this is not NULL, the interrupt status will be read from the device. When the interrupt status is read, it will also be cleared. Clearing the transmit interrupt does not empty the recycled transmit buffer array. @param TxBuf Recycled transmit buffer address. The network interface will not transmit if its internal recycled transmit buffer array is full. Reading the transmit buffer does not clear the transmit interrupt. If this is NULL, then the transmit buffer status will not be read. If there are no transmit buffers to recycle and TxBuf is not NULL, * TxBuf will be set to NULL. @retval EFI_SUCCESS The status of the network interface was retrieved. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, OUT UINT32 *InterruptStatus OPTIONAL, OUT VOID **TxBuf OPTIONAL ); /** Places a packet in the transmit queue of a network interface. @param This The protocol instance pointer. @param HeaderSize The size, in bytes, of the media header to be filled in by the Transmit() function. If HeaderSize is non-zero, then it must be equal to This->Mode->MediaHeaderSize and the DestAddr and Protocol parameters must not be NULL. @param BufferSize The size, in bytes, of the entire packet (media header and data) to be transmitted through the network interface. @param Buffer A pointer to the packet (media header followed by data) to be transmitted. This parameter cannot be NULL. If HeaderSize is zero, then the media header in Buffer must already be filled in by the caller. If HeaderSize is non-zero, then the media header will be filled in by the Transmit() function. @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then This->Mode->CurrentAddress is used for the source HW MAC address. @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this parameter is ignored. @param Protocol The type of header to build. If HeaderSize is zero, then this parameter is ignored. See RFC 1700, section "Ether Types", for examples. @retval EFI_SUCCESS The packet was placed on the transmit queue. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_NOT_READY The network interface is too busy to accept this transmit request. @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINTN HeaderSize, IN UINTN BufferSize, IN VOID *Buffer, IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, IN UINT16 *Protocol OPTIONAL ); /** Receives a packet from a network interface. @param This The protocol instance pointer. @param HeaderSize The size, in bytes, of the media header received on the network interface. If this parameter is NULL, then the media header size will not be returned. @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in bytes, of the packet that was received on the network interface. @param Buffer A pointer to the data buffer to receive both the media header and the data. @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW MAC source address will not be extracted from the media header. @param DestAddr The destination HW MAC address. If this parameter is NULL, the HW MAC destination address will not be extracted from the media header. @param Protocol The media header type. If this parameter is NULL, then the protocol will not be extracted from the media header. See RFC 1700 section "Ether Types" for examples. @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has been updated to the number of bytes received. @retval EFI_NOT_STARTED The network interface has not been started. @retval EFI_NOT_READY The network interface is too busy to accept this transmit request. @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. @retval EFI_UNSUPPORTED This function is not supported by the network interface. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE)( IN EFI_SIMPLE_NETWORK_PROTOCOL *This, OUT UINTN *HeaderSize OPTIONAL, IN OUT UINTN *BufferSize, OUT VOID *Buffer, OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, OUT UINT16 *Protocol OPTIONAL ); #define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 // // Revision defined in EFI1.1 // #define EFI_SIMPLE_NETWORK_INTERFACE_REVISION EFI_SIMPLE_NETWORK_PROTOCOL_REVISION /// /// The EFI_SIMPLE_NETWORK_PROTOCOL protocol is used to initialize access /// to a network adapter. Once the network adapter initializes, /// the EFI_SIMPLE_NETWORK_PROTOCOL protocol provides services that /// allow packets to be transmitted and received. /// struct _EFI_SIMPLE_NETWORK_PROTOCOL { /// /// Revision of the EFI_SIMPLE_NETWORK_PROTOCOL. All future revisions must /// be backwards compatible. If a future version is not backwards compatible /// it is not the same GUID. /// UINT64 Revision; EFI_SIMPLE_NETWORK_START Start; EFI_SIMPLE_NETWORK_STOP Stop; EFI_SIMPLE_NETWORK_INITIALIZE Initialize; EFI_SIMPLE_NETWORK_RESET Reset; EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters; EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress; EFI_SIMPLE_NETWORK_STATISTICS Statistics; EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac; EFI_SIMPLE_NETWORK_NVDATA NvData; EFI_SIMPLE_NETWORK_GET_STATUS GetStatus; EFI_SIMPLE_NETWORK_TRANSMIT Transmit; EFI_SIMPLE_NETWORK_RECEIVE Receive; /// /// Event used with WaitForEvent() to wait for a packet to be received. /// EFI_EVENT WaitForPacket; /// /// Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device. /// EFI_SIMPLE_NETWORK_MODE *Mode; }; extern EFI_GUID gEfiSimpleNetworkProtocolGuid; #endif /** @file Simple Pointer protocol from the UEFI 2.0 specification. Abstraction of a very simple pointer device like a mouse or trackball. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SIMPLE_POINTER_H__ #define __SIMPLE_POINTER_H__ #define EFI_SIMPLE_POINTER_PROTOCOL_GUID \ { \ 0x31878c87, 0xb75, 0x11d5, {0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } typedef struct _EFI_SIMPLE_POINTER_PROTOCOL EFI_SIMPLE_POINTER_PROTOCOL; // // Data structures // typedef struct { /// /// The signed distance in counts that the pointer device has been moved along the x-axis. /// INT32 RelativeMovementX; /// /// The signed distance in counts that the pointer device has been moved along the y-axis. /// INT32 RelativeMovementY; /// /// The signed distance in counts that the pointer device has been moved along the z-axis. /// INT32 RelativeMovementZ; /// /// If TRUE, then the left button of the pointer device is being /// pressed. If FALSE, then the left button of the pointer device is not being pressed. /// BOOLEAN LeftButton; /// /// If TRUE, then the right button of the pointer device is being /// pressed. If FALSE, then the right button of the pointer device is not being pressed. /// BOOLEAN RightButton; } EFI_SIMPLE_POINTER_STATE; typedef struct { /// /// The resolution of the pointer device on the x-axis in counts/mm. /// If 0, then the pointer device does not support an x-axis. /// UINT64 ResolutionX; /// /// The resolution of the pointer device on the y-axis in counts/mm. /// If 0, then the pointer device does not support an x-axis. /// UINT64 ResolutionY; /// /// The resolution of the pointer device on the z-axis in counts/mm. /// If 0, then the pointer device does not support an x-axis. /// UINT64 ResolutionZ; /// /// TRUE if a left button is present on the pointer device. Otherwise FALSE. /// BOOLEAN LeftButton; /// /// TRUE if a right button is present on the pointer device. Otherwise FALSE. /// BOOLEAN RightButton; } EFI_SIMPLE_POINTER_MODE; /** Resets the pointer device hardware. @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance. @param ExtendedVerification Indicates that the driver may perform a more exhaustive verification operation of the device during reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_POINTER_RESET)( IN EFI_SIMPLE_POINTER_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Retrieves the current state of a pointer device. @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance. @param State A pointer to the state information on the pointer device. @retval EFI_SUCCESS The state of the pointer device was returned in State. @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to GetState(). @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's current state. **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_POINTER_GET_STATE)( IN EFI_SIMPLE_POINTER_PROTOCOL *This, OUT EFI_SIMPLE_POINTER_STATE *State ); /// /// The EFI_SIMPLE_POINTER_PROTOCOL provides a set of services for a pointer /// device that can use used as an input device from an application written /// to this specification. The services include the ability to reset the /// pointer device, retrieve get the state of the pointer device, and /// retrieve the capabilities of the pointer device. /// struct _EFI_SIMPLE_POINTER_PROTOCOL { EFI_SIMPLE_POINTER_RESET Reset; EFI_SIMPLE_POINTER_GET_STATE GetState; /// /// Event to use with WaitForEvent() to wait for input from the pointer device. /// EFI_EVENT WaitForInput; /// /// Pointer to EFI_SIMPLE_POINTER_MODE data. /// EFI_SIMPLE_POINTER_MODE *Mode; }; extern EFI_GUID gEfiSimplePointerProtocolGuid; #endif /** @file Simple Text Input protocol from the UEFI 2.0 specification. Abstraction of a very simple input device like a keyboard or serial terminal. Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SIMPLE_TEXT_IN_PROTOCOL_H__ #define __SIMPLE_TEXT_IN_PROTOCOL_H__ #define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ { \ 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL; /// /// Protocol GUID name defined in EFI1.1. /// #define SIMPLE_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID /// /// Protocol name in EFI1.1 for backward-compatible. /// typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL SIMPLE_INPUT_INTERFACE; /// /// The keystroke information for the key that was pressed. /// typedef struct { UINT16 ScanCode; CHAR16 UnicodeChar; } EFI_INPUT_KEY; // // Required unicode control chars // #define CHAR_BACKSPACE 0x0008 #define CHAR_TAB 0x0009 #define CHAR_LINEFEED 0x000A #define CHAR_CARRIAGE_RETURN 0x000D // // EFI Scan codes // #define SCAN_NULL 0x0000 #define SCAN_UP 0x0001 #define SCAN_DOWN 0x0002 #define SCAN_RIGHT 0x0003 #define SCAN_LEFT 0x0004 #define SCAN_HOME 0x0005 #define SCAN_END 0x0006 #define SCAN_INSERT 0x0007 #define SCAN_DELETE 0x0008 #define SCAN_PAGE_UP 0x0009 #define SCAN_PAGE_DOWN 0x000A #define SCAN_F1 0x000B #define SCAN_F2 0x000C #define SCAN_F3 0x000D #define SCAN_F4 0x000E #define SCAN_F5 0x000F #define SCAN_F6 0x0010 #define SCAN_F7 0x0011 #define SCAN_F8 0x0012 #define SCAN_F9 0x0013 #define SCAN_F10 0x0014 #define SCAN_ESC 0x0017 /** Reset the input device and optionally run diagnostics @param This Protocol instance pointer. @param ExtendedVerification Driver may perform diagnostics on reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_INPUT_RESET)( IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Reads the next keystroke from the input device. The WaitForKey Event can be used to test for existence of a keystroke via WaitForEvent () call. @param This Protocol instance pointer. @param Key A pointer to a buffer that is filled in with the keystroke information for the key that was pressed. @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data available. @retval EFI_DEVICE_ERROR The keystroke information was not returned due to hardware errors. **/ typedef EFI_STATUS (EFIAPI *EFI_INPUT_READ_KEY)( IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key ); /// /// The EFI_SIMPLE_TEXT_INPUT_PROTOCOL is used on the ConsoleIn device. /// It is the minimum required protocol for ConsoleIn. /// struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL { EFI_INPUT_RESET Reset; EFI_INPUT_READ_KEY ReadKeyStroke; /// /// Event to use with WaitForEvent() to wait for a key to be available /// EFI_EVENT WaitForKey; }; extern EFI_GUID gEfiSimpleTextInProtocolGuid; #endif /** @file Simple Text Input Ex protocol from the UEFI 2.0 specification. This protocol defines an extension to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL which exposes much more state and modifier information from the input device, also allows one to register a notification for a particular keystroke. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SIMPLE_TEXT_IN_EX_H__ #define __SIMPLE_TEXT_IN_EX_H__ #include #define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ {0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; /** The Reset() function resets the input device hardware. As part of initialization process, the firmware/device will make a quick but reasonable attempt to verify that the device is functioning. If the ExtendedVerification flag is TRUE the firmware may take an extended amount of time to verify the device is operating on reset. Otherwise the reset operation is to occur as quickly as possible. The hardware verification process is not defined by this specification and is left up to the platform firmware or driver to implement. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param ExtendedVerification Indicates that the driver may perform a more exhaustive verification operation of the device during reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_INPUT_RESET_EX)( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /// /// EFI_KEY_TOGGLE_STATE. The toggle states are defined. /// They are: EFI_TOGGLE_STATE_VALID, EFI_SCROLL_LOCK_ACTIVE /// EFI_NUM_LOCK_ACTIVE, EFI_CAPS_LOCK_ACTIVE /// typedef UINT8 EFI_KEY_TOGGLE_STATE; typedef struct _EFI_KEY_STATE { /// /// Reflects the currently pressed shift /// modifiers for the input device. The /// returned value is valid only if the high /// order bit has been set. /// UINT32 KeyShiftState; /// /// Reflects the current internal state of /// various toggled attributes. The returned /// value is valid only if the high order /// bit has been set. /// EFI_KEY_TOGGLE_STATE KeyToggleState; } EFI_KEY_STATE; typedef struct { /// /// The EFI scan code and Unicode value returned from the input device. /// EFI_INPUT_KEY Key; /// /// The current state of various toggled attributes as well as input modifier values. /// EFI_KEY_STATE KeyState; } EFI_KEY_DATA; // // Any Shift or Toggle State that is valid should have // high order bit set. // // Shift state // #define EFI_SHIFT_STATE_VALID 0x80000000 #define EFI_RIGHT_SHIFT_PRESSED 0x00000001 #define EFI_LEFT_SHIFT_PRESSED 0x00000002 #define EFI_RIGHT_CONTROL_PRESSED 0x00000004 #define EFI_LEFT_CONTROL_PRESSED 0x00000008 #define EFI_RIGHT_ALT_PRESSED 0x00000010 #define EFI_LEFT_ALT_PRESSED 0x00000020 #define EFI_RIGHT_LOGO_PRESSED 0x00000040 #define EFI_LEFT_LOGO_PRESSED 0x00000080 #define EFI_MENU_KEY_PRESSED 0x00000100 #define EFI_SYS_REQ_PRESSED 0x00000200 // // Toggle state // #define EFI_TOGGLE_STATE_VALID 0x80 #define EFI_KEY_STATE_EXPOSED 0x40 #define EFI_SCROLL_LOCK_ACTIVE 0x01 #define EFI_NUM_LOCK_ACTIVE 0x02 #define EFI_CAPS_LOCK_ACTIVE 0x04 // // EFI Scan codes // #define SCAN_F11 0x0015 #define SCAN_F12 0x0016 #define SCAN_PAUSE 0x0048 #define SCAN_F13 0x0068 #define SCAN_F14 0x0069 #define SCAN_F15 0x006A #define SCAN_F16 0x006B #define SCAN_F17 0x006C #define SCAN_F18 0x006D #define SCAN_F19 0x006E #define SCAN_F20 0x006F #define SCAN_F21 0x0070 #define SCAN_F22 0x0071 #define SCAN_F23 0x0072 #define SCAN_F24 0x0073 #define SCAN_MUTE 0x007F #define SCAN_VOLUME_UP 0x0080 #define SCAN_VOLUME_DOWN 0x0081 #define SCAN_BRIGHTNESS_UP 0x0100 #define SCAN_BRIGHTNESS_DOWN 0x0101 #define SCAN_SUSPEND 0x0102 #define SCAN_HIBERNATE 0x0103 #define SCAN_TOGGLE_DISPLAY 0x0104 #define SCAN_RECOVERY 0x0105 #define SCAN_EJECT 0x0106 /** The function reads the next keystroke from the input device. If there is no pending keystroke the function returns EFI_NOT_READY. If there is a pending keystroke, then KeyData.Key.ScanCode is the EFI scan code defined in Error! Reference source not found. The KeyData.Key.UnicodeChar is the actual printable character or is zero if the key does not represent a printable character (control key, function key, etc.). The KeyData.KeyState is shift state for the character reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode . When interpreting the data from this function, it should be noted that if a class of printable characters that are normally adjusted by shift modifiers (e.g. Shift Key + "f" key) would be presented solely as a KeyData.Key.UnicodeChar without the associated shift state. So in the previous example of a Shift Key + "f" key being pressed, the only pertinent data returned would be KeyData.Key.UnicodeChar with the value of "F". This of course would not typically be the case for non-printable characters such as the pressing of the Right Shift Key + F10 key since the corresponding returned data would be reflected both in the KeyData.KeyState.KeyShiftState and KeyData.Key.ScanCode values. UEFI drivers which implement the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return KeyData.Key and KeyData.KeyState values. These drivers must always return the most current state of KeyData.KeyState.KeyShiftState and KeyData.KeyState.KeyToggleState. It should also be noted that certain input devices may not be able to produce shift or toggle state information, and in those cases the high order bit in the respective Toggle and Shift state fields should not be active. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param KeyData A pointer to a buffer that is filled in with the keystroke state data for the key that was pressed. @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data available. @retval EFI_DEVICE_ERROR The keystroke information was not returned due to hardware errors. **/ typedef EFI_STATUS (EFIAPI *EFI_INPUT_READ_KEY_EX)( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData ); /** The SetState() function allows the input device hardware to have state settings adjusted. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to set the state for the input device. @retval EFI_SUCCESS The device state was set appropriately. @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not have the setting adjusted. @retval EFI_UNSUPPORTED The device does not support the ability to have its state set. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_STATE)( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_TOGGLE_STATE *KeyToggleState ); /// /// The function will be called when the key sequence is typed specified by KeyData. /// typedef EFI_STATUS (EFIAPI *EFI_KEY_NOTIFY_FUNCTION)( IN EFI_KEY_DATA *KeyData ); /** The RegisterKeystrokeNotify() function registers a function which will be called when a specified keystroke will occur. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param KeyData A pointer to a buffer that is filled in with the keystroke information for the key that was pressed. If KeyData.Key, KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0, then any incomplete keystroke will trigger a notification of the KeyNotificationFunction. @param KeyNotificationFunction Points to the function to be called when the key sequence is typed specified by KeyData. This notification function should be called at <=TPL_CALLBACK. @param NotifyHandle Points to the unique handle assigned to the registered notification. @retval EFI_SUCCESS Key notify was registered successfully. @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. **/ typedef EFI_STATUS (EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY)( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT VOID **NotifyHandle ); /** The UnregisterKeystrokeNotify() function removes the notification which was previously registered. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param NotificationHandle The handle of the notification function being unregistered. @retval EFI_SUCCESS Key notify was unregistered successfully. @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY)( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle ); /// /// The EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL is used on the ConsoleIn /// device. It is an extension to the Simple Text Input protocol /// which allows a variety of extended shift state information to be /// returned. /// struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { EFI_INPUT_RESET_EX Reset; EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx; /// /// Event to use with WaitForEvent() to wait for a key to be available. /// EFI_EVENT WaitForKeyEx; EFI_SET_STATE SetState; EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; }; extern EFI_GUID gEfiSimpleTextInputExProtocolGuid; #endif /** @file Simple Text Out protocol from the UEFI 2.0 specification. Abstraction of a very simple text based output device like VGA text mode or a serial terminal. The Simple Text Out protocol instance can represent a single hardware device or a virtual device that is an aggregation of multiple physical devices. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SIMPLE_TEXT_OUT_H__ #define __SIMPLE_TEXT_OUT_H__ #define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ { \ 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } /// /// Protocol GUID defined in EFI1.1. /// #define SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; /// /// Backward-compatible with EFI1.1. /// typedef EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SIMPLE_TEXT_OUTPUT_INTERFACE; // // Defines for required EFI Unicode Box Draw characters // #define BOXDRAW_HORIZONTAL 0x2500 #define BOXDRAW_VERTICAL 0x2502 #define BOXDRAW_DOWN_RIGHT 0x250c #define BOXDRAW_DOWN_LEFT 0x2510 #define BOXDRAW_UP_RIGHT 0x2514 #define BOXDRAW_UP_LEFT 0x2518 #define BOXDRAW_VERTICAL_RIGHT 0x251c #define BOXDRAW_VERTICAL_LEFT 0x2524 #define BOXDRAW_DOWN_HORIZONTAL 0x252c #define BOXDRAW_UP_HORIZONTAL 0x2534 #define BOXDRAW_VERTICAL_HORIZONTAL 0x253c #define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 #define BOXDRAW_DOUBLE_VERTICAL 0x2551 #define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 #define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 #define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 #define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 #define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 #define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 #define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 #define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 #define BOXDRAW_DOUBLE_UP_RIGHT 0x255a #define BOXDRAW_UP_LEFT_DOUBLE 0x255b #define BOXDRAW_UP_DOUBLE_LEFT 0x255c #define BOXDRAW_DOUBLE_UP_LEFT 0x255d #define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e #define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f #define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 #define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 #define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 #define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 #define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 #define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 #define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 #define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 #define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 #define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 #define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a #define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b #define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c // // EFI Required Block Elements Code Chart // #define BLOCKELEMENT_FULL_BLOCK 0x2588 #define BLOCKELEMENT_LIGHT_SHADE 0x2591 // // EFI Required Geometric Shapes Code Chart // #define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 #define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba #define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc #define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 // // EFI Required Arrow shapes // #define ARROW_LEFT 0x2190 #define ARROW_UP 0x2191 #define ARROW_RIGHT 0x2192 #define ARROW_DOWN 0x2193 // // EFI Console Colours // #define EFI_BLACK 0x00 #define EFI_BLUE 0x01 #define EFI_GREEN 0x02 #define EFI_CYAN (EFI_BLUE | EFI_GREEN) #define EFI_RED 0x04 #define EFI_MAGENTA (EFI_BLUE | EFI_RED) #define EFI_BROWN (EFI_GREEN | EFI_RED) #define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) #define EFI_BRIGHT 0x08 #define EFI_DARKGRAY (EFI_BLACK | EFI_BRIGHT) #define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) #define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) #define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) #define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) #define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) #define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) #define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) // // Macro to accept color values in their raw form to create // a value that represents both a foreground and background // color in a single byte. // For Foreground, and EFI_* value is valid from EFI_BLACK(0x00) to // EFI_WHITE (0x0F). // For Background, only EFI_BLACK, EFI_BLUE, EFI_GREEN, EFI_CYAN, // EFI_RED, EFI_MAGENTA, EFI_BROWN, and EFI_LIGHTGRAY are acceptable // // Do not use EFI_BACKGROUND_xxx values with this macro. // #define EFI_TEXT_ATTR(Foreground, Background) ((Foreground) | ((Background) << 4)) #define EFI_BACKGROUND_BLACK 0x00 #define EFI_BACKGROUND_BLUE 0x10 #define EFI_BACKGROUND_GREEN 0x20 #define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) #define EFI_BACKGROUND_RED 0x40 #define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) #define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) #define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) // // We currently define attributes from 0 - 7F for color manipulations // To internally handle the local display characteristics for a particular character, // Bit 7 signifies the local glyph representation for a character. If turned on, glyphs will be // pulled from the wide glyph database and will display locally as a wide character (16 X 19 versus 8 X 19) // If bit 7 is off, the narrow glyph database will be used. This does NOT affect information that is sent to // non-local displays, such as serial or LAN consoles. // #define EFI_WIDE_ATTRIBUTE 0x80 /** Reset the text output device hardware and optionally run diagnostics @param This The protocol instance pointer. @param ExtendedVerification Driver may perform more exhaustive verification operation of the device during reset. @retval EFI_SUCCESS The text output device was reset. @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and could not be reset. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_RESET)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); /** Write a string to the output device. @param This The protocol instance pointer. @param String The NULL-terminated string to be displayed on the output device(s). All output devices must also support the Unicode drawing character codes defined in this file. @retval EFI_SUCCESS The string was output to the device. @retval EFI_DEVICE_ERROR The device reported an error while attempting to output the text. @retval EFI_UNSUPPORTED The output device's mode is not currently in a defined text mode. @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the characters in the string could not be rendered and were skipped. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_STRING)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String ); /** Verifies that all characters in a string can be output to the target device. @param This The protocol instance pointer. @param String The NULL-terminated string to be examined for the output device(s). @retval EFI_SUCCESS The device(s) are capable of rendering the output string. @retval EFI_UNSUPPORTED Some of the characters in the string cannot be rendered by one or more of the output devices mapped by the EFI handle. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_TEST_STRING)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *String ); /** Returns information for an available text mode that the output device(s) supports. @param This The protocol instance pointer. @param ModeNumber The mode number to return information on. @param Columns Returns the geometry of the text output device for the requested ModeNumber. @param Rows Returns the geometry of the text output device for the requested ModeNumber. @retval EFI_SUCCESS The requested mode information was returned. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED The mode number was not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_QUERY_MODE)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows ); /** Sets the output device(s) to a specified mode. @param This The protocol instance pointer. @param ModeNumber The mode number to set. @retval EFI_SUCCESS The requested text mode was set. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED The mode number was not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_SET_MODE)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber ); /** Sets the background and foreground colors for the OutputString () and ClearScreen () functions. @param This The protocol instance pointer. @param Attribute The attribute to set. Bits 0..3 are the foreground color, and bits 4..6 are the background color. All other bits are undefined and must be zero. The valid Attributes are defined in this file. @retval EFI_SUCCESS The attribute was set. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED The attribute requested is not defined. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_SET_ATTRIBUTE)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute ); /** Clears the output device(s) display to the currently selected background color. @param This The protocol instance pointer. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED The output device is not in a valid text mode. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_CLEAR_SCREEN)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This ); /** Sets the current coordinates of the cursor position @param This The protocol instance pointer. @param Column The position to set the cursor to. Must be greater than or equal to zero and less than the number of columns and rows by QueryMode (). @param Row The position to set the cursor to. Must be greater than or equal to zero and less than the number of columns and rows by QueryMode (). @retval EFI_SUCCESS The operation completed successfully. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the cursor position is invalid for the current mode. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row ); /** Makes the cursor visible or invisible @param This The protocol instance pointer. @param Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is set to be invisible. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request, or the device does not support changing the cursor mode. @retval EFI_UNSUPPORTED The output device is not in a valid text mode. **/ typedef EFI_STATUS (EFIAPI *EFI_TEXT_ENABLE_CURSOR)( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible ); /** @par Data Structure Description: Mode Structure pointed to by Simple Text Out protocol. **/ typedef struct { /// /// The number of modes supported by QueryMode () and SetMode (). /// INT32 MaxMode; // // current settings // /// /// The text mode of the output device(s). /// INT32 Mode; /// /// The current character output attribute. /// INT32 Attribute; /// /// The cursor's column. /// INT32 CursorColumn; /// /// The cursor's row. /// INT32 CursorRow; /// /// The cursor is currently visible or not. /// BOOLEAN CursorVisible; } EFI_SIMPLE_TEXT_OUTPUT_MODE; /// /// The SIMPLE_TEXT_OUTPUT protocol is used to control text-based output devices. /// It is the minimum required protocol for any handle supplied as the ConsoleOut /// or StandardError device. In addition, the minimum supported text mode of such /// devices is at least 80 x 25 characters. /// struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { EFI_TEXT_RESET Reset; EFI_TEXT_STRING OutputString; EFI_TEXT_TEST_STRING TestString; EFI_TEXT_QUERY_MODE QueryMode; EFI_TEXT_SET_MODE SetMode; EFI_TEXT_SET_ATTRIBUTE SetAttribute; EFI_TEXT_CLEAR_SCREEN ClearScreen; EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; EFI_TEXT_ENABLE_CURSOR EnableCursor; /// /// Pointer to SIMPLE_TEXT_OUTPUT_MODE data. /// EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; }; extern EFI_GUID gEfiSimpleTextOutProtocolGuid; #endif /** @file The UEFI Smart Card Reader Protocol provides an abstraction for device to provide smart card reader support. This protocol is very close to Part 5 of PC/SC workgroup specifications and provides an API to applications willing to communicate with a smart card or a smart card reader. Copyright (c) 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __SMART_CARD_READER_H__ #define __SMART_CARD_READER_H__ #define EFI_SMART_CARD_READER_PROTOCOL_GUID \ { \ 0x2a4d1adf, 0x21dc, 0x4b81, {0xa4, 0x2f, 0x8b, 0x8e, 0xe2, 0x38, 0x00, 0x60} \ } typedef struct _EFI_SMART_CARD_READER_PROTOCOL EFI_SMART_CARD_READER_PROTOCOL; // // Codes for access mode // #define SCARD_AM_READER 0x0001 // Exclusive access to reader #define SCARD_AM_CARD 0x0002 // Exclusive access to card // // Codes for card action // #define SCARD_CA_NORESET 0x0000 // Don't reset card #define SCARD_CA_COLDRESET 0x0001 // Perform a cold reset #define SCARD_CA_WARMRESET 0x0002 // Perform a warm reset #define SCARD_CA_UNPOWER 0x0003 // Power off the card #define SCARD_CA_EJECT 0x0004 // Eject the card // // Protocol types // #define SCARD_PROTOCOL_UNDEFINED 0x0000 #define SCARD_PROTOCOL_T0 0x0001 #define SCARD_PROTOCOL_T1 0x0002 #define SCARD_PROTOCOL_RAW 0x0004 // // Codes for state type // #define SCARD_UNKNOWN 0x0000 /* state is unknown */ #define SCARD_ABSENT 0x0001 /* Card is absent */ #define SCARD_INACTIVE 0x0002 /* Card is present and not powered*/ #define SCARD_ACTIVE 0x0003 /* Card is present and powered */ // // Macro to generate a ControlCode & PC/SC part 10 control code // #define SCARD_CTL_CODE(code) (0x42000000 + (code)) #define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400) /** This function requests connection to the smart card or the reader, using the appropriate reset type and protocol. The SCardConnectfunction requests access to the smart card or the reader. Upon success, it is then possible to call SCardTransmit. If AccessMode is set to SCARD_AM_READER, PreferredProtocols must be set to SCARD_PROTOCOL_UNDEFINED and CardAction to SCARD_CA_NORESET else function fails with EFI_INVALID_PARAMETER. @param[in] This Indicates a pointer to the calling context. @param[in] AccessMode Codes of access mode. @param[in] CardAction SCARD_CA_NORESET, SCARD_CA_COLDRESET or SCARD_CA_WARMRESET. @param[in] PreferredProtocols Bitmask of acceptable protocols. @param[out] ActiveProtocol A flag that indicates the active protocol. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL @retval EFI_INVALID_PARAMETER AccessMode is not valid. @retval EFI_INVALID_PARAMETER CardAction is not valid. @retval EFI_INVALID_PARAMETER Invalid combination of AccessMode/CardAction/ PreferredProtocols. @retval EFI_NOT_READY A smart card is inserted but failed to return an ATR. @retval EFI_UNSUPPORTED PreferredProtocols does not contain an available protocol to use. @retval EFI_NO_MEDIA AccessMode is set to SCARD_AM_CARD but there is no smart card inserted. @retval EFI_ACCESS_DENIED Access is already locked by a previous SCardConnectcall. @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_CONNECT)( IN EFI_SMART_CARD_READER_PROTOCOL *This, IN UINT32 AccessMode, IN UINT32 CardAction, IN UINT32 PreferredProtocols, OUT UINT32 *ActiveProtocol ); /** This function releases a connection previously taken by SCardConnect. The SCardDisconnect function releases the lock previously taken by SCardConnect. In case the smart card has been removed before this call, thisfunction returns EFI_SUCCESS. If there is no previous call to SCardConnect, this function returns EFI_SUCCESS. @param[in] This Indicates a pointer to the calling context. @param[in] CardAction Codes for card action. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL @retval EFI_INVALID_PARAMETER CardAction value is unknown. @retval EFI_UNSUPPORTED Reader does not support Eject card feature (disconnect was not performed). @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_DISCONNECT)( IN EFI_SMART_CARD_READER_PROTOCOL *This, IN UINT32 CardAction ); /** This function retrieves some basic information about the smart card and reader. The SCardStatusfunction retrieves basic reader and card information. If ReaderName, State, CardProtocolor Atris NULL, the function does not fail but does not fill in such variables. If EFI_SUCCESS is not returned, ReaderName and Atr contents shall not be considered as valid. @param[in] This Indicates a pointer to the calling context. @param[out] ReaderName A pointer to a NULL terminated string that will contain the reader name. @param[in, out] ReaderNameLength On input, a pointer to the variablethat holds the maximal size, in bytes,of ReaderName. On output, the required size, in bytes, for ReaderName. @param[out] State Current state of the smart card reader. @param[out] CardProtocol Current protocol used to communicate with the smart card. @param[out] Atr A pointer to retrieve the ATR of the smart card. @param[in, out] AtrLength On input, a pointer to hold the maximum size, in bytes, of Atr(usually 33). On output, the required size, inbytes, for the smart card ATR. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL @retval EFI_INVALID_PARAMETER ReaderName is not NULL but ReaderNameLength is NULL @retval EFI_INVALID_PARAMETER Atr is not NULL but AtrLength is NULL @retval EFI_BUFFER_TOO_SMALL ReaderNameLength is not big enough to hold the reader name. ReaderNameLength has been updated to the required value. @retval EFI_BUFFER_TOO_SMALL AtrLength is not big enough to hold the ATR. AtrLength has been updated to the required value. @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_STATUS)( IN EFI_SMART_CARD_READER_PROTOCOL *This, OUT CHAR16 *ReaderName OPTIONAL, IN OUT UINTN *ReaderNameLength OPTIONAL, OUT UINT32 *State OPTIONAL, OUT UINT32 *CardProtocol OPTIONAL, OUT UINT8 *Atr OPTIONAL, IN OUT UINTN *AtrLength OPTIONAL ); /** This function sends a command to the card or reader and returns its response. The protocol to use to communicate with the smart card has been selected through SCardConnectcall. In case RAPDULength indicates a buffer too small to holdthe response APDU, the function fails with EFI_BUFFER_TOO_SMALL. @param[in] This A pointer to the EFI_USBFN_IO_PROTOCOLinstance. @param[in] CAPDU A pointer to a byte array thatcontains the Command APDU to send to the smart card or reader. @param[in] CAPDULength Command APDU size, in bytes. @param[out] RAPDU A pointer to a byte array that will contain the Response APDU. @param[in, out] RAPDULength On input, the maximum size, inbytes, of the Response APDU. On output, the size, in bytes, of the Response APDU. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER CAPDU is NULL or CAPDULength is 0. @retval EFI_BUFFER_TOO_SMALL RAPDULength is not big enough to hold the response APDU. RAPDULength has been updated to the required value. @retval EFI_NO_MEDIA There is no card in the reader. @retval EFI_NOT_READY Card is not powered. @retval EFI_PROTOCOL_ERROR A protocol error has occurred. @retval EFI_TIMEOUT The reader did not respond. @retval EFI_ACCESS_DENIED A communication with the reader/card is already pending. @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_TRANSMIT)( IN EFI_SMART_CARD_READER_PROTOCOL *This, IN UINT8 *CAPDU, IN UINTN CAPDULength, OUT UINT8 *RAPDU, IN OUT UINTN *RAPDULength ); /** This function provides direct access to the reader. This function gives direct control to send commands to the driver or the reader. The ControlCode to use is vendor dependant; the only standard code defined is the one to get PC/SC part 10 features. InBuffer and Outbuffer may be NULL when ControlCode operation does not require them. @param[in] This Indicates a pointer to the calling context. @param[in] ControlCode The control code for the operation to perform. @param[in] InBuffer A pointer to the input parameters. @param[in] InBufferLength Size, in bytes, of input parameters. @param[out] OutBuffer A pointer to the output parameters. @param[in, out] OutBufferLength On input, maximal size, in bytes, to store output parameters. On output, the size, in bytes, of output parameters. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER ControlCode requires input parameters but: InBuffer is NULL or InBufferLenth is NULL or InBuffer is not NULL but InBufferLenth is less than expected. @retval EFI_INVALID_PARAMETER OutBuffer is not NULL but OutBufferLength is NULL. @retval EFI_UNSUPPORTED ControlCode is not supported. @retval EFI_BUFFER_TOO_SMALL OutBufferLength is not big enough to hold the output parameters. OutBufferLength has been updated to the required value. @retval EFI_NO_MEDIA There is no card in the reader and the control code specified requires one. @retval EFI_NOT_READY ControlCode requires a powered card to operate. @retval EFI_PROTOCOL_ERROR A protocol error has occurred. @retval EFI_TIMEOUT The reader did not respond. @retval EFI_ACCESS_DENIED A communication with the reader/card is already pending. @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_CONTROL)( IN EFI_SMART_CARD_READER_PROTOCOL *This, IN UINT32 ControlCode, IN UINT8 *InBuffer OPTIONAL, IN UINTN InBufferLength OPTIONAL, OUT UINT8 *OutBuffer OPTIONAL, IN OUT UINTN *OutBufferLength OPTIONAL ); /** This function retrieves a reader or smart card attribute. Possibly supported attrib values are listed in "PC/SC specification, Part 3: Requirements for PC-Connected Interface Devices". @param[in] This Indicates a pointer to the calling context. @param[in] Attrib Identifier for the attribute to retrieve. @param[out] OutBuffer A pointer to a buffer that will contain attribute data. @param[in, out] OutBufferLength On input, maximal size, in bytes, to store attribute data. On output, the size, in bytes, of attribute data. @retval EFI_SUCCESS The requested command completed successfully. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER OutBuffer is NULL or OutBufferLength is 0. @retval EFI_BUFFER_TOO_SMALL OutBufferLength is not big enough to hold the output parameters. OutBufferLength has been updated to the required value. @retval EFI_UNSUPPORTED Attribis not supported @retval EFI_NO_MEDIA There is no card in the reader and Attrib value requires one. @retval EFI_NOT_READY Attrib requires a powered card to operate. @retval EFI_PROTOCOL_ERROR A protocol error has occurred. @retval EFI_TIMEOUT The reader did not respond. @retval EFI_DEVICE_ERROR Any other error condition, typically a reader removal. **/ typedef EFI_STATUS (EFIAPI *EFI_SMART_CARD_READER_GET_ATTRIB)( IN EFI_SMART_CARD_READER_PROTOCOL *This, IN UINT32 Attrib, OUT UINT8 *OutBuffer, IN OUT UINTN *OutBufferLength ); /// /// Smart card aware application invokes this protocol to get access to an inserted /// smart card in the reader or to the reader itself. /// struct _EFI_SMART_CARD_READER_PROTOCOL { EFI_SMART_CARD_READER_CONNECT SCardConnect; EFI_SMART_CARD_READER_DISCONNECT SCardDisconnect; EFI_SMART_CARD_READER_STATUS SCardStatus; EFI_SMART_CARD_READER_TRANSMIT SCardTransmit; EFI_SMART_CARD_READER_CONTROL SCardControl; EFI_SMART_CARD_READER_GET_ATTRIB SCardGetAttrib; }; extern EFI_GUID gEfiSmartCardReaderProtocolGuid; #endif /** @file Status code Runtime Protocol as defined in PI Specification 1.4a VOLUME 2 DXE Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __STATUS_CODE_RUNTIME_PROTOCOL_H__ #define __STATUS_CODE_RUNTIME_PROTOCOL_H__ #define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \ { 0xd2b2b828, 0x826, 0x48a7, { 0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0 } } /** Provides an interface that a software module can call to report a status code. @param Type Indicates the type of status code being reported. @param Value Describes the current status of a hardware or software entity. This included information about the class and subclass that is used to classify the entity as well as an operation. @param Instance The enumeration of a hardware or software entity within the system. Valid instance numbers start with 1. @param CallerId This optional parameter may be used to identify the caller. This parameter allows the status code driver to apply different rules to different callers. @param Data This optional parameter may be used to pass additional data. @retval EFI_SUCCESS The function completed successfully @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. **/ typedef EFI_STATUS (EFIAPI *EFI_REPORT_STATUS_CODE)( IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL, IN EFI_STATUS_CODE_DATA *Data OPTIONAL ); /// /// Provides the service required to report a status code to the platform firmware. /// This protocol must be produced by a runtime DXE driver. /// typedef struct _EFI_STATUS_CODE_PROTOCOL { EFI_REPORT_STATUS_CODE ReportStatusCode; } EFI_STATUS_CODE_PROTOCOL; extern EFI_GUID gEfiStatusCodeRuntimeProtocolGuid; #endif /** @file EFI Storage Security Command Protocol as defined in UEFI 2.3.1 specification. This protocol is used to abstract mass storage devices to allow code running in the EFI boot services environment to send security protocol commands to mass storage devices without specific knowledge of the type of device or controller that manages the device. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __STORAGE_SECURITY_COMMAND_H__ #define __STORAGE_SECURITY_COMMAND_H__ #define EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID \ { \ 0xC88B0B6D, 0x0DFC, 0x49A7, {0x9C, 0xB4, 0x49, 0x07, 0x4B, 0x4C, 0x3A, 0x78 } \ } typedef struct _EFI_STORAGE_SECURITY_COMMAND_PROTOCOL EFI_STORAGE_SECURITY_COMMAND_PROTOCOL; /** Send a security protocol command to a device that receives data and/or the result of one or more commands sent by SendData. The ReceiveData function sends a security protocol command to the given MediaId. The security protocol command sent is defined by SecurityProtocolId and contains the security protocol specific data SecurityProtocolSpecificData. The function returns the data from the security protocol command in PayloadBuffer. For devices supporting the SCSI command set, the security protocol command is sent using the SECURITY PROTOCOL IN command defined in SPC-4. For devices supporting the ATA command set, the security protocol command is sent using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize is non-zero. If the PayloadBufferSize is zero, the security protocol command is sent using the Trusted Non-Data command defined in ATA8-ACS. If PayloadBufferSize is too small to store the available data from the security protocol command, the function shall copy PayloadBufferSize bytes into the PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, the function shall return EFI_INVALID_PARAMETER. If the given MediaId does not support security protocol commands, the function shall return EFI_UNSUPPORTED. If there is no media in the device, the function returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, the function returns EFI_MEDIA_CHANGED. If the security protocol fails to complete within the Timeout period, the function shall return EFI_TIMEOUT. If the security protocol command completes without an error, the function shall return EFI_SUCCESS. If the security protocol command completes with an error, the function shall return EFI_DEVICE_ERROR. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to receive data from. @param Timeout The timeout, in 100ns units, to use for the execution of the security protocol command. A Timeout value of 0 means that this function will wait indefinitely for the security protocol command to execute. If Timeout is greater than zero, then this function will return EFI_TIMEOUT if the time required to execute the receive data command is greater than Timeout. @param SecurityProtocolId The value of the "Security Protocol" parameter of the security protocol command to be sent. @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter of the security protocol command to be sent. @param PayloadBufferSize Size in bytes of the payload data buffer. @param PayloadBuffer A pointer to a destination buffer to store the security protocol command specific payload data for the security protocol command. The caller is responsible for having either implicit or explicit ownership of the buffer. @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the data written to the payload data buffer. @retval EFI_SUCCESS The security protocol command completed successfully. @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available data from the device. The PayloadBuffer contains the truncated data. @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. @retval EFI_DEVICE_ERROR The security protocol command completed with an error. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero. @retval EFI_TIMEOUT A timeout occurred while waiting for the security protocol command to execute. **/ typedef EFI_STATUS (EFIAPI *EFI_STORAGE_SECURITY_RECEIVE_DATA)( IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Timeout, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN PayloadBufferSize, OUT VOID *PayloadBuffer, OUT UINTN *PayloadTransferSize ); /** Send a security protocol command to a device. The SendData function sends a security protocol command containing the payload PayloadBuffer to the given MediaId. The security protocol command sent is defined by SecurityProtocolId and contains the security protocol specific data SecurityProtocolSpecificData. If the underlying protocol command requires a specific padding for the command payload, the SendData function shall add padding bytes to the command payload to satisfy the padding requirements. For devices supporting the SCSI command set, the security protocol command is sent using the SECURITY PROTOCOL OUT command defined in SPC-4. For devices supporting the ATA command set, the security protocol command is sent using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize is non-zero. If the PayloadBufferSize is zero, the security protocol command is sent using the Trusted Non-Data command defined in ATA8-ACS. If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall return EFI_INVALID_PARAMETER. If the given MediaId does not support security protocol commands, the function shall return EFI_UNSUPPORTED. If there is no media in the device, the function returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, the function returns EFI_MEDIA_CHANGED. If the security protocol fails to complete within the Timeout period, the function shall return EFI_TIMEOUT. If the security protocol command completes without an error, the function shall return EFI_SUCCESS. If the security protocol command completes with an error, the function shall return EFI_DEVICE_ERROR. @param This Indicates a pointer to the calling context. @param MediaId ID of the medium to receive data from. @param Timeout The timeout, in 100ns units, to use for the execution of the security protocol command. A Timeout value of 0 means that this function will wait indefinitely for the security protocol command to execute. If Timeout is greater than zero, then this function will return EFI_TIMEOUT if the time required to execute the receive data command is greater than Timeout. @param SecurityProtocolId The value of the "Security Protocol" parameter of the security protocol command to be sent. @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter of the security protocol command to be sent. @param PayloadBufferSize Size in bytes of the payload data buffer. @param PayloadBuffer A pointer to a destination buffer to store the security protocol command specific payload data for the security protocol command. @retval EFI_SUCCESS The security protocol command completed successfully. @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. @retval EFI_DEVICE_ERROR The security protocol command completed with an error. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. @retval EFI_TIMEOUT A timeout occurred while waiting for the security protocol command to execute. **/ typedef EFI_STATUS (EFIAPI *EFI_STORAGE_SECURITY_SEND_DATA)( IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Timeout, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN PayloadBufferSize, IN VOID *PayloadBuffer ); /// /// The EFI_STORAGE_SECURITY_COMMAND_PROTOCOL is used to send security protocol /// commands to a mass storage device. Two types of security protocol commands /// are supported. SendData sends a command with data to a device. ReceiveData /// sends a command that receives data and/or the result of one or more commands /// sent by SendData. /// /// The security protocol command formats supported shall be based on the definition /// of the SECURITY PROTOCOL IN and SECURITY PROTOCOL OUT commands defined in SPC-4. /// If the device uses the SCSI command set, no translation is needed in the firmware /// and the firmware can package the parameters into a SECURITY PROTOCOL IN or SECURITY /// PROTOCOL OUT command and send the command to the device. If the device uses a /// non-SCSI command set, the firmware shall map the command and data payload to the /// corresponding command and payload format defined in the non-SCSI command set /// (for example, TRUSTED RECEIVE and TRUSTED SEND in ATA8-ACS). /// /// The firmware shall automatically add an EFI_STORAGE_SECURITY_COMMAND_PROTOCOL /// for any storage devices detected during system boot that support SPC-4, ATA8-ACS /// or their successors. /// struct _EFI_STORAGE_SECURITY_COMMAND_PROTOCOL { EFI_STORAGE_SECURITY_RECEIVE_DATA ReceiveData; EFI_STORAGE_SECURITY_SEND_DATA SendData; }; extern EFI_GUID gEfiStorageSecurityCommandProtocolGuid; #endif /** @file The Super I/O Protocol is installed by the Super I/O driver. The Super I/O driver is a UEFI driver model compliant driver. In the Start() routine of the Super I/O driver, a handle with an instance of EFI_SIO_PROTOCOL is created for each device within the Super I/O. The device within the Super I/O is powered up, enabled, and assigned with the default set of resources. In the Stop() routine of the Super I/O driver, the device is disabled and Super I/O protocol is uninstalled. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_SUPER_IO_PROTOCOL_H__ #define __EFI_SUPER_IO_PROTOCOL_H__ #include #define EFI_SIO_PROTOCOL_GUID \ { 0x215fdd18, 0xbd50, 0x4feb, { 0x89, 0xb, 0x58, 0xca, 0xb, 0x47, 0x39, 0xe9 } } typedef union { ACPI_SMALL_RESOURCE_HEADER *SmallHeader; ACPI_LARGE_RESOURCE_HEADER *LargeHeader; } ACPI_RESOURCE_HEADER_PTR; typedef struct { UINT8 Register; ///< Register number. UINT8 AndMask; ///< Bitwise AND mask. UINT8 OrMask; ///< Bitwise OR mask. } EFI_SIO_REGISTER_MODIFY; typedef struct _EFI_SIO_PROTOCOL EFI_SIO_PROTOCOL; /** Provides a low level access to the registers for the Super I/O. @param[in] This Indicates a pointer to the calling context. @param[in] Write Specifies the type of the register operation. If this parameter is TRUE, Value is interpreted as an input parameter and the operation is a register write. If this parameter is FALSE, Value is interpreted as an output parameter and the operation is a register read. @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the Super I/O driver will turn off configuration mode of the Super I/O prior to returning from this function. If this parameter is set to FALSE, the Super I/O driver will leave Super I/O in the configuration mode. The Super I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/O if necessary prior to register access. @param[in] Register Register number. @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be written to the Super I/O register. If Write is FALSE, Value is a pointer to the destination buffer for the byte of data to be read from the Super I/O register. @retval EFI_SUCCESS The operation completed successfully @retval EFI_INVALID_PARAMETER The Value is NULL @retval EFI_INVALID_PARAMETER Invalid Register number **/ typedef EFI_STATUS (EFIAPI *EFI_SIO_REGISTER_ACCESS)( IN CONST EFI_SIO_PROTOCOL *This, IN BOOLEAN Write, IN BOOLEAN ExitCfgMode, IN UINT8 Register, IN OUT UINT8 *Value ); /** Provides an interface to get a list of the current resources consumed by the device in the ACPI Resource Descriptor format. GetResources() returns a list of resources currently consumed by the device. The ResourceList is a pointer to the buffer containing resource descriptors for the device. The descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag' resource descriptor. @param[in] This Indicates a pointer to the calling context. @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related Definitions" below. @retval EFI_SUCCESS The operation completed successfully @retval EFI_INVALID_PARAMETER ResourceList is NULL **/ typedef EFI_STATUS (EFIAPI *EFI_SIO_GET_RESOURCES)( IN CONST EFI_SIO_PROTOCOL *This, OUT ACPI_RESOURCE_HEADER_PTR *ResourceList ); /** Sets the resources for the device. @param[in] This Indicates a pointer to the calling context. @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related Definitions" section of EFI_SIO_PROTOCOL.GetResources(). @retval EFI_SUCCESS The operation completed successfully @retval EFI_INVALID_PARAMETER ResourceList is invalid @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use **/ typedef EFI_STATUS (EFIAPI *EFI_SIO_SET_RESOURCES)( IN CONST EFI_SIO_PROTOCOL *This, IN ACPI_RESOURCE_HEADER_PTR ResourceList ); /** Provides a collection of resource descriptor lists. Each resource descriptor list in the collection defines a combination of resources that can potentially be used by the device. @param[in] This Indicates a pointer to the calling context. @param[out] ResourceCollection Collection of the resource descriptor lists. @retval EFI_SUCCESS The operation completed successfully @retval EFI_INVALID_PARAMETER ResourceCollection is NULL **/ typedef EFI_STATUS (EFIAPI *EFI_SIO_POSSIBLE_RESOURCES)( IN CONST EFI_SIO_PROTOCOL *This, OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection ); /** Provides an interface for a table based programming of the Super I/O registers. The Modify() function provides an interface for table based programming of the Super I/O registers. This function can be used to perform programming of multiple Super I/O registers with a single function call. For each table entry, the Register is read, its content is bitwise ANDed with AndMask, and then ORed with OrMask before being written back to the Register. The Super I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/ O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be returned to the original state. @param[in] This Indicates a pointer to the calling context. @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY structures. Each structure specifies a single Super I/O register modify operation. Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below. @param[in] NumberOfCommands Number of elements in the Command array. @retval EFI_SUCCESS The operation completed successfully @retval EFI_INVALID_PARAMETER Command is NULL **/ typedef EFI_STATUS (EFIAPI *EFI_SIO_MODIFY)( IN CONST EFI_SIO_PROTOCOL *This, IN CONST EFI_SIO_REGISTER_MODIFY *Command, IN UINTN NumberOfCommands ); struct _EFI_SIO_PROTOCOL { EFI_SIO_REGISTER_ACCESS RegisterAccess; EFI_SIO_GET_RESOURCES GetResources; EFI_SIO_SET_RESOURCES SetResources; EFI_SIO_POSSIBLE_RESOURCES PossibleResources; EFI_SIO_MODIFY Modify; }; extern EFI_GUID gEfiSioProtocolGuid; #endif // __EFI_SUPER_IO_PROTOCOL_H__ /** @file TPM2 Protocol as defined in TCG PC Client Platform EFI Protocol Specification Family "2.0". See http://trustedcomputinggroup.org for the latest specification Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __TCG2_PROTOCOL_H__ #define __TCG2_PROTOCOL_H__ #include #include #define EFI_TCG2_PROTOCOL_GUID \ {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }} typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL; typedef struct tdEFI_TCG2_VERSION { UINT8 Major; UINT8 Minor; } EFI_TCG2_VERSION; typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP; typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT; typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP; #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002 typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY { // // Allocated size of the structure // UINT8 Size; // // Version of the EFI_TCG2_BOOT_SERVICE_CAPABILITY structure itself. // For this version of the protocol, the Major version shall be set to 1 // and the Minor version shall be set to 1. // EFI_TCG2_VERSION StructureVersion; // // Version of the EFI TCG2 protocol. // For this version of the protocol, the Major version shall be set to 1 // and the Minor version shall be set to 1. // EFI_TCG2_VERSION ProtocolVersion; // // Supported hash algorithms (this bitmap is determined by the supported PCR // banks in the TPM and the hashing algorithms supported by the firmware) // EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; // // Bitmap of supported event log formats // EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs; // // False = TPM not present // BOOLEAN TPMPresentFlag; // // Max size (in bytes) of a command that can be sent to the TPM // UINT16 MaxCommandSize; // // Max size (in bytes) of a response that can be provided by the TPM // UINT16 MaxResponseSize; // // 4-byte Vendor ID // (see TCG Vendor ID registry, Section "TPM Capabilities Vendor ID") // UINT32 ManufacturerID; // // Maximum number of PCR banks (hashing algorithms) supported. // No granularity is provided to support a specific set of algorithms. // Minimum value is 1. // UINT32 NumberOfPCRBanks; // // A bitmap of currently active PCR banks (hashing algorithms). // This is a subset of the supported hashing algorithms reported in HashAlgorithmBitMap. // NumberOfPcrBanks defines the number of bits that are set. // EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks; } EFI_TCG2_BOOT_SERVICE_CAPABILITY; #define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001 #define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002 #define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004 #define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008 #define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010 // // This bit is shall be set when an event shall be extended but not logged. // #define EFI_TCG2_EXTEND_ONLY 0x0000000000000001 // // This bit shall be set when the intent is to measure a PE/COFF image. // #define PE_COFF_IMAGE 0x0000000000000010 #define MAX_PCR_INDEX 23 #pragma pack(1) #define EFI_TCG2_EVENT_HEADER_VERSION 1 typedef struct { // // Size of the event header itself (sizeof(EFI_TCG2_EVENT_HEADER)). // UINT32 HeaderSize; // // Header version. For this version of this specification, the value shall be 1. // UINT16 HeaderVersion; // // Index of the PCR that shall be extended (0 - 23). // TCG_PCRINDEX PCRIndex; // // Type of the event that shall be extended (and optionally logged). // TCG_EVENTTYPE EventType; } EFI_TCG2_EVENT_HEADER; typedef struct tdEFI_TCG2_EVENT { // // Total size of the event including the Size component, the header and the Event data. // UINT32 Size; EFI_TCG2_EVENT_HEADER Header; UINT8 Event[1]; } EFI_TCG2_EVENT; #pragma pack() /** The EFI_TCG2_PROTOCOL GetCapability function call provides protocol capability information and state information. @param[in] This Indicates the calling context @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY structure and sets the size field to the size of the structure allocated. The callee fills in the fields with the EFI protocol capability information and the current EFI TCG2 state information up to the number of fields which fit within the size of the structure passed in. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. The ProtocolCapability variable will not be populated. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. The ProtocolCapability variable will not be populated. @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response. It will be partially populated (required Size field will be set). **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_GET_CAPABILITY)( IN EFI_TCG2_PROTOCOL *This, IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability ); /** The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to retrieve the address of a given event log and its last entry. @param[in] This Indicates the calling context @param[in] EventLogFormat The type of the event log for which the information is requested. @param[out] EventLogLocation A pointer to the memory address of the event log. @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the address of the start of the last entry in the event log in memory. @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would have exceeded the area allocated for events, this value is set to TRUE. Otherwise, the value will be FALSE and the Event Log will be complete. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect (e.g. asking for an event log whose format is not supported). **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_GET_EVENT_LOG)( IN EFI_TCG2_PROTOCOL *This, IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, OUT EFI_PHYSICAL_ADDRESS *EventLogLocation, OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry, OUT BOOLEAN *EventLogTruncated ); /** The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with an opportunity to extend and optionally log events without requiring knowledge of actual TPM commands. The extend operation will occur even if this function cannot create an event log entry (e.g. due to the event log being full). @param[in] This Indicates the calling context @param[in] Flags Bitmap providing additional information. @param[in] DataToHash Physical address of the start of the data buffer to be hashed. @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash. @param[in] EfiTcgEvent Pointer to data buffer containing information about the event. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. @retval EFI_UNSUPPORTED The PE/COFF image type is not supported. **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_HASH_LOG_EXTEND_EVENT)( IN EFI_TCG2_PROTOCOL *This, IN UINT64 Flags, IN EFI_PHYSICAL_ADDRESS DataToHash, IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT *EfiTcgEvent ); /** This service enables the sending of commands to the TPM. @param[in] This Indicates the calling context @param[in] InputParameterBlockSize Size of the TPM input parameter block. @param[in] InputParameterBlock Pointer to the TPM input parameter block. @param[in] OutputParameterBlockSize Size of the TPM output parameter block. @param[in] OutputParameterBlock Pointer to the TPM output parameter block. @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received. @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_SUBMIT_COMMAND)( IN EFI_TCG2_PROTOCOL *This, IN UINT32 InputParameterBlockSize, IN UINT8 *InputParameterBlock, IN UINT32 OutputParameterBlockSize, IN UINT8 *OutputParameterBlock ); /** This service returns the currently active PCR banks. @param[in] This Indicates the calling context @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks. @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_GET_ACTIVE_PCR_BANKS)( IN EFI_TCG2_PROTOCOL *This, OUT UINT32 *ActivePcrBanks ); /** This service sets the currently active PCR banks. @param[in] This Indicates the calling context @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set. @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_SET_ACTIVE_PCR_BANKS)( IN EFI_TCG2_PROTOCOL *This, IN UINT32 ActivePcrBanks ); /** This service retrieves the result of a previous invocation of SetActivePcrBanks. @param[in] This Indicates the calling context @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot. @param[out] Response The response from the SetActivePcrBank request. @retval EFI_SUCCESS The result value could be returned. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. **/ typedef EFI_STATUS (EFIAPI *EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS)( IN EFI_TCG2_PROTOCOL *This, OUT UINT32 *OperationPresent, OUT UINT32 *Response ); struct tdEFI_TCG2_PROTOCOL { EFI_TCG2_GET_CAPABILITY GetCapability; EFI_TCG2_GET_EVENT_LOG GetEventLog; EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent; EFI_TCG2_SUBMIT_COMMAND SubmitCommand; EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks; EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks; EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks; }; extern EFI_GUID gEfiTcg2ProtocolGuid; // // Log entries after Get Event Log service // #define EFI_TCG2_FINAL_EVENTS_TABLE_GUID \ {0x1e2ed096, 0x30e2, 0x4254, { 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25 }} extern EFI_GUID gEfiTcg2FinalEventsTableGuid; typedef struct tdEFI_TCG2_FINAL_EVENTS_TABLE { // // The version of this structure. // UINT64 Version; // // Number of events recorded after invocation of GetEventLog API // UINT64 NumberOfEvents; // // List of events of type TCG_PCR_EVENT2. // // TCG_PCR_EVENT2 Event[1]; } EFI_TCG2_FINAL_EVENTS_TABLE; #define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1 #endif /** @file EFI TCPv4(Transmission Control Protocol version 4) Protocol Definition The EFI TCPv4 Service Binding Protocol is used to locate EFI TCPv4 Protocol drivers to create and destroy child of the driver to communicate with other host using TCP protocol. The EFI TCPv4 Protocol provides services to send and receive data stream. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0. **/ #ifndef __EFI_TCP4_PROTOCOL_H__ #define __EFI_TCP4_PROTOCOL_H__ #include #define EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x00720665, 0x67EB, 0x4a99, {0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9 } \ } #define EFI_TCP4_PROTOCOL_GUID \ { \ 0x65530BC7, 0xA359, 0x410f, {0xB0, 0x10, 0x5A, 0xAD, 0xC7, 0xEC, 0x2B, 0x62 } \ } typedef struct _EFI_TCP4_PROTOCOL EFI_TCP4_PROTOCOL; /// /// EFI_TCP4_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE InstanceHandle; EFI_IPv4_ADDRESS LocalAddress; UINT16 LocalPort; EFI_IPv4_ADDRESS RemoteAddress; UINT16 RemotePort; } EFI_TCP4_SERVICE_POINT; /// /// EFI_TCP4_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE DriverHandle; UINT32 ServiceCount; EFI_TCP4_SERVICE_POINT Services[1]; } EFI_TCP4_VARIABLE_DATA; typedef struct { BOOLEAN UseDefaultAddress; EFI_IPv4_ADDRESS StationAddress; EFI_IPv4_ADDRESS SubnetMask; UINT16 StationPort; EFI_IPv4_ADDRESS RemoteAddress; UINT16 RemotePort; BOOLEAN ActiveFlag; } EFI_TCP4_ACCESS_POINT; typedef struct { UINT32 ReceiveBufferSize; UINT32 SendBufferSize; UINT32 MaxSynBackLog; UINT32 ConnectionTimeout; UINT32 DataRetries; UINT32 FinTimeout; UINT32 TimeWaitTimeout; UINT32 KeepAliveProbes; UINT32 KeepAliveTime; UINT32 KeepAliveInterval; BOOLEAN EnableNagle; BOOLEAN EnableTimeStamp; BOOLEAN EnableWindowScaling; BOOLEAN EnableSelectiveAck; BOOLEAN EnablePathMtuDiscovery; } EFI_TCP4_OPTION; typedef struct { // // I/O parameters // UINT8 TypeOfService; UINT8 TimeToLive; // // Access Point // EFI_TCP4_ACCESS_POINT AccessPoint; // // TCP Control Options // EFI_TCP4_OPTION *ControlOption; } EFI_TCP4_CONFIG_DATA; /// /// TCP4 connnection state /// typedef enum { Tcp4StateClosed = 0, Tcp4StateListen = 1, Tcp4StateSynSent = 2, Tcp4StateSynReceived = 3, Tcp4StateEstablished = 4, Tcp4StateFinWait1 = 5, Tcp4StateFinWait2 = 6, Tcp4StateClosing = 7, Tcp4StateTimeWait = 8, Tcp4StateCloseWait = 9, Tcp4StateLastAck = 10 } EFI_TCP4_CONNECTION_STATE; typedef struct { EFI_EVENT Event; EFI_STATUS Status; } EFI_TCP4_COMPLETION_TOKEN; typedef struct { /// /// The Status in the CompletionToken will be set to one of /// the following values if the active open succeeds or an unexpected /// error happens: /// EFI_SUCCESS: The active open succeeds and the instance's /// state is Tcp4StateEstablished. /// EFI_CONNECTION_RESET: The connect fails because the connection is reset /// either by instance itself or the communication peer. /// EFI_CONNECTION_REFUSED: The connect fails because this connection is initiated with /// an active open and the connection is refused. /// EFI_ABORTED: The active open is aborted. /// EFI_TIMEOUT: The connection establishment timer expires and /// no more specific information is available. /// EFI_NETWORK_UNREACHABLE: The active open fails because /// an ICMP network unreachable error is received. /// EFI_HOST_UNREACHABLE: The active open fails because an /// ICMP host unreachable error is received. /// EFI_PROTOCOL_UNREACHABLE: The active open fails /// because an ICMP protocol unreachable error is received. /// EFI_PORT_UNREACHABLE: The connection establishment /// timer times out and an ICMP port unreachable error is received. /// EFI_ICMP_ERROR: The connection establishment timer timeout and some other ICMP /// error is received. /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. /// EFI_NO_MEDIA: There was a media error. /// EFI_TCP4_COMPLETION_TOKEN CompletionToken; } EFI_TCP4_CONNECTION_TOKEN; typedef struct { EFI_TCP4_COMPLETION_TOKEN CompletionToken; EFI_HANDLE NewChildHandle; } EFI_TCP4_LISTEN_TOKEN; typedef struct { UINT32 FragmentLength; VOID *FragmentBuffer; } EFI_TCP4_FRAGMENT_DATA; typedef struct { BOOLEAN UrgentFlag; UINT32 DataLength; UINT32 FragmentCount; EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; } EFI_TCP4_RECEIVE_DATA; typedef struct { BOOLEAN Push; BOOLEAN Urgent; UINT32 DataLength; UINT32 FragmentCount; EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; } EFI_TCP4_TRANSMIT_DATA; typedef struct { /// /// When transmission finishes or meets any unexpected error it will /// be set to one of the following values: /// EFI_SUCCESS: The receiving or transmission operation /// completes successfully. /// EFI_CONNECTION_FIN: The receiving operation fails because the communication peer /// has closed the connection and there is no more data in the /// receive buffer of the instance. /// EFI_CONNECTION_RESET: The receiving or transmission operation fails /// because this connection is reset either by instance /// itself or the communication peer. /// EFI_ABORTED: The receiving or transmission is aborted. /// EFI_TIMEOUT: The transmission timer expires and no more /// specific information is available. /// EFI_NETWORK_UNREACHABLE: The transmission fails /// because an ICMP network unreachable error is received. /// EFI_HOST_UNREACHABLE: The transmission fails because an /// ICMP host unreachable error is received. /// EFI_PROTOCOL_UNREACHABLE: The transmission fails /// because an ICMP protocol unreachable error is received. /// EFI_PORT_UNREACHABLE: The transmission fails and an /// ICMP port unreachable error is received. /// EFI_ICMP_ERROR: The transmission fails and some other /// ICMP error is received. /// EFI_DEVICE_ERROR: An unexpected system or network error occurs. /// EFI_NO_MEDIA: There was a media error. /// EFI_TCP4_COMPLETION_TOKEN CompletionToken; union { /// /// When this token is used for receiving, RxData is a pointer to EFI_TCP4_RECEIVE_DATA. /// EFI_TCP4_RECEIVE_DATA *RxData; /// /// When this token is used for transmitting, TxData is a pointer to EFI_TCP4_TRANSMIT_DATA. /// EFI_TCP4_TRANSMIT_DATA *TxData; } Packet; } EFI_TCP4_IO_TOKEN; typedef struct { EFI_TCP4_COMPLETION_TOKEN CompletionToken; BOOLEAN AbortOnClose; } EFI_TCP4_CLOSE_TOKEN; // // Interface definition for TCP4 protocol // /** Get the current operational status. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param Tcp4State The pointer to the buffer to receive the current TCP state. @param Tcp4ConfigData The pointer to the buffer to receive the current TCP configuration. @param Ip4ModeData The pointer to the buffer to receive the current IPv4 configuration data used by the TCPv4 instance. @param MnpConfigData The pointer to the buffer to receive the current MNP configuration data used indirectly by the TCPv4 instance. @param SnpModeData The pointer to the buffer to receive the current SNP configuration data used indirectly by the TCPv4 instance. @retval EFI_SUCCESS The mode data was read. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't been started. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_GET_MODE_DATA)( IN EFI_TCP4_PROTOCOL *This, OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL, OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL, OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Initialize or brutally reset the operational parameters for this EFI TCPv4 instance. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param Tcp4ConfigData The pointer to the configure data to configure the instance. @retval EFI_SUCCESS The operational settings are set, changed, or reset successfully. @retval EFI_INVALID_PARAMETER Some parameter is invalid. @retval EFI_NO_MAPPING When using a default address, configuration (through DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_ACCESS_DENIED Configuring TCP instance when it is configured without calling Configure() with NULL to reset it. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. @retval EFI_UNSUPPORTED One or more of the control options are not supported in the implementation. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when executing Configure(). **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_CONFIGURE)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL ); /** Add or delete a route entry to the route table @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param DeleteRoute Set it to TRUE to delete this route from the routing table. Set it to FALSE to add this route to the routing table. DestinationAddress and SubnetMask are used as the keywords to search route entry. @param SubnetAddress The destination network. @param SubnetMask The subnet mask of the destination network. @param GatewayAddress The gateway address for this route. It must be on the same subnet with the station address unless a direct route is specified. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The EFI TCPv4 Protocol instance has not been configured. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - SubnetAddress is NULL. - SubnetMask is NULL. - GatewayAddress is NULL. - *SubnetAddress is not NULL a valid subnet address. - *SubnetMask is not a valid subnet mask. - *GatewayAddress is not a valid unicast IP address or it is not in the same subnet. @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the entry to the routing table. @retval EFI_NOT_FOUND This route is not in the routing table. @retval EFI_ACCESS_DENIED The route is already defined in the routing table. @retval EFI_UNSUPPORTED The TCP driver does not support this operation. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_ROUTES)( IN EFI_TCP4_PROTOCOL *This, IN BOOLEAN DeleteRoute, IN EFI_IPv4_ADDRESS *SubnetAddress, IN EFI_IPv4_ADDRESS *SubnetMask, IN EFI_IPv4_ADDRESS *GatewayAddress ); /** Initiate a nonblocking TCP connection request for an active TCP instance. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param ConnectionToken The pointer to the connection token to return when the TCP three way handshake finishes. @retval EFI_SUCCESS The connection request is successfully initiated and the state of this TCPv4 instance has been changed to Tcp4StateSynSent. @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: - This instance is not configured as an active one. - This instance is not in Tcp4StateClosed state. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - ConnectionToken is NULL. - ConnectionToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to initiate the activ eopen. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_CONNECT)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken ); /** Listen on the passive instance to accept an incoming connection request. This is a nonblocking operation. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param ListenToken The pointer to the listen token to return when operation finishes. @retval EFI_SUCCESS The listen token has been queued successfully. @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following are TRUE: - This instance is not a passive instance. - This instance is not in Tcp4StateListen state. - The same listen token has already existed in the listen token queue of this TCP instance. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - ListenToken is NULL. - ListentToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_ACCEPT)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_LISTEN_TOKEN *ListenToken ); /** Queues outgoing data into the transmit queue. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param Token The pointer to the completion token to queue to the transmit queue. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - Token is NULL. - Token->CompletionToken.Event is NULL. - Token->Packet.TxData is NULL L. - Token->Packet.FragmentCount is zero. - Token->Packet.DataLength is not equal to the sum of fragment lengths. @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: - A transmit completion token with the same Token->CompletionToken.Event was already in the transmission queue. - The current instance is in Tcp4StateClosed state. - The current instance is a passive one and it is in Tcp4StateListen state. - User has called Close() to disconnect this connection. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of resource shortage. @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_TRANSMIT)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_IO_TOKEN *Token ); /** Places an asynchronous receive request into the receiving queue. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param Token The pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token->CompletionToken.Event is NULL. - Token->Packet.RxData is NULL. - Token->Packet.RxData->DataLength is 0. - The Token->Packet.RxData->DataLength is not the sum of all FragmentBuffer length in FragmentTable. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: - A receive completion token with the same Token- >CompletionToken.Event was already in the receive queue. - The current instance is in Tcp4StateClosed state. - The current instance is a passive one and it is in Tcp4StateListen state. - User has called Close() to disconnect this connection. @retval EFI_CONNECTION_FIN The communication peer has closed the connection and there is no any buffered data in the receive buffer of this instance. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_RECEIVE)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_IO_TOKEN *Token ); /** Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a nonblocking operation. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param CloseToken The pointer to the close token to return when operation finishes. @retval EFI_SUCCESS The Close() is called successfully. @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following are TRUE: - Configure() has been called with TcpConfigData set to NULL and this function has not returned. - Previous Close() call on this instance has not finished. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - CloseToken is NULL. - CloseToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_CLOSE)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_CLOSE_TOKEN *CloseToken ); /** Abort an asynchronous connection, listen, transmission or receive request. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @param Token The pointer to a token that has been issued by EFI_TCP4_PROTOCOL.Connect(), EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending tokens issued by above four functions will be aborted. Type EFI_TCP4_COMPLETION_TOKEN is defined in EFI_TCP4_PROTOCOL.Connect(). @retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event is signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance hasn't been configured. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP,RARP, etc.) hasn't finished yet. @retval EFI_NOT_FOUND The asynchronous I/O request isn't found in the transmission or receive queue. It has either completed or wasn't issued by Transmit() and Receive(). @retval EFI_UNSUPPORTED The implementation does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_CANCEL)( IN EFI_TCP4_PROTOCOL *This, IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL ); /** Poll to receive incoming data and transmit outgoing segments. @param This The pointer to the EFI_TCP4_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY No incoming or outgoing data is processed. @retval EFI_TIMEOUT Data was dropped out of the transmission or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP4_POLL)( IN EFI_TCP4_PROTOCOL *This ); /// /// The EFI_TCP4_PROTOCOL defines the EFI TCPv4 Protocol child to be used by /// any network drivers or applications to send or receive data stream. /// It can either listen on a specified port as a service or actively connected /// to remote peer as a client. Each instance has its own independent settings, /// such as the routing table. /// struct _EFI_TCP4_PROTOCOL { EFI_TCP4_GET_MODE_DATA GetModeData; EFI_TCP4_CONFIGURE Configure; EFI_TCP4_ROUTES Routes; EFI_TCP4_CONNECT Connect; EFI_TCP4_ACCEPT Accept; EFI_TCP4_TRANSMIT Transmit; EFI_TCP4_RECEIVE Receive; EFI_TCP4_CLOSE Close; EFI_TCP4_CANCEL Cancel; EFI_TCP4_POLL Poll; }; extern EFI_GUID gEfiTcp4ServiceBindingProtocolGuid; extern EFI_GUID gEfiTcp4ProtocolGuid; #endif /** @file EFI TCPv6(Transmission Control Protocol version 6) Protocol Definition The EFI TCPv6 Service Binding Protocol is used to locate EFI TCPv6 Protocol drivers to create and destroy child of the driver to communicate with other host using TCP protocol. The EFI TCPv6 Protocol provides services to send and receive data stream. Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_TCP6_PROTOCOL_H__ #define __EFI_TCP6_PROTOCOL_H__ #include #include #define EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0x0d, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64 } \ } #define EFI_TCP6_PROTOCOL_GUID \ { \ 0x46e44855, 0xbd60, 0x4ab7, {0xab, 0x0d, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77 } \ } typedef struct _EFI_TCP6_PROTOCOL EFI_TCP6_PROTOCOL; /// /// EFI_TCP6_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { /// /// The EFI TCPv6 Protocol instance handle that is using this /// address/port pair. /// EFI_HANDLE InstanceHandle; /// /// The local IPv6 address to which this TCP instance is bound. Set /// to 0::/128, if this TCP instance is configured to listen on all /// available source addresses. /// EFI_IPv6_ADDRESS LocalAddress; /// /// The local port number in host byte order. /// UINT16 LocalPort; /// /// The remote IPv6 address. It may be 0::/128 if this TCP instance is /// not connected to any remote host. /// EFI_IPv6_ADDRESS RemoteAddress; /// /// The remote port number in host byte order. It may be zero if this /// TCP instance is not connected to any remote host. /// UINT16 RemotePort; } EFI_TCP6_SERVICE_POINT; /// /// EFI_TCP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE DriverHandle; ///< The handle of the driver that creates this entry. UINT32 ServiceCount; ///< The number of address/port pairs following this data structure. EFI_TCP6_SERVICE_POINT Services[1]; ///< List of address/port pairs that are currently in use. } EFI_TCP6_VARIABLE_DATA; /// /// EFI_TCP6_ACCESS_POINT /// typedef struct { /// /// The local IP address assigned to this TCP instance. The EFI /// TCPv6 driver will only deliver incoming packets whose /// destination addresses exactly match the IP address. Set to zero to /// let the underlying IPv6 driver choose a source address. If not zero /// it must be one of the configured IP addresses in the underlying /// IPv6 driver. /// EFI_IPv6_ADDRESS StationAddress; /// /// The local port number to which this EFI TCPv6 Protocol instance /// is bound. If the instance doesn't care the local port number, set /// StationPort to zero to use an ephemeral port. /// UINT16 StationPort; /// /// The remote IP address to which this EFI TCPv6 Protocol instance /// is connected. If ActiveFlag is FALSE (i.e. a passive TCPv6 /// instance), the instance only accepts connections from the /// RemoteAddress. If ActiveFlag is TRUE the instance will /// connect to the RemoteAddress, i.e., outgoing segments will be /// sent to this address and only segments from this address will be /// delivered to the application. When ActiveFlag is FALSE, it /// can be set to zero and means that incoming connection requests /// from any address will be accepted. /// EFI_IPv6_ADDRESS RemoteAddress; /// /// The remote port to which this EFI TCPv6 Protocol instance /// connects or from which connection request will be accepted by /// this EFI TCPv6 Protocol instance. If ActiveFlag is FALSE it /// can be zero and means that incoming connection request from /// any port will be accepted. Its value can not be zero when /// ActiveFlag is TRUE. /// UINT16 RemotePort; /// /// Set it to TRUE to initiate an active open. Set it to FALSE to /// initiate a passive open to act as a server. /// BOOLEAN ActiveFlag; } EFI_TCP6_ACCESS_POINT; /// /// EFI_TCP6_OPTION /// typedef struct { /// /// The size of the TCP receive buffer. /// UINT32 ReceiveBufferSize; /// /// The size of the TCP send buffer. /// UINT32 SendBufferSize; /// /// The length of incoming connect request queue for a passive /// instance. When set to zero, the value is implementation specific. /// UINT32 MaxSynBackLog; /// /// The maximum seconds a TCP instance will wait for before a TCP /// connection established. When set to zero, the value is /// implementation specific. /// UINT32 ConnectionTimeout; /// /// The number of times TCP will attempt to retransmit a packet on /// an established connection. When set to zero, the value is /// implementation specific. /// UINT32 DataRetries; /// /// How many seconds to wait in the FIN_WAIT_2 states for a final /// FIN flag before the TCP instance is closed. This timeout is in /// effective only if the application has called Close() to /// disconnect the connection completely. It is also called /// FIN_WAIT_2 timer in other implementations. When set to zero, /// it should be disabled because the FIN_WAIT_2 timer itself is /// against the standard. The default value is 60. /// UINT32 FinTimeout; /// /// How many seconds to wait in TIME_WAIT state before the TCP /// instance is closed. The timer is disabled completely to provide a /// method to close the TCP connection quickly if it is set to zero. It /// is against the related RFC documents. /// UINT32 TimeWaitTimeout; /// /// The maximum number of TCP keep-alive probes to send before /// giving up and resetting the connection if no response from the /// other end. Set to zero to disable keep-alive probe. /// UINT32 KeepAliveProbes; /// /// The number of seconds a connection needs to be idle before TCP /// sends out periodical keep-alive probes. When set to zero, the /// value is implementation specific. It should be ignored if keep- /// alive probe is disabled. /// UINT32 KeepAliveTime; /// /// The number of seconds between TCP keep-alive probes after the /// periodical keep-alive probe if no response. When set to zero, the /// value is implementation specific. It should be ignored if keep- /// alive probe is disabled. /// UINT32 KeepAliveInterval; /// /// Set it to TRUE to enable the Nagle algorithm as defined in /// RFC896. Set it to FALSE to disable it. /// BOOLEAN EnableNagle; /// /// Set it to TRUE to enable TCP timestamps option as defined in /// RFC1323. Set to FALSE to disable it. /// BOOLEAN EnableTimeStamp; /// /// Set it to TRUE to enable TCP window scale option as defined in /// RFC1323. Set it to FALSE to disable it. /// BOOLEAN EnableWindowScaling; /// /// Set it to TRUE to enable selective acknowledge mechanism /// described in RFC 2018. Set it to FALSE to disable it. /// Implementation that supports SACK can optionally support /// DSAK as defined in RFC 2883. /// BOOLEAN EnableSelectiveAck; /// /// Set it to TRUE to enable path MTU discovery as defined in /// RFC 1191. Set to FALSE to disable it. /// BOOLEAN EnablePathMtuDiscovery; } EFI_TCP6_OPTION; /// /// EFI_TCP6_CONFIG_DATA /// typedef struct { /// /// TrafficClass field in transmitted IPv6 packets. /// UINT8 TrafficClass; /// /// HopLimit field in transmitted IPv6 packets. /// UINT8 HopLimit; /// /// Used to specify TCP communication end settings for a TCP instance. /// EFI_TCP6_ACCESS_POINT AccessPoint; /// /// Used to configure the advance TCP option for a connection. If set /// to NULL, implementation specific options for TCP connection will be used. /// EFI_TCP6_OPTION *ControlOption; } EFI_TCP6_CONFIG_DATA; /// /// EFI_TCP6_CONNECTION_STATE /// typedef enum { Tcp6StateClosed = 0, Tcp6StateListen = 1, Tcp6StateSynSent = 2, Tcp6StateSynReceived = 3, Tcp6StateEstablished = 4, Tcp6StateFinWait1 = 5, Tcp6StateFinWait2 = 6, Tcp6StateClosing = 7, Tcp6StateTimeWait = 8, Tcp6StateCloseWait = 9, Tcp6StateLastAck = 10 } EFI_TCP6_CONNECTION_STATE; /// /// EFI_TCP6_COMPLETION_TOKEN /// is used as a common header for various asynchronous tokens. /// typedef struct { /// /// The Event to signal after request is finished and Status field is /// updated by the EFI TCPv6 Protocol driver. /// EFI_EVENT Event; /// /// The result of the completed operation. /// EFI_STATUS Status; } EFI_TCP6_COMPLETION_TOKEN; /// /// EFI_TCP6_CONNECTION_TOKEN /// will be set if the active open succeeds or an unexpected /// error happens. /// typedef struct { /// /// The Status in the CompletionToken will be set to one of /// the following values if the active open succeeds or an unexpected /// error happens: /// EFI_SUCCESS: The active open succeeds and the instance's /// state is Tcp6StateEstablished. /// EFI_CONNECTION_RESET: The connect fails because the connection is reset /// either by instance itself or the communication peer. /// EFI_CONNECTION_REFUSED: The receiving or transmission operation fails because this /// connection is refused. /// EFI_ABORTED: The active open is aborted. /// EFI_TIMEOUT: The connection establishment timer expires and /// no more specific information is available. /// EFI_NETWORK_UNREACHABLE: The active open fails because /// an ICMP network unreachable error is received. /// EFI_HOST_UNREACHABLE: The active open fails because an /// ICMP host unreachable error is received. /// EFI_PROTOCOL_UNREACHABLE: The active open fails /// because an ICMP protocol unreachable error is received. /// EFI_PORT_UNREACHABLE: The connection establishment /// timer times out and an ICMP port unreachable error is received. /// EFI_ICMP_ERROR: The connection establishment timer times /// out and some other ICMP error is received. /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. /// EFI_SECURITY_VIOLATION: The active open was failed because of IPSec policy check. /// EFI_NO_MEDIA: There was a media error. /// EFI_TCP6_COMPLETION_TOKEN CompletionToken; } EFI_TCP6_CONNECTION_TOKEN; /// /// EFI_TCP6_LISTEN_TOKEN /// returns when list operation finishes. /// typedef struct { /// /// The Status in CompletionToken will be set to the /// following value if accept finishes: /// EFI_SUCCESS: A remote peer has successfully established a /// connection to this instance. A new TCP instance has also been /// created for the connection. /// EFI_CONNECTION_RESET: The accept fails because the connection is reset either /// by instance itself or communication peer. /// EFI_ABORTED: The accept request has been aborted. /// EFI_SECURITY_VIOLATION: The accept operation was failed because of IPSec policy check. /// EFI_TCP6_COMPLETION_TOKEN CompletionToken; EFI_HANDLE NewChildHandle; } EFI_TCP6_LISTEN_TOKEN; /// /// EFI_TCP6_FRAGMENT_DATA /// allows multiple receive or transmit buffers to be specified. The /// purpose of this structure is to provide scattered read and write. /// typedef struct { UINT32 FragmentLength; ///< Length of data buffer in the fragment. VOID *FragmentBuffer; ///< Pointer to the data buffer in the fragment. } EFI_TCP6_FRAGMENT_DATA; /// /// EFI_TCP6_RECEIVE_DATA /// When TCPv6 driver wants to deliver received data to the application, /// it will pick up the first queued receiving token, update its /// Token->Packet.RxData then signal the Token->CompletionToken.Event. /// typedef struct { /// /// Whether the data is urgent. When this flag is set, the instance is in /// urgent mode. /// BOOLEAN UrgentFlag; /// /// When calling Receive() function, it is the byte counts of all /// Fragmentbuffer in FragmentTable allocated by user. /// When the token is signaled by TCPv6 driver it is the length of /// received data in the fragments. /// UINT32 DataLength; /// /// Number of fragments. /// UINT32 FragmentCount; /// /// An array of fragment descriptors. /// EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; } EFI_TCP6_RECEIVE_DATA; /// /// EFI_TCP6_TRANSMIT_DATA /// The EFI TCPv6 Protocol user must fill this data structure before sending a packet. /// The packet may contain multiple buffers in non-continuous memory locations. /// typedef struct { /// /// Push If TRUE, data must be transmitted promptly, and the PUSH bit in /// the last TCP segment created will be set. If FALSE, data /// transmission may be delayed to combine with data from /// subsequent Transmit()s for efficiency. /// BOOLEAN Push; /// /// The data in the fragment table are urgent and urgent point is in /// effect if TRUE. Otherwise those data are NOT considered urgent. /// BOOLEAN Urgent; /// /// Length of the data in the fragments. /// UINT32 DataLength; /// /// Number of fragments. /// UINT32 FragmentCount; /// /// An array of fragment descriptors. /// EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; } EFI_TCP6_TRANSMIT_DATA; /// /// EFI_TCP6_IO_TOKEN /// returns When transmission finishes or meets any unexpected error. /// typedef struct { /// /// When transmission finishes or meets any unexpected error it will /// be set to one of the following values: /// EFI_SUCCESS: The receiving or transmission operation /// completes successfully. /// EFI_CONNECTION_FIN: The receiving operation fails because the communication peer /// has closed the connection and there is no more data in the /// receive buffer of the instance. /// EFI_CONNECTION_RESET: The receiving or transmission operation fails /// because this connection is reset either by instance /// itself or the communication peer. /// EFI_ABORTED: The receiving or transmission is aborted. /// EFI_TIMEOUT: The transmission timer expires and no more /// specific information is available. /// EFI_NETWORK_UNREACHABLE: The transmission fails /// because an ICMP network unreachable error is received. /// EFI_HOST_UNREACHABLE: The transmission fails because an /// ICMP host unreachable error is received. /// EFI_PROTOCOL_UNREACHABLE: The transmission fails /// because an ICMP protocol unreachable error is received. /// EFI_PORT_UNREACHABLE: The transmission fails and an /// ICMP port unreachable error is received. /// EFI_ICMP_ERROR: The transmission fails and some other /// ICMP error is received. /// EFI_DEVICE_ERROR: An unexpected system or network error occurs. /// EFI_SECURITY_VIOLATION: The receiving or transmission /// operation was failed because of IPSec policy check /// EFI_NO_MEDIA: There was a media error. /// EFI_TCP6_COMPLETION_TOKEN CompletionToken; union { /// /// When this token is used for receiving, RxData is a pointer to /// EFI_TCP6_RECEIVE_DATA. /// EFI_TCP6_RECEIVE_DATA *RxData; /// /// When this token is used for transmitting, TxData is a pointer to /// EFI_TCP6_TRANSMIT_DATA. /// EFI_TCP6_TRANSMIT_DATA *TxData; } Packet; } EFI_TCP6_IO_TOKEN; /// /// EFI_TCP6_CLOSE_TOKEN /// returns when close operation finishes. /// typedef struct { /// /// When close finishes or meets any unexpected error it will be set /// to one of the following values: /// EFI_SUCCESS: The close operation completes successfully. /// EFI_ABORTED: User called configure with NULL without close stopping. /// EFI_SECURITY_VIOLATION: The close operation was failed because of IPSec policy check. /// EFI_TCP6_COMPLETION_TOKEN CompletionToken; /// /// Abort the TCP connection on close instead of the standard TCP /// close process when it is set to TRUE. This option can be used to /// satisfy a fast disconnect. /// BOOLEAN AbortOnClose; } EFI_TCP6_CLOSE_TOKEN; /** Get the current operational status. The GetModeData() function copies the current operational settings of this EFI TCPv6 Protocol instance into user-supplied buffers. This function can also be used to retrieve the operational setting of underlying drivers such as IPv6, MNP, or SNP. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[out] Tcp6State The buffer in which the current TCP state is returned. @param[out] Tcp6ConfigData The buffer in which the current TCP configuration is returned. @param[out] Ip6ModeData The buffer in which the current IPv6 configuration data used by the TCP instance is returned. @param[out] MnpConfigData The buffer in which the current MNP configuration data used indirectly by the TCP instance is returned. @param[out] SnpModeData The buffer in which the current SNP mode data used indirectly by the TCP instance is returned. @retval EFI_SUCCESS The mode data was read. @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't been started. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_GET_MODE_DATA)( IN EFI_TCP6_PROTOCOL *This, OUT EFI_TCP6_CONNECTION_STATE *Tcp6State OPTIONAL, OUT EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL, OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Initialize or brutally reset the operational parameters for this EFI TCPv6 instance. The Configure() function does the following: - Initialize this TCP instance, i.e., initialize the communication end settings and specify active open or passive open for an instance. - Reset this TCP instance brutally, i.e., cancel all pending asynchronous tokens, flush transmission and receiving buffer directly without informing the communication peer. No other TCPv6 Protocol operation except Poll() can be executed by this instance until it is configured properly. For an active TCP instance, after a proper configuration it may call Connect() to initiates the three-way handshake. For a passive TCP instance, its state will transit to Tcp6StateListen after configuration, and Accept() may be called to listen the incoming TCP connection requests. If Tcp6ConfigData is set to NULL, the instance is reset. Resetting process will be done brutally, the state machine will be set to Tcp6StateClosed directly, the receive queue and transmit queue will be flushed, and no traffic is allowed through this instance. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] Tcp6ConfigData Pointer to the configure data to configure the instance. If Tcp6ConfigData is set to NULL, the instance is reset. @retval EFI_SUCCESS The operational settings are set, changed, or reset successfully. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following conditions are TRUE: - This is NULL. - Tcp6ConfigData->AccessPoint.StationAddress is neither zero nor one of the configured IP addresses in the underlying IPv6 driver. - Tcp6ConfigData->AccessPoint.RemoteAddress isn't a valid unicast IPv6 address. - Tcp6ConfigData->AccessPoint.RemoteAddress is zero or Tcp6ConfigData->AccessPoint.RemotePort is zero when Tcp6ConfigData->AccessPoint.ActiveFlag is TRUE. - A same access point has been configured in other TCP instance properly. @retval EFI_ACCESS_DENIED Configuring TCP instance when it is configured without calling Configure() with NULL to reset it. @retval EFI_UNSUPPORTED One or more of the control options are not supported in the implementation. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when executing Configure(). @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_CONFIGURE)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL ); /** Initiate a nonblocking TCP connection request for an active TCP instance. The Connect() function will initiate an active open to the remote peer configured in current TCP instance if it is configured active. If the connection succeeds or fails due to any error, the ConnectionToken->CompletionToken.Event will be signaled and ConnectionToken->CompletionToken.Status will be updated accordingly. This function can only be called for the TCP instance in Tcp6StateClosed state. The instance will transfer into Tcp6StateSynSent if the function returns EFI_SUCCESS. If TCP three-way handshake succeeds, its state will become Tcp6StateEstablished, otherwise, the state will return to Tcp6StateClosed. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] ConnectionToken Pointer to the connection token to return when the TCP three way handshake finishes. @retval EFI_SUCCESS The connection request is successfully initiated and the state of this TCP instance has been changed to Tcp6StateSynSent. @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: - This instance is not configured as an active one. - This instance is not in Tcp6StateClosed state. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - ConnectionToken is NULL. - ConnectionToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to initiate the active open. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_CONNECT)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_CONNECTION_TOKEN *ConnectionToken ); /** Listen on the passive instance to accept an incoming connection request. This is a nonblocking operation. The Accept() function initiates an asynchronous accept request to wait for an incoming connection on the passive TCP instance. If a remote peer successfully establishes a connection with this instance, a new TCP instance will be created and its handle will be returned in ListenToken->NewChildHandle. The newly created instance is configured by inheriting the passive instance's configuration and is ready for use upon return. The new instance is in the Tcp6StateEstablished state. The ListenToken->CompletionToken.Event will be signaled when a new connection is accepted, user aborts the listen or connection is reset. This function only can be called when current TCP instance is in Tcp6StateListen state. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] ListenToken Pointer to the listen token to return when operation finishes. @retval EFI_SUCCESS The listen token has been queued successfully. @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following are TRUE: - This instance is not a passive instance. - This instance is not in Tcp6StateListen state. - The same listen token has already existed in the listen token queue of this TCP instance. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - ListenToken is NULL. - ListentToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_ACCEPT)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_LISTEN_TOKEN *ListenToken ); /** Queues outgoing data into the transmit queue. The Transmit() function queues a sending request to this TCP instance along with the user data. The status of the token is updated and the event in the token will be signaled once the data is sent out or some error occurs. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] Token Pointer to the completion token to queue to the transmit queue. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - Token is NULL. - Token->CompletionToken.Event is NULL. - Token->Packet.TxData is NULL. - Token->Packet.FragmentCount is zero. - Token->Packet.DataLength is not equal to the sum of fragment lengths. @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: - A transmit completion token with the same Token-> CompletionToken.Event was already in the transmission queue. - The current instance is in Tcp6StateClosed state. - The current instance is a passive one and it is in Tcp6StateListen state. - User has called Close() to disconnect this connection. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of resource shortage. @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_TRANSMIT)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_IO_TOKEN *Token ); /** Places an asynchronous receive request into the receiving queue. The Receive() function places a completion token into the receive packet queue. This function is always asynchronous. The caller must allocate the Token->CompletionToken.Event and the FragmentBuffer used to receive data. The caller also must fill the DataLength which represents the whole length of all FragmentBuffer. When the receive operation completes, the EFI TCPv6 Protocol driver updates the Token->CompletionToken.Status and Token->Packet.RxData fields and the Token->CompletionToken.Event is signaled. If got data the data and its length will be copied into the FragmentTable, at the same time the full length of received data will be recorded in the DataLength fields. Providing a proper notification function and context for the event will enable the user to receive the notification and receiving status. That notification function is guaranteed to not be re-entered. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] Token Pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Token is NULL. - Token->CompletionToken.Event is NULL. - Token->Packet.RxData is NULL. - Token->Packet.RxData->DataLength is 0. - The Token->Packet.RxData->DataLength is not the sum of all FragmentBuffer length in FragmentTable. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI TCPv6 Protocol instance has been reset to startup defaults. @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: - A receive completion token with the same Token->CompletionToken.Event was already in the receive queue. - The current instance is in Tcp6StateClosed state. - The current instance is a passive one and it is in Tcp6StateListen state. - User has called Close() to disconnect this connection. @retval EFI_CONNECTION_FIN The communication peer has closed the connection and there is no any buffered data in the receive buffer of this instance @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_RECEIVE)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_IO_TOKEN *Token ); /** Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a nonblocking operation. Initiate an asynchronous close token to TCP driver. After Close() is called, any buffered transmission data will be sent by TCP driver and the current instance will have a graceful close working flow described as RFC 793 if AbortOnClose is set to FALSE, otherwise, a rest packet will be sent by TCP driver to fast disconnect this connection. When the close operation completes successfully the TCP instance is in Tcp6StateClosed state, all pending asynchronous operations are signaled and any buffers used for TCP network traffic are flushed. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] CloseToken Pointer to the close token to return when operation finishes. @retval EFI_SUCCESS The Close() is called successfully. @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. @retval EFI_ACCESS_DENIED One or more of the following are TRUE: - CloseToken or CloseToken->CompletionToken.Event is already in use. - Previous Close() call on this instance has not finished. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - CloseToken is NULL. - CloseToken->CompletionToken.Event is NULL. @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_CLOSE)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_CLOSE_TOKEN *CloseToken ); /** Abort an asynchronous connection, listen, transmission or receive request. The Cancel() function aborts a pending connection, listen, transmit or receive request. If Token is not NULL and the token is in the connection, listen, transmission or receive queue when it is being cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will be signaled. If the token is not in one of the queues, which usually means that the asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL all asynchronous token issued by Connect(), Accept(), Transmit() and Receive() will be aborted. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @param[in] Token Pointer to a token that has been issued by EFI_TCP6_PROTOCOL.Connect(), EFI_TCP6_PROTOCOL.Accept(), EFI_TCP6_PROTOCOL.Transmit() or EFI_TCP6_PROTOCOL.Receive(). If NULL, all pending tokens issued by above four functions will be aborted. Type EFI_TCP6_COMPLETION_TOKEN is defined in EFI_TCP_PROTOCOL.Connect(). @retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event is signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance hasn't been configured. @retval EFI_NOT_FOUND The asynchronous I/O request isn't found in the transmission or receive queue. It has either completed or wasn't issued by Transmit() and Receive(). @retval EFI_UNSUPPORTED The implementation does not support this function. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_CANCEL)( IN EFI_TCP6_PROTOCOL *This, IN EFI_TCP6_COMPLETION_TOKEN *Token OPTIONAL ); /** Poll to receive incoming data and transmit outgoing segments. The Poll() function increases the rate that data is moved between the network and application and can be called when the TCP instance is created successfully. Its use is optional. @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NOT_READY No incoming or outgoing data is processed. @retval EFI_TIMEOUT Data was dropped out of the transmission or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_TCP6_POLL)( IN EFI_TCP6_PROTOCOL *This ); /// /// EFI_TCP6_PROTOCOL /// defines the EFI TCPv6 Protocol child to be used by any network drivers or /// applications to send or receive data stream. It can either listen on a /// specified port as a service or actively connect to remote peer as a client. /// Each instance has its own independent settings. /// struct _EFI_TCP6_PROTOCOL { EFI_TCP6_GET_MODE_DATA GetModeData; EFI_TCP6_CONFIGURE Configure; EFI_TCP6_CONNECT Connect; EFI_TCP6_ACCEPT Accept; EFI_TCP6_TRANSMIT Transmit; EFI_TCP6_RECEIVE Receive; EFI_TCP6_CLOSE Close; EFI_TCP6_CANCEL Cancel; EFI_TCP6_POLL Poll; }; extern EFI_GUID gEfiTcp6ServiceBindingProtocolGuid; extern EFI_GUID gEfiTcp6ProtocolGuid; #endif /** @file Timer Architectural Protocol as defined in PI Specification VOLUME 2 DXE This code is used to provide the timer tick for the DXE core. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_TIMER_H__ #define __ARCH_PROTOCOL_TIMER_H__ /// /// Global ID for the Timer Architectural Protocol /// #define EFI_TIMER_ARCH_PROTOCOL_GUID \ { 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } /// /// Declare forward reference for the Timer Architectural Protocol /// typedef struct _EFI_TIMER_ARCH_PROTOCOL EFI_TIMER_ARCH_PROTOCOL; /** This function of this type is called when a timer interrupt fires. This function executes at TPL_HIGH_LEVEL. The DXE Core will register a function of this type to be called for the timer interrupt, so it can know how much time has passed. This information is used to signal timer based events. @param Time Time since the last timer interrupt in 100 ns units. This will typically be TimerPeriod, but if a timer interrupt is missed, and the EFI_TIMER_ARCH_PROTOCOL driver can detect missed interrupts, then Time will contain the actual amount of time since the last interrupt. None. **/ typedef VOID (EFIAPI *EFI_TIMER_NOTIFY)( IN UINT64 Time ); /** This function registers the handler NotifyFunction so it is called every time the timer interrupt fires. It also passes the amount of time since the last handler call to the NotifyFunction. If NotifyFunction is NULL, then the handler is unregistered. If the handler is registered, then EFI_SUCCESS is returned. If the CPU does not support registering a timer interrupt handler, then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler when a handler is already registered, then EFI_ALREADY_STARTED is returned. If an attempt is made to unregister a handler when a handler is not registered, then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR is returned. @param This The EFI_TIMER_ARCH_PROTOCOL instance. @param NotifyFunction The function to call when a timer interrupt fires. This function executes at TPL_HIGH_LEVEL. The DXE Core will register a handler for the timer interrupt, so it can know how much time has passed. This information is used to signal timer based events. NULL will unregister the handler. @retval EFI_SUCCESS The timer handler was registered. @retval EFI_UNSUPPORTED The platform does not support timer interrupts. @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered. @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered. @retval EFI_DEVICE_ERROR The timer handler could not be registered. **/ typedef EFI_STATUS (EFIAPI *EFI_TIMER_REGISTER_HANDLER)( IN EFI_TIMER_ARCH_PROTOCOL *This, IN EFI_TIMER_NOTIFY NotifyFunction ); /** This function adjusts the period of timer interrupts to the value specified by TimerPeriod. If the timer period is updated, then the selected timer period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. If an error occurs while attempting to update the timer period, then the timer hardware will be put back in its state prior to this call, and EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt is disabled. This is not the same as disabling the CPU's interrupts. Instead, it must either turn off the timer hardware, or it must adjust the interrupt controller so that a CPU interrupt is not generated when the timer interrupt fires. @param This The EFI_TIMER_ARCH_PROTOCOL instance. @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. If the timer is programmable, then the timer period will be rounded up to the nearest timer period that is supported by the timer hardware. If TimerPeriod is set to 0, then the timer interrupts will be disabled. @retval EFI_SUCCESS The timer period was changed. @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. **/ typedef EFI_STATUS (EFIAPI *EFI_TIMER_SET_TIMER_PERIOD)( IN EFI_TIMER_ARCH_PROTOCOL *This, IN UINT64 TimerPeriod ); /** This function retrieves the period of timer interrupts in 100 ns units, returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is returned, then the timer is currently disabled. @param This The EFI_TIMER_ARCH_PROTOCOL instance. @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If 0 is returned, then the timer is currently disabled. @retval EFI_SUCCESS The timer period was returned in TimerPeriod. @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_TIMER_GET_TIMER_PERIOD)( IN EFI_TIMER_ARCH_PROTOCOL *This, OUT UINT64 *TimerPeriod ); /** This function generates a soft timer interrupt. If the platform does not support soft timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() service, then a soft timer interrupt will be generated. If the timer interrupt is enabled when this service is called, then the registered handler will be invoked. The registered handler should not be able to distinguish a hardware-generated timer interrupt from a software-generated timer interrupt. @param This The EFI_TIMER_ARCH_PROTOCOL instance. @retval EFI_SUCCESS The soft timer interrupt was generated. @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts. **/ typedef EFI_STATUS (EFIAPI *EFI_TIMER_GENERATE_SOFT_INTERRUPT)( IN EFI_TIMER_ARCH_PROTOCOL *This ); /// /// This protocol provides the services to initialize a periodic timer /// interrupt, and to register a handler that is called each time the timer /// interrupt fires. It may also provide a service to adjust the rate of the /// periodic timer interrupt. When a timer interrupt occurs, the handler is /// passed the amount of time that has passed since the previous timer /// interrupt. /// struct _EFI_TIMER_ARCH_PROTOCOL { EFI_TIMER_REGISTER_HANDLER RegisterHandler; EFI_TIMER_SET_TIMER_PERIOD SetTimerPeriod; EFI_TIMER_GET_TIMER_PERIOD GetTimerPeriod; EFI_TIMER_GENERATE_SOFT_INTERRUPT GenerateSoftInterrupt; }; extern EFI_GUID gEfiTimerArchProtocolGuid; #endif /** @file UDP4 Service Binding Protocol as defined in UEFI specification. The EFI UDPv4 Protocol provides simple packet-oriented services to transmit and receive UDP packets. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.0. **/ #ifndef __EFI_UDP4_PROTOCOL_H__ #define __EFI_UDP4_PROTOCOL_H__ #include // // GUID definitions // #define EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x83f01464, 0x99bd, 0x45e5, {0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6 } \ } #define EFI_UDP4_PROTOCOL_GUID \ { \ 0x3ad9df29, 0x4501, 0x478d, {0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3 } \ } typedef struct _EFI_UDP4_PROTOCOL EFI_UDP4_PROTOCOL; /// /// EFI_UDP4_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE InstanceHandle; EFI_IPv4_ADDRESS LocalAddress; UINT16 LocalPort; EFI_IPv4_ADDRESS RemoteAddress; UINT16 RemotePort; } EFI_UDP4_SERVICE_POINT; /// /// EFI_UDP4_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { EFI_HANDLE DriverHandle; UINT32 ServiceCount; EFI_UDP4_SERVICE_POINT Services[1]; } EFI_UDP4_VARIABLE_DATA; typedef struct { UINT32 FragmentLength; VOID *FragmentBuffer; } EFI_UDP4_FRAGMENT_DATA; typedef struct { EFI_IPv4_ADDRESS SourceAddress; UINT16 SourcePort; EFI_IPv4_ADDRESS DestinationAddress; UINT16 DestinationPort; } EFI_UDP4_SESSION_DATA; typedef struct { // // Receiving Filters // BOOLEAN AcceptBroadcast; BOOLEAN AcceptPromiscuous; BOOLEAN AcceptAnyPort; BOOLEAN AllowDuplicatePort; // // I/O parameters // UINT8 TypeOfService; UINT8 TimeToLive; BOOLEAN DoNotFragment; UINT32 ReceiveTimeout; UINT32 TransmitTimeout; // // Access Point // BOOLEAN UseDefaultAddress; EFI_IPv4_ADDRESS StationAddress; EFI_IPv4_ADDRESS SubnetMask; UINT16 StationPort; EFI_IPv4_ADDRESS RemoteAddress; UINT16 RemotePort; } EFI_UDP4_CONFIG_DATA; typedef struct { EFI_UDP4_SESSION_DATA *UdpSessionData; // OPTIONAL EFI_IPv4_ADDRESS *GatewayAddress; // OPTIONAL UINT32 DataLength; UINT32 FragmentCount; EFI_UDP4_FRAGMENT_DATA FragmentTable[1]; } EFI_UDP4_TRANSMIT_DATA; typedef struct { EFI_TIME TimeStamp; EFI_EVENT RecycleSignal; EFI_UDP4_SESSION_DATA UdpSession; UINT32 DataLength; UINT32 FragmentCount; EFI_UDP4_FRAGMENT_DATA FragmentTable[1]; } EFI_UDP4_RECEIVE_DATA; typedef struct { EFI_EVENT Event; EFI_STATUS Status; union { EFI_UDP4_RECEIVE_DATA *RxData; EFI_UDP4_TRANSMIT_DATA *TxData; } Packet; } EFI_UDP4_COMPLETION_TOKEN; /** Reads the current operational settings. The GetModeData() function copies the current operational settings of this EFI UDPv4 Protocol instance into user-supplied buffers. This function is used optionally to retrieve the operational mode data of underlying networks or drivers. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param Udp4ConfigData The pointer to the buffer to receive the current configuration data. @param Ip4ModeData The pointer to the EFI IPv4 Protocol mode data structure. @param MnpConfigData The pointer to the managed network configuration data structure. @param SnpModeData The pointer to the simple network mode data structure. @retval EFI_SUCCESS The mode data was read. @retval EFI_NOT_STARTED When Udp4ConfigData is queried, no configuration data is available because this instance has not been started. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_GET_MODE_DATA)( IN EFI_UDP4_PROTOCOL *This, OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL, OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Initializes, changes, or resets the operational parameters for this instance of the EFI UDPv4 Protocol. The Configure() function is used to do the following: * Initialize and start this instance of the EFI UDPv4 Protocol. * Change the filtering rules and operational parameters. * Reset this instance of the EFI UDPv4 Protocol. Until these parameters are initialized, no network traffic can be sent or received by this instance. This instance can be also reset by calling Configure() with UdpConfigData set to NULL. Once reset, the receiving queue and transmitting queue are flushed and no traffic is allowed through this instance. With different parameters in UdpConfigData, Configure() can be used to bind this instance to specified port. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param Udp4ConfigData The pointer to the buffer to receive the current configuration data. @retval EFI_SUCCESS The configuration settings were set, changed, or reset successfully. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER UdpConfigData.StationAddress is not a valid unicast IPv4 address. @retval EFI_INVALID_PARAMETER UdpConfigData.SubnetMask is not a valid IPv4 address mask. The subnet mask must be contiguous. @retval EFI_INVALID_PARAMETER UdpConfigData.RemoteAddress is not a valid unicast IPv4 address if it is not zero. @retval EFI_ALREADY_STARTED The EFI UDPv4 Protocol instance is already started/configured and must be stopped/reset before it can be reconfigured. @retval EFI_ACCESS_DENIED UdpConfigData. AllowDuplicatePort is FALSE and UdpConfigData.StationPort is already used by other instance. @retval EFI_OUT_OF_RESOURCES The EFI UDPv4 Protocol driver cannot allocate memory for this EFI UDPv4 Protocol instance. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred and this instance was not opened. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_CONFIGURE)( IN EFI_UDP4_PROTOCOL *This, IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL ); /** Joins and leaves multicast groups. The Groups() function is used to enable and disable the multicast group filtering. If the JoinFlag is FALSE and the MulticastAddress is NULL, then all currently joined groups are left. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param JoinFlag Set to TRUE to join a multicast group. Set to FALSE to leave one or all multicast groups. @param MulticastAddress The pointer to multicast group address to join or leave. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The EFI UDPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_OUT_OF_RESOURCES Could not allocate resources to join the group. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - JoinFlag is TRUE and MulticastAddress is NULL. - JoinFlag is TRUE and *MulticastAddress is not a valid multicast address. @retval EFI_ALREADY_STARTED The group address is already in the group table (when JoinFlag is TRUE). @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_GROUPS)( IN EFI_UDP4_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_IPv4_ADDRESS *MulticastAddress OPTIONAL ); /** Adds and deletes routing table entries. The Routes() function adds a route to or deletes a route from the routing table. Routes are determined by comparing the SubnetAddress with the destination IP address and arithmetically AND-ing it with the SubnetMask. The gateway address must be on the same subnet as the configured station address. The default route is added with SubnetAddress and SubnetMask both set to 0.0.0.0. The default route matches all destination IP addresses that do not match any other routes. A zero GatewayAddress is a nonroute. Packets are sent to the destination IP address if it can be found in the Address Resolution Protocol (ARP) cache or on the local subnet. One automatic nonroute entry will be inserted into the routing table for outgoing packets that are addressed to a local subnet (gateway address of 0.0.0.0). Each instance of the EFI UDPv4 Protocol has its own independent routing table. Instances of the EFI UDPv4 Protocol that use the default IP address will also have copies of the routing table provided by the EFI_IP4_CONFIG_PROTOCOL. These copies will be updated automatically whenever the IP driver reconfigures its instances; as a result, the previous modification to these copies will be lost. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param DeleteRoute Set to TRUE to delete this route from the routing table. Set to FALSE to add this route to the routing table. @param SubnetAddress The destination network address that needs to be routed. @param SubnetMask The subnet mask of SubnetAddress. @param GatewayAddress The gateway IP address for this route. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The EFI UDPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, - RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table. @retval EFI_NOT_FOUND This route is not in the routing table. @retval EFI_ACCESS_DENIED The route is already defined in the routing table. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_ROUTES)( IN EFI_UDP4_PROTOCOL *This, IN BOOLEAN DeleteRoute, IN EFI_IPv4_ADDRESS *SubnetAddress, IN EFI_IPv4_ADDRESS *SubnetMask, IN EFI_IPv4_ADDRESS *GatewayAddress ); /** Polls for incoming data packets and processes outgoing data packets. The Poll() function can be used by network drivers and applications to increase the rate that data packets are moved between the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the Poll() function more often. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_POLL)( IN EFI_UDP4_PROTOCOL *This ); /** Places an asynchronous receive request into the receiving queue. The Receive() function places a completion token into the receive packet queue. This function is always asynchronous. The caller must fill in the Token.Event field in the completion token, and this field cannot be NULL. When the receive operation completes, the EFI UDPv4 Protocol driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event is signaled. Providing a proper notification function and context for the event will enable the user to receive the notification and receiving status. That notification function is guaranteed to not be re-entered. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param Token The pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI UDPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_INVALID_PARAMETER Token is NULL. @retval EFI_INVALID_PARAMETER Token.Event is NULL. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_ACCESS_DENIED A receive completion token with the same Token.Event was already in the receive queue. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_RECEIVE)( IN EFI_UDP4_PROTOCOL *This, IN EFI_UDP4_COMPLETION_TOKEN *Token ); /** Queues outgoing data packets into the transmit queue. The Transmit() function places a sending request to this instance of the EFI UDPv4 Protocol, alongside the transmit data that was filled by the user. Whenever the packet in the token is sent out or some errors occur, the Token.Event will be signaled and Token.Status is updated. Providing a proper notification function and context for the event will enable the user to receive the notification and transmitting status. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param Token The pointer to the completion token that will be placed into the transmit queue. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This EFI UDPv4 Protocol instance has not been started. @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event was already in the transmit queue. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. @retval EFI_NOT_FOUND There is no route to the destination network or address. @retval EFI_BAD_BUFFER_SIZE The data length is greater than the maximum UDP packet size. Or the length of the IP header + UDP header + data length is greater than MTU if DoNotFragment is TRUE. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_TRANSMIT)( IN EFI_UDP4_PROTOCOL *This, IN EFI_UDP4_COMPLETION_TOKEN *Token ); /** Aborts an asynchronous transmit or receive request. The Cancel() function is used to abort a pending transmit or receive request. If the token is in the transmit or receive request queues, after calling this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be signaled. If the token is not in one of the queues, which usually means that the asynchronous operation has completed, this function will not signal the token and EFI_NOT_FOUND is returned. @param This The pointer to the EFI_UDP4_PROTOCOL instance. @param Token The pointer to a token that has been issued by EFI_UDP4_PROTOCOL.Transmit() or EFI_UDP4_PROTOCOL.Receive().If NULL, all pending tokens are aborted. @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token.Event was signaled. When Token is NULL, all pending requests are aborted and their events are signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) is not finished yet. @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was not found in the transmit or receive queue. It has either completed or was not issued by Transmit() and Receive(). **/ typedef EFI_STATUS (EFIAPI *EFI_UDP4_CANCEL)( IN EFI_UDP4_PROTOCOL *This, IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL ); /// /// The EFI_UDP4_PROTOCOL defines an EFI UDPv4 Protocol session that can be used /// by any network drivers, applications, or daemons to transmit or receive UDP packets. /// This protocol instance can either be bound to a specified port as a service or /// connected to some remote peer as an active client. Each instance has its own settings, /// such as the routing table and group table, which are independent from each other. /// struct _EFI_UDP4_PROTOCOL { EFI_UDP4_GET_MODE_DATA GetModeData; EFI_UDP4_CONFIGURE Configure; EFI_UDP4_GROUPS Groups; EFI_UDP4_ROUTES Routes; EFI_UDP4_TRANSMIT Transmit; EFI_UDP4_RECEIVE Receive; EFI_UDP4_CANCEL Cancel; EFI_UDP4_POLL Poll; }; extern EFI_GUID gEfiUdp4ServiceBindingProtocolGuid; extern EFI_GUID gEfiUdp4ProtocolGuid; #endif /** @file The EFI UDPv6 (User Datagram Protocol version 6) Protocol Definition, which is built upon the EFI IPv6 Protocol and provides simple packet-oriented services to transmit and receive UDP packets. Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_UDP6_PROTOCOL_H__ #define __EFI_UDP6_PROTOCOL_H__ #include #define EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID \ { \ 0x66ed4721, 0x3c98, 0x4d3e, {0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 } \ } #define EFI_UDP6_PROTOCOL_GUID \ { \ 0x4f948815, 0xb4b9, 0x43cb, {0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 } \ } /// /// EFI_UDP6_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { /// /// The EFI UDPv6 Protocol instance handle that is using this address/port pair. /// EFI_HANDLE InstanceHandle; /// /// The IPv6 address to which this instance of the EFI UDPv6 Protocol is bound. /// Set to 0::/128, if this instance is used to listen all packets from any /// source address. /// EFI_IPv6_ADDRESS LocalAddress; /// /// The port number in host byte order on which the service is listening. /// UINT16 LocalPort; /// /// The IPv6 address of the remote host. May be 0::/128 if it is not connected /// to any remote host or connected with more than one remote host. /// EFI_IPv6_ADDRESS RemoteAddress; /// /// The port number in host byte order on which the remote host is /// listening. Maybe zero if it is not connected to any remote host. /// UINT16 RemotePort; } EFI_UDP6_SERVICE_POINT; /// /// EFI_UDP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. /// The definition in here is only present to provide backwards compatability. /// typedef struct { /// /// The handle of the driver that creates this entry. /// EFI_HANDLE DriverHandle; /// /// The number of address/port pairs that follow this data structure. /// UINT32 ServiceCount; /// /// List of address/port pairs that are currently in use. /// EFI_UDP6_SERVICE_POINT Services[1]; } EFI_UDP6_VARIABLE_DATA; typedef struct _EFI_UDP6_PROTOCOL EFI_UDP6_PROTOCOL; /// /// EFI_UDP6_FRAGMENT_DATA allows multiple receive or transmit buffers to be specified. /// The purpose of this structure is to avoid copying the same packet multiple times. /// typedef struct { UINT32 FragmentLength; ///< Length of the fragment data buffer. VOID *FragmentBuffer; ///< Pointer to the fragment data buffer. } EFI_UDP6_FRAGMENT_DATA; /// /// The EFI_UDP6_SESSION_DATA is used to retrieve the settings when receiving packets or /// to override the existing settings (only DestinationAddress and DestinationPort can /// be overridden) of this EFI UDPv6 Protocol instance when sending packets. /// typedef struct { /// /// Address from which this packet is sent. This field should not be used when /// sending packets. /// EFI_IPv6_ADDRESS SourceAddress; /// /// Port from which this packet is sent. It is in host byte order. This field should /// not be used when sending packets. /// UINT16 SourcePort; /// /// Address to which this packet is sent. When sending packet, it'll be ignored /// if it is zero. /// EFI_IPv6_ADDRESS DestinationAddress; /// /// Port to which this packet is sent. When sending packet, it'll be /// ignored if it is zero. /// UINT16 DestinationPort; } EFI_UDP6_SESSION_DATA; typedef struct { /// /// Set to TRUE to accept UDP packets that are sent to any address. /// BOOLEAN AcceptPromiscuous; /// /// Set to TRUE to accept UDP packets that are sent to any port. /// BOOLEAN AcceptAnyPort; /// /// Set to TRUE to allow this EFI UDPv6 Protocol child instance to open a port number /// that is already being used by another EFI UDPv6 Protocol child instance. /// BOOLEAN AllowDuplicatePort; /// /// TrafficClass field in transmitted IPv6 packets. /// UINT8 TrafficClass; /// /// HopLimit field in transmitted IPv6 packets. /// UINT8 HopLimit; /// /// The receive timeout value (number of microseconds) to be associated with each /// incoming packet. Zero means do not drop incoming packets. /// UINT32 ReceiveTimeout; /// /// The transmit timeout value (number of microseconds) to be associated with each /// outgoing packet. Zero means do not drop outgoing packets. /// UINT32 TransmitTimeout; /// /// The station IP address that will be assigned to this EFI UDPv6 Protocol instance. /// The EFI UDPv6 and EFI IPv6 Protocol drivers will only deliver incoming packets /// whose destination matches this IP address exactly. Address 0::/128 is also accepted /// as a special case. Under this situation, underlying IPv6 driver is responsible for /// binding a source address to this EFI IPv6 protocol instance according to source /// address selection algorithm. Only incoming packet from the selected source address /// is delivered. This field can be set and changed only when the EFI IPv6 driver is /// transitioning from the stopped to the started states. If no address is available /// for selecting, the EFI IPv6 Protocol driver will use EFI_IP6_CONFIG_PROTOCOL to /// retrieve the IPv6 address. EFI_IPv6_ADDRESS StationAddress; /// /// The port number to which this EFI UDPv6 Protocol instance is bound. If a client /// of the EFI UDPv6 Protocol does not care about the port number, set StationPort /// to zero. The EFI UDPv6 Protocol driver will assign a random port number to transmitted /// UDP packets. Ignored it if AcceptAnyPort is TRUE. /// UINT16 StationPort; /// /// The IP address of remote host to which this EFI UDPv6 Protocol instance is connecting. /// If RemoteAddress is not 0::/128, this EFI UDPv6 Protocol instance will be connected to /// RemoteAddress; i.e., outgoing packets of this EFI UDPv6 Protocol instance will be sent /// to this address by default and only incoming packets from this address will be delivered /// to client. Ignored for incoming filtering if AcceptPromiscuous is TRUE. EFI_IPv6_ADDRESS RemoteAddress; /// /// The port number of the remote host to which this EFI UDPv6 Protocol instance is connecting. /// If it is not zero, outgoing packets of this EFI UDPv6 Protocol instance will be sent to /// this port number by default and only incoming packets from this port will be delivered /// to client. Ignored if RemoteAddress is 0::/128 and ignored for incoming filtering if /// AcceptPromiscuous is TRUE. UINT16 RemotePort; } EFI_UDP6_CONFIG_DATA; /// /// The EFI UDPv6 Protocol client must fill this data structure before sending a packet. /// The packet may contain multiple buffers that may be not in a continuous memory location. /// typedef struct { /// /// If not NULL, the data that is used to override the transmitting settings.Only the two /// filed UdpSessionData.DestinationAddress and UdpSessionData.DestionPort can be used as /// the transmitting setting filed. /// EFI_UDP6_SESSION_DATA *UdpSessionData; /// /// Sum of the fragment data length. Must not exceed the maximum UDP packet size. /// UINT32 DataLength; /// /// Number of fragments. /// UINT32 FragmentCount; /// /// Array of fragment descriptors. /// EFI_UDP6_FRAGMENT_DATA FragmentTable[1]; } EFI_UDP6_TRANSMIT_DATA; /// /// EFI_UDP6_RECEIVE_DATA is filled by the EFI UDPv6 Protocol driver when this EFI UDPv6 /// Protocol instance receives an incoming packet. If there is a waiting token for incoming /// packets, the CompletionToken.Packet.RxData field is updated to this incoming packet and /// the CompletionToken.Event is signaled. The EFI UDPv6 Protocol client must signal the /// RecycleSignal after processing the packet. /// FragmentTable could contain multiple buffers that are not in the continuous memory locations. /// The EFI UDPv6 Protocol client might need to combine two or more buffers in FragmentTable to /// form their own protocol header. /// typedef struct { /// /// Time when the EFI UDPv6 Protocol accepted the packet. /// EFI_TIME TimeStamp; /// /// Indicates the event to signal when the received data has been processed. /// EFI_EVENT RecycleSignal; /// /// The UDP session data including SourceAddress, SourcePort, DestinationAddress, /// and DestinationPort. /// EFI_UDP6_SESSION_DATA UdpSession; /// /// The sum of the fragment data length. /// UINT32 DataLength; /// /// Number of fragments. Maybe zero. /// UINT32 FragmentCount; /// /// Array of fragment descriptors. Maybe zero. /// EFI_UDP6_FRAGMENT_DATA FragmentTable[1]; } EFI_UDP6_RECEIVE_DATA; /// /// The EFI_UDP6_COMPLETION_TOKEN structures are used for both transmit and receive operations. /// When used for transmitting, the Event and TxData fields must be filled in by the EFI UDPv6 /// Protocol client. After the transmit operation completes, the Status field is updated by the /// EFI UDPv6 Protocol and the Event is signaled. /// When used for receiving, only the Event field must be filled in by the EFI UDPv6 Protocol /// client. After a packet is received, RxData and Status are filled in by the EFI UDPv6 Protocol /// and the Event is signaled. /// typedef struct { /// /// This Event will be signaled after the Status field is updated by the EFI UDPv6 Protocol /// driver. The type of Event must be EVT_NOTIFY_SIGNAL. /// EFI_EVENT Event; /// /// Will be set to one of the following values: /// - EFI_SUCCESS: The receive or transmit operation completed successfully. /// - EFI_ABORTED: The receive or transmit was aborted. /// - EFI_TIMEOUT: The transmit timeout expired. /// - EFI_NETWORK_UNREACHABLE: The destination network is unreachable. RxData is set to /// NULL in this situation. /// - EFI_HOST_UNREACHABLE: The destination host is unreachable. RxData is set to NULL in /// this situation. /// - EFI_PROTOCOL_UNREACHABLE: The UDP protocol is unsupported in the remote system. /// RxData is set to NULL in this situation. /// - EFI_PORT_UNREACHABLE: No service is listening on the remote port. RxData is set to /// NULL in this situation. /// - EFI_ICMP_ERROR: Some other Internet Control Message Protocol (ICMP) error report was /// received. For example, packets are being sent too fast for the destination to receive them /// and the destination sent an ICMP source quench report. RxData is set to NULL in this situation. /// - EFI_DEVICE_ERROR: An unexpected system or network error occurred. /// - EFI_SECURITY_VIOLATION: The transmit or receive was failed because of IPsec policy check. /// - EFI_NO_MEDIA: There was a media error. /// EFI_STATUS Status; union { /// /// When this token is used for receiving, RxData is a pointer to EFI_UDP6_RECEIVE_DATA. /// EFI_UDP6_RECEIVE_DATA *RxData; /// /// When this token is used for transmitting, TxData is a pointer to EFI_UDP6_TRANSMIT_DATA. /// EFI_UDP6_TRANSMIT_DATA *TxData; } Packet; } EFI_UDP6_COMPLETION_TOKEN; /** Read the current operational settings. The GetModeData() function copies the current operational settings of this EFI UDPv6 Protocol instance into user-supplied buffers. This function is used optionally to retrieve the operational mode data of underlying networks or drivers. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[out] Udp6ConfigData The buffer in which the current UDP configuration data is returned. @param[out] Ip6ModeData The buffer in which the current EFI IPv6 Protocol mode data is returned. @param[out] MnpConfigData The buffer in which the current managed network configuration data is returned. @param[out] SnpModeData The buffer in which the simple network mode data is returned. @retval EFI_SUCCESS The mode data was read. @retval EFI_NOT_STARTED When Udp6ConfigData is queried, no configuration data is available because this instance has not been started. @retval EFI_INVALID_PARAMETER This is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_GET_MODE_DATA)( IN EFI_UDP6_PROTOCOL *This, OUT EFI_UDP6_CONFIG_DATA *Udp6ConfigData OPTIONAL, OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL ); /** Initializes, changes, or resets the operational parameters for this instance of the EFI UDPv6 Protocol. The Configure() function is used to do the following: - Initialize and start this instance of the EFI UDPv6 Protocol. - Change the filtering rules and operational parameters. - Reset this instance of the EFI UDPv6 Protocol. Until these parameters are initialized, no network traffic can be sent or received by this instance. This instance can be also reset by calling Configure() with UdpConfigData set to NULL. Once reset, the receiving queue and transmitting queue are flushed and no traffic is allowed through this instance. With different parameters in UdpConfigData, Configure() can be used to bind this instance to specified port. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[in] UdpConfigData Pointer to the buffer contained the configuration data. @retval EFI_SUCCESS The configuration settings were set, changed, or reset successfully. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: - This is NULL. - UdpConfigData.StationAddress neither zero nor one of the configured IP addresses in the underlying IPv6 driver. - UdpConfigData.RemoteAddress is not a valid unicast IPv6 address if it is not zero. @retval EFI_ALREADY_STARTED The EFI UDPv6 Protocol instance is already started/configured and must be stopped/reset before it can be reconfigured. Only TrafficClass, HopLimit, ReceiveTimeout, and TransmitTimeout can be reconfigured without stopping the current instance of the EFI UDPv6 Protocol. @retval EFI_ACCESS_DENIED UdpConfigData.AllowDuplicatePort is FALSE and UdpConfigData.StationPort is already used by other instance. @retval EFI_OUT_OF_RESOURCES The EFI UDPv6 Protocol driver cannot allocate memory for this EFI UDPv6 Protocol instance. @retval EFI_DEVICE_ERROR An unexpected network or system error occurred and this instance was not opened. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_CONFIGURE)( IN EFI_UDP6_PROTOCOL *This, IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL ); /** Joins and leaves multicast groups. The Groups() function is used to join or leave one or more multicast group. If the JoinFlag is FALSE and the MulticastAddress is NULL, then all currently joined groups are left. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[in] JoinFlag Set to TRUE to join a multicast group. Set to FALSE to leave one or all multicast groups. @param[in] MulticastAddress Pointer to multicast group address to join or leave. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_NOT_STARTED The EFI UDPv6 Protocol instance has not been started. @retval EFI_OUT_OF_RESOURCES Could not allocate resources to join the group. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - JoinFlag is TRUE and MulticastAddress is NULL. - JoinFlag is TRUE and *MulticastAddress is not a valid multicast address. @retval EFI_ALREADY_STARTED The group address is already in the group table (when JoinFlag is TRUE). @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_GROUPS)( IN EFI_UDP6_PROTOCOL *This, IN BOOLEAN JoinFlag, IN EFI_IPv6_ADDRESS *MulticastAddress OPTIONAL ); /** Queues outgoing data packets into the transmit queue. The Transmit() function places a sending request to this instance of the EFI UDPv6 Protocol, alongside the transmit data that was filled by the user. Whenever the packet in the token is sent out or some errors occur, the Token.Event will be signaled and Token.Status is updated. Providing a proper notification function and context for the event will enable the user to receive the notification and transmitting status. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[in] Token Pointer to the completion token that will be placed into the transmit queue. @retval EFI_SUCCESS The data has been queued for transmission. @retval EFI_NOT_STARTED This EFI UDPv6 Protocol instance has not been started. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. - Token.Packet.TxData is NULL. - Token.Packet.TxData.FragmentCount is zero. - Token.Packet.TxData.DataLength is not equal to the sum of fragment lengths. - One or more of the Token.Packet.TxData.FragmentTable[].FragmentLength fields is zero. - One or more of the Token.Packet.TxData.FragmentTable[].FragmentBuffer fields is NULL. - Token.Packet.TxData.UdpSessionData.DestinationAddress is not zero and is not valid unicast Ipv6 address if UdpSessionData is not NULL. - Token.Packet.TxData.UdpSessionData is NULL and this instance's UdpConfigData.RemoteAddress is unspecified. - Token.Packet.TxData.UdpSessionData.DestinationAddress is non-zero when DestinationAddress is configured as non-zero when doing Configure() for this EFI Udp6 protocol instance. - Token.Packet.TxData.UdpSesionData.DestinationAddress is zero when DestinationAddress is unspecified when doing Configure() for this EFI Udp6 protocol instance. @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event was already in the transmit queue. @retval EFI_NOT_READY The completion token could not be queued because the transmit queue is full. @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. @retval EFI_NOT_FOUND There is no route to the destination network or address. @retval EFI_BAD_BUFFER_SIZE The data length is greater than the maximum UDP packet size. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_TRANSMIT)( IN EFI_UDP6_PROTOCOL *This, IN EFI_UDP6_COMPLETION_TOKEN *Token ); /** Places an asynchronous receive request into the receiving queue. The Receive() function places a completion token into the receive packet queue. This function is always asynchronous. The caller must fill in the Token.Event field in the completion token, and this field cannot be NULL. When the receive operation completes, the EFI UDPv6 Protocol driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event is signaled. Providing a proper notification function and context for the event will enable the user to receive the notification and receiving status. That notification function is guaranteed to not be re-entered. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[in] Token Pointer to a token that is associated with the receive data descriptor. @retval EFI_SUCCESS The receive completion token was cached. @retval EFI_NOT_STARTED This EFI UDPv6 Protocol instance has not been started. @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source address for this instance, but no source address was available for use. @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: - This is NULL. - Token is NULL. - Token.Event is NULL. @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system resources (usually memory). @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI UDPv6 Protocol instance has been reset to startup defaults. @retval EFI_ACCESS_DENIED A receive completion token with the same Token.Event was already in the receive queue. @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_RECEIVE)( IN EFI_UDP6_PROTOCOL *This, IN EFI_UDP6_COMPLETION_TOKEN *Token ); /** Aborts an asynchronous transmit or receive request. The Cancel() function is used to abort a pending transmit or receive request. If the token is in the transmit or receive request queues, after calling this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be signaled. If the token is not in one of the queues, which usually means that the asynchronous operation has completed, this function will not signal the token and EFI_NOT_FOUND is returned. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @param[in] Token Pointer to a token that has been issued by EFI_UDP6_PROTOCOL.Transmit() or EFI_UDP6_PROTOCOL.Receive().If NULL, all pending tokens are aborted. @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token.Event was signaled. When Token is NULL, all pending requests are aborted and their events are signaled. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_NOT_STARTED This instance has not been started. @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was not found in the transmit or receive queue. It has either completed or was not issued by Transmit() and Receive(). **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_CANCEL)( IN EFI_UDP6_PROTOCOL *This, IN EFI_UDP6_COMPLETION_TOKEN *Token OPTIONAL ); /** Polls for incoming data packets and processes outgoing data packets. The Poll() function can be used by network drivers and applications to increase the rate that data packets are moved between the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets without missing incoming packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should try calling the Poll() function more often. @param[in] This Pointer to the EFI_UDP6_PROTOCOL instance. @retval EFI_SUCCESS Incoming or outgoing data was processed. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. Consider increasing the polling rate. **/ typedef EFI_STATUS (EFIAPI *EFI_UDP6_POLL)( IN EFI_UDP6_PROTOCOL *This ); /// /// The EFI_UDP6_PROTOCOL defines an EFI UDPv6 Protocol session that can be used by any network drivers, /// applications, or daemons to transmit or receive UDP packets. This protocol instance can either be /// bound to a specified port as a service or connected to some remote peer as an active client. /// Each instance has its own settings, such as group table, that are independent from each other. /// struct _EFI_UDP6_PROTOCOL { EFI_UDP6_GET_MODE_DATA GetModeData; EFI_UDP6_CONFIGURE Configure; EFI_UDP6_GROUPS Groups; EFI_UDP6_TRANSMIT Transmit; EFI_UDP6_RECEIVE Receive; EFI_UDP6_CANCEL Cancel; EFI_UDP6_POLL Poll; }; extern EFI_GUID gEfiUdp6ServiceBindingProtocolGuid; extern EFI_GUID gEfiUdp6ProtocolGuid; #endif /** @file UGA Draw protocol from the EFI 1.10 specification. Abstraction of a very simple graphics device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UGA_DRAW_H__ #define __UGA_DRAW_H__ #define EFI_UGA_DRAW_PROTOCOL_GUID \ { \ 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \ } typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL; /** Return the current video mode information. @param This The EFI_UGA_DRAW_PROTOCOL instance. @param HorizontalResolution The size of video screen in pixels in the X dimension. @param VerticalResolution The size of video screen in pixels in the Y dimension. @param ColorDepth Number of bits per pixel, currently defined to be 32. @param RefreshRate The refresh rate of the monitor in Hertz. @retval EFI_SUCCESS Mode information returned. @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () @retval EFI_INVALID_PARAMETER One of the input args was NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE)( IN EFI_UGA_DRAW_PROTOCOL *This, OUT UINT32 *HorizontalResolution, OUT UINT32 *VerticalResolution, OUT UINT32 *ColorDepth, OUT UINT32 *RefreshRate ); /** Set the current video mode information. @param This The EFI_UGA_DRAW_PROTOCOL instance. @param HorizontalResolution The size of video screen in pixels in the X dimension. @param VerticalResolution The size of video screen in pixels in the Y dimension. @param ColorDepth Number of bits per pixel, currently defined to be 32. @param RefreshRate The refresh rate of the monitor in Hertz. @retval EFI_SUCCESS Mode information returned. @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () **/ typedef EFI_STATUS (EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE)( IN EFI_UGA_DRAW_PROTOCOL *This, IN UINT32 HorizontalResolution, IN UINT32 VerticalResolution, IN UINT32 ColorDepth, IN UINT32 RefreshRate ); typedef struct { UINT8 Blue; UINT8 Green; UINT8 Red; UINT8 Reserved; } EFI_UGA_PIXEL; typedef union { EFI_UGA_PIXEL Pixel; UINT32 Raw; } EFI_UGA_PIXEL_UNION; /// /// Enumration value for actions of Blt operations. /// typedef enum { EfiUgaVideoFill, ///< Write data from the BltBuffer pixel (SourceX, SourceY) ///< directly to every pixel of the video display rectangle ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). ///< Only one pixel will be used from the BltBuffer. Delta is NOT used. EfiUgaVideoToBltBuffer, ///< Read data from the video display rectangle ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in ///< the BltBuffer rectangle (DestinationX, DestinationY ) ///< (DestinationX + Width, DestinationY + Height). If DestinationX or ///< DestinationY is not zero then Delta must be set to the length in bytes ///< of a row in the BltBuffer. EfiUgaBltBufferToVideo, ///< Write data from the BltBuffer rectangle ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the ///< video display rectangle (DestinationX, DestinationY) ///< (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is ///< not zero then Delta must be set to the length in bytes of a row in the ///< BltBuffer. EfiUgaVideoToVideo, ///< Copy from the video display rectangle (SourceX, SourceY) ///< (SourceX + Width, SourceY + Height) .to the video display rectangle ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). ///< The BltBuffer and Delta are not used in this mode. EfiUgaBltMax ///< Maxmimum value for enumration value of Blt operation. If a Blt operation ///< larger or equal to this enumration value, it is invalid. } EFI_UGA_BLT_OPERATION; /** Blt a rectangle of pixels on the graphics screen. @param[in] This - Protocol instance pointer. @param[in] BltBuffer - Buffer containing data to blit into video buffer. This buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) @param[in] BltOperation - Operation to perform on BlitBuffer and video memory @param[in] SourceX - X coordinate of source for the BltBuffer. @param[in] SourceY - Y coordinate of source for the BltBuffer. @param[in] DestinationX - X coordinate of destination for the BltBuffer. @param[in] DestinationY - Y coordinate of destination for the BltBuffer. @param[in] Width - Width of rectangle in BltBuffer in pixels. @param[in] Height - Hight of rectangle in BltBuffer in pixels. @param[in] Delta - OPTIONAL @retval EFI_SUCCESS - The Blt operation completed. @retval EFI_INVALID_PARAMETER - BltOperation is not valid. @retval EFI_DEVICE_ERROR - A hardware error occurred writting to the video buffer. **/ typedef EFI_STATUS (EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT)( IN EFI_UGA_DRAW_PROTOCOL *This, IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, IN EFI_UGA_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL ); /// /// This protocol provides a basic abstraction to set video modes and /// copy pixels to and from the graphics controller's frame buffer. /// struct _EFI_UGA_DRAW_PROTOCOL { EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode; EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode; EFI_UGA_DRAW_PROTOCOL_BLT Blt; }; extern EFI_GUID gEfiUgaDrawProtocolGuid; #endif /** @file UGA IO protocol from the EFI 1.10 specification. Abstraction of a very simple graphics device. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UGA_IO_H__ #define __UGA_IO_H__ #define EFI_UGA_IO_PROTOCOL_GUID \ { 0x61a4d49e, 0x6f68, 0x4f1b, { 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 } } typedef struct _EFI_UGA_IO_PROTOCOL EFI_UGA_IO_PROTOCOL; typedef UINT32 UGA_STATUS; typedef enum { UgaDtParentBus = 1, UgaDtGraphicsController, UgaDtOutputController, UgaDtOutputPort, UgaDtOther } UGA_DEVICE_TYPE, *PUGA_DEVICE_TYPE; typedef UINT32 UGA_DEVICE_ID, *PUGA_DEVICE_ID; typedef struct { UGA_DEVICE_TYPE deviceType; UGA_DEVICE_ID deviceId; UINT32 ui32DeviceContextSize; UINT32 ui32SharedContextSize; } UGA_DEVICE_DATA, *PUGA_DEVICE_DATA; typedef struct _UGA_DEVICE { VOID *pvDeviceContext; VOID *pvSharedContext; VOID *pvRunTimeContext; struct _UGA_DEVICE *pParentDevice; VOID *pvBusIoServices; VOID *pvStdIoServices; UGA_DEVICE_DATA deviceData; } UGA_DEVICE, *PUGA_DEVICE; typedef enum { UgaIoGetVersion = 1, UgaIoGetChildDevice, UgaIoStartDevice, UgaIoStopDevice, UgaIoFlushDevice, UgaIoResetDevice, UgaIoGetDeviceState, UgaIoSetDeviceState, UgaIoSetPowerState, UgaIoGetMemoryConfiguration, UgaIoSetVideoMode, UgaIoCopyRectangle, UgaIoGetEdidSegment, UgaIoDeviceChannelOpen, UgaIoDeviceChannelClose, UgaIoDeviceChannelRead, UgaIoDeviceChannelWrite, UgaIoGetPersistentDataSize, UgaIoGetPersistentData, UgaIoSetPersistentData, UgaIoGetDevicePropertySize, UgaIoGetDeviceProperty, UgaIoBtPrivateInterface } UGA_IO_REQUEST_CODE, *PUGA_IO_REQUEST_CODE; typedef struct { IN UGA_IO_REQUEST_CODE ioRequestCode; IN VOID *pvInBuffer; IN UINT64 ui64InBufferSize; OUT VOID *pvOutBuffer; IN UINT64 ui64OutBufferSize; OUT UINT64 ui64BytesReturned; } UGA_IO_REQUEST, *PUGA_IO_REQUEST; /** Dynamically allocate storage for a child UGA_DEVICE. @param[in] This The EFI_UGA_IO_PROTOCOL instance. @param[in] ParentDevice ParentDevice specifies a pointer to the parent device of Device. @param[in] DeviceData A pointer to UGA_DEVICE_DATA returned from a call to DispatchService() with a UGA_DEVICE of Parent and an IoRequest of type UgaIoGetChildDevice. @param[in] RunTimeContext Context to associate with Device. @param[out] Device The Device returns a dynamically allocated child UGA_DEVICE object for ParentDevice. The caller is responsible for deleting Device. @retval EFI_SUCCESS Device was returned. @retval EFI_INVALID_PARAMETER One of the arguments was not valid. @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. **/ typedef EFI_STATUS (EFIAPI *EFI_UGA_IO_PROTOCOL_CREATE_DEVICE)( IN EFI_UGA_IO_PROTOCOL *This, IN UGA_DEVICE *ParentDevice, IN UGA_DEVICE_DATA *DeviceData, IN VOID *RunTimeContext, OUT UGA_DEVICE **Device ); /** Delete a dynamically allocated child UGA_DEVICE object that was allocated via CreateDevice(). @param[in] This The EFI_UGA_IO_PROTOCOL instance. Type EFI_UGA_IO_PROTOCOL is defined in Section 10.7. @param[in] Device The Device points to a UGA_DEVICE object that was dynamically allocated via a CreateDevice() call. @retval EFI_SUCCESS Device was returned. @retval EFI_INVALID_PARAMETER The Device was not allocated via CreateDevice(). **/ typedef EFI_STATUS (EFIAPI *EFI_UGA_IO_PROTOCOL_DELETE_DEVICE)( IN EFI_UGA_IO_PROTOCOL *This, IN UGA_DEVICE *Device ); /** This is the main UGA service dispatch routine for all UGA_IO_REQUEST s. @param pDevice pDevice specifies a pointer to a device object associated with a device enumerated by a pIoRequest->ioRequestCode of type UgaIoGetChildDevice. The root device for the EFI_UGA_IO_PROTOCOL is represented by pDevice being set to NULL. @param pIoRequest pIoRequest points to a caller allocated buffer that contains data defined by pIoRequest->ioRequestCode. See Related Definitions for a definition of UGA_IO_REQUEST_CODE s and their associated data structures. @return UGA_STATUS **/ typedef UGA_STATUS (EFIAPI *PUGA_FW_SERVICE_DISPATCH)( IN PUGA_DEVICE pDevice, IN OUT PUGA_IO_REQUEST pIoRequest ); /// /// Provides a basic abstraction to send I/O requests to the graphics device and any of its children. /// struct _EFI_UGA_IO_PROTOCOL { EFI_UGA_IO_PROTOCOL_CREATE_DEVICE CreateDevice; EFI_UGA_IO_PROTOCOL_DELETE_DEVICE DeleteDevice; PUGA_FW_SERVICE_DISPATCH DispatchService; }; extern EFI_GUID gEfiUgaIoProtocolGuid; // // Data structure that is stored in the EFI Configuration Table with the // EFI_UGA_IO_PROTOCOL_GUID. The option ROMs listed in this table may have // EBC UGA drivers. // typedef struct { UINT32 Version; UINT32 HeaderSize; UINT32 SizeOfEntries; UINT32 NumberOfEntries; } EFI_DRIVER_OS_HANDOFF_HEADER; typedef enum { EfiUgaDriverFromPciRom, EfiUgaDriverFromSystem, EfiDriverHandoffMax } EFI_DRIVER_HANOFF_ENUM; typedef struct { EFI_DRIVER_HANOFF_ENUM Type; EFI_DEVICE_PATH_PROTOCOL *DevicePath; VOID *PciRomImage; UINT64 PciRomSize; } EFI_DRIVER_OS_HANDOFF; #endif /** @file Unicode Collation protocol that follows the UEFI 2.0 specification. This protocol is used to allow code running in the boot services environment to perform lexical comparison functions on Unicode strings for given languages. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UNICODE_COLLATION_H__ #define __UNICODE_COLLATION_H__ #define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ { \ 0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ { \ 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49 } \ } typedef struct _EFI_UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL; /// /// Protocol GUID name defined in EFI1.1. /// #define UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL_GUID /// /// Protocol defined in EFI1.1. /// typedef EFI_UNICODE_COLLATION_PROTOCOL UNICODE_COLLATION_INTERFACE; /// /// Protocol data structures and defines /// #define EFI_UNICODE_BYTE_ORDER_MARK (CHAR16) (0xfeff) // // Protocol member functions // /** Performs a case-insensitive comparison of two Null-terminated strings. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param Str1 A pointer to a Null-terminated string. @param Str2 A pointer to a Null-terminated string. @retval 0 Str1 is equivalent to Str2. @retval >0 Str1 is lexically greater than Str2. @retval <0 Str1 is lexically less than Str2. **/ typedef INTN (EFIAPI *EFI_UNICODE_COLLATION_STRICOLL)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *Str1, IN CHAR16 *Str2 ); /** Performs a case-insensitive comparison of a Null-terminated pattern string and a Null-terminated string. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param String A pointer to a Null-terminated string. @param Pattern A pointer to a Null-terminated pattern string. @retval TRUE Pattern was found in String. @retval FALSE Pattern was not found in String. **/ typedef BOOLEAN (EFIAPI *EFI_UNICODE_COLLATION_METAIMATCH)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN CHAR16 *Pattern ); /** Converts all the characters in a Null-terminated string to lower case characters. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param String A pointer to a Null-terminated string. **/ typedef VOID (EFIAPI *EFI_UNICODE_COLLATION_STRLWR)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ); /** Converts all the characters in a Null-terminated string to upper case characters. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param String A pointer to a Null-terminated string. **/ typedef VOID (EFIAPI *EFI_UNICODE_COLLATION_STRUPR)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ); /** Converts an 8.3 FAT file name in an OEM character set to a Null-terminated string. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param FatSize The size of the string Fat in bytes. @param Fat A pointer to a Null-terminated string that contains an 8.3 file name using an 8-bit OEM character set. @param String A pointer to a Null-terminated string. The string must be allocated in advance to hold FatSize characters. **/ typedef VOID (EFIAPI *EFI_UNICODE_COLLATION_FATTOSTR)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN UINTN FatSize, IN CHAR8 *Fat, OUT CHAR16 *String ); /** Converts a Null-terminated string to legal characters in a FAT filename using an OEM character set. @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. @param String A pointer to a Null-terminated string. @param FatSize The size of the string Fat in bytes. @param Fat A pointer to a string that contains the converted version of String using legal FAT characters from an OEM character set. @retval TRUE One or more conversions failed and were substituted with '_' @retval FALSE None of the conversions failed. **/ typedef BOOLEAN (EFIAPI *EFI_UNICODE_COLLATION_STRTOFAT)( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN UINTN FatSize, OUT CHAR8 *Fat ); /// /// The EFI_UNICODE_COLLATION_PROTOCOL is used to perform case-insensitive /// comparisons of strings. /// struct _EFI_UNICODE_COLLATION_PROTOCOL { EFI_UNICODE_COLLATION_STRICOLL StriColl; EFI_UNICODE_COLLATION_METAIMATCH MetaiMatch; EFI_UNICODE_COLLATION_STRLWR StrLwr; EFI_UNICODE_COLLATION_STRUPR StrUpr; // // for supporting fat volumes // EFI_UNICODE_COLLATION_FATTOSTR FatToStr; EFI_UNICODE_COLLATION_STRTOFAT StrToFat; /// /// A Null-terminated ASCII string array that contains one or more language codes. /// When this field is used for UnicodeCollation2, it is specified in RFC 4646 format. /// When it is used for UnicodeCollation, it is specified in ISO 639-2 format. /// CHAR8 *SupportedLanguages; }; extern EFI_GUID gEfiUnicodeCollationProtocolGuid; extern EFI_GUID gEfiUnicodeCollation2ProtocolGuid; #endif /** @file EFI_USB2_HC_PROTOCOL as defined in UEFI 2.0. The USB Host Controller Protocol is used by code, typically USB bus drivers, running in the EFI boot services environment, to perform data transactions over a USB bus. In addition, it provides an abstraction for the root hub of the USB bus. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _USB2_HOSTCONTROLLER_H_ #define _USB2_HOSTCONTROLLER_H_ #include #define EFI_USB2_HC_PROTOCOL_GUID \ { \ 0x3e745226, 0x9818, 0x45b6, {0xa2, 0xac, 0xd7, 0xcd, 0xe, 0x8b, 0xa2, 0xbc } \ } /// /// Forward reference for pure ANSI compatability /// typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL; typedef struct { UINT16 PortStatus; ///< Contains current port status bitmap. UINT16 PortChangeStatus; ///< Contains current port status change bitmap. } EFI_USB_PORT_STATUS; /// /// EFI_USB_PORT_STATUS.PortStatus bit definition /// #define USB_PORT_STAT_CONNECTION 0x0001 #define USB_PORT_STAT_ENABLE 0x0002 #define USB_PORT_STAT_SUSPEND 0x0004 #define USB_PORT_STAT_OVERCURRENT 0x0008 #define USB_PORT_STAT_RESET 0x0010 #define USB_PORT_STAT_POWER 0x0100 #define USB_PORT_STAT_LOW_SPEED 0x0200 #define USB_PORT_STAT_HIGH_SPEED 0x0400 #define USB_PORT_STAT_SUPER_SPEED 0x0800 #define USB_PORT_STAT_OWNER 0x2000 /// /// EFI_USB_PORT_STATUS.PortChangeStatus bit definition /// #define USB_PORT_STAT_C_CONNECTION 0x0001 #define USB_PORT_STAT_C_ENABLE 0x0002 #define USB_PORT_STAT_C_SUSPEND 0x0004 #define USB_PORT_STAT_C_OVERCURRENT 0x0008 #define USB_PORT_STAT_C_RESET 0x0010 /// /// Usb port features value /// Each value indicates its bit index in the port status and status change bitmaps, /// if combines these two bitmaps into a 32-bit bitmap. /// typedef enum { EfiUsbPortEnable = 1, EfiUsbPortSuspend = 2, EfiUsbPortReset = 4, EfiUsbPortPower = 8, EfiUsbPortOwner = 13, EfiUsbPortConnectChange = 16, EfiUsbPortEnableChange = 17, EfiUsbPortSuspendChange = 18, EfiUsbPortOverCurrentChange = 19, EfiUsbPortResetChange = 20 } EFI_USB_PORT_FEATURE; #define EFI_USB_SPEED_FULL 0x0000 ///< 12 Mb/s, USB 1.1 OHCI and UHCI HC. #define EFI_USB_SPEED_LOW 0x0001 ///< 1 Mb/s, USB 1.1 OHCI and UHCI HC. #define EFI_USB_SPEED_HIGH 0x0002 ///< 480 Mb/s, USB 2.0 EHCI HC. #define EFI_USB_SPEED_SUPER 0x0003 ///< 4.8 Gb/s, USB 3.0 XHCI HC. typedef struct { UINT8 TranslatorHubAddress; ///< device address UINT8 TranslatorPortNumber; ///< the port number of the hub that device is connected to. } EFI_USB2_HC_TRANSACTION_TRANSLATOR; // // Protocol definitions // /** Retrieves the Host Controller capabilities. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param MaxSpeed Host controller data transfer speed. @param PortNumber Number of the root hub ports. @param Is64BitCapable TRUE if controller supports 64-bit memory addressing, FALSE otherwise. @retval EFI_SUCCESS The host controller capabilities were retrieved successfully. @retval EFI_INVALID_PARAMETER One of the input args was NULL. @retval EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_GET_CAPABILITY)( IN EFI_USB2_HC_PROTOCOL *This, OUT UINT8 *MaxSpeed, OUT UINT8 *PortNumber, OUT UINT8 *Is64BitCapable ); #define EFI_USB_HC_RESET_GLOBAL 0x0001 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 /** Provides software reset for the USB host controller. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param Attributes A bit mask of the reset operation to perform. @retval EFI_SUCCESS The reset operation succeeded. @retval EFI_INVALID_PARAMETER Attributes is not valid. @retval EFI_UNSUPPORTED The type of reset specified by Attributes is not currently supported by the host controller hardware. @retval EFI_ACCESS_DENIED Reset operation is rejected due to the debug port being configured and active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Attributes can be used to perform reset operation for this host controller. @retval EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_RESET)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT16 Attributes ); /** Enumration value for status of USB HC. **/ typedef enum { EfiUsbHcStateHalt, ///< The host controller is in halt ///< state. No USB transactions can occur ///< while in this state. The host ///< controller can enter this state for ///< three reasons: 1) After host ///< controller hardware reset. 2) ///< Explicitly set by software. 3) ///< Triggered by a fatal error such as ///< consistency check failure. EfiUsbHcStateOperational, ///< The host controller is in an ///< operational state. When in ///< this state, the host ///< controller can execute bus ///< traffic. This state must be ///< explicitly set to enable the ///< USB bus traffic. EfiUsbHcStateSuspend, ///< The host controller is in the ///< suspend state. No USB ///< transactions can occur while in ///< this state. The host controller ///< enters this state for the ///< following reasons: 1) Explicitly ///< set by software. 2) Triggered ///< when there is no bus traffic for ///< 3 microseconds. EfiUsbHcStateMaximum ///< Maximum value for enumration value of HC status. } EFI_USB_HC_STATE; /** Retrieves current state of the USB host controller. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param State A pointer to the EFI_USB_HC_STATE data structure that indicates current state of the USB host controller. @retval EFI_SUCCESS The state information of the host controller was returned in State. @retval EFI_INVALID_PARAMETER State is NULL. @retval EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the host controller's current state. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_GET_STATE)( IN EFI_USB2_HC_PROTOCOL *This, OUT EFI_USB_HC_STATE *State ); /** Sets the USB host controller to a specific state. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param State Indicates the state of the host controller that will be set. @retval EFI_SUCCESS The USB host controller was successfully placed in the state specified by State. @retval EFI_INVALID_PARAMETER State is not valid. @retval EFI_DEVICE_ERROR Failed to set the state specified by State due to device error. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_SET_STATE)( IN EFI_USB2_HC_PROTOCOL *This, IN EFI_USB_HC_STATE State ); /** Submits control transfer to a target USB device. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param DeviceSpeed Indicates device speed. @param MaximumPacketLength Indicates the maximum packet size that the default control transfer endpoint is capable of sending or receiving. @param Request A pointer to the USB device request that will be sent to the USB device. @param TransferDirection Specifies the data direction for the transfer. There are three values available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength On input, indicates the size, in bytes, of the data buffer specified by Data. On output, indicates the amount of data actually transferred. @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is allowed to complete. @param Translator A pointer to the transaction translator data. @param TransferResult A pointer to the detailed result information generated by this control transfer. @retval EFI_SUCCESS The control transfer was completed successfully. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The control transfer could not be completed due to a lack of resources. @retval EFI_TIMEOUT The control transfer failed due to timeout. @retval EFI_DEVICE_ERROR The control transfer failed due to host controller or device error. Caller should check TransferResult for detailed error information. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN EFI_USB_DEVICE_REQUEST *Request, IN EFI_USB_DATA_DIRECTION TransferDirection, IN OUT VOID *Data OPTIONAL, IN OUT UINTN *DataLength OPTIONAL, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult ); #define EFI_USB_MAX_BULK_BUFFER_NUM 10 /** Submits bulk transfer to a bulk endpoint of a USB device. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param EndPointAddress The combination of an endpoint number and an endpoint direction of the target USB device. @param DeviceSpeed Indicates device speed. @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of sending or receiving. @param DataBuffersNumber Number of data buffers prepared for the transfer. @param Data Array of pointers to the buffers of data that will be transmitted to USB device or received from USB device. @param DataLength When input, indicates the size, in bytes, of the data buffers specified by Data. When output, indicates the actually transferred data size. @param DataToggle A pointer to the data toggle value. @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is allowed to complete. @param Translator A pointer to the transaction translator data. @param TransferResult A pointer to the detailed result information of the bulk transfer. @retval EFI_SUCCESS The bulk transfer was completed successfully. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The bulk transfer could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The bulk transfer failed due to timeout. @retval EFI_DEVICE_ERROR The bulk transfer failed due to host controller or device error. Caller should check TransferResult for detailed error information. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_BULK_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult ); /** Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device. Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param EndPointAddress The combination of an endpoint number and an endpoint direction of the target USB device. @param DeviceSpeed Indicates device speed. @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of sending or receiving. @param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between the host and the target interrupt endpoint. If FALSE, the specified asynchronous interrupt pipe is canceled. If TRUE, and an interrupt transfer exists for the target end point, then EFI_INVALID_PARAMETER is returned. @param DataToggle A pointer to the data toggle value. @param PollingInterval Indicates the interval, in milliseconds, that the asynchronous interrupt transfer is polled. @param DataLength Indicates the length of data to be received at the rate specified by PollingInterval from the target asynchronous interrupt endpoint. @param Translator A pointr to the transaction translator data. @param CallBackFunction The Callback function. This function is called at the rate specified by PollingInterval. @param Context The context that is passed to the CallBackFunction. This is an optional parameter and may be NULL. @retval EFI_SUCCESS The asynchronous interrupt transfer request has been successfully submitted or canceled. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaxiumPacketLength, IN BOOLEAN IsNewTransfer, IN OUT UINT8 *DataToggle, IN UINTN PollingInterval OPTIONAL, IN UINTN DataLength OPTIONAL, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator OPTIONAL, IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL, IN VOID *Context OPTIONAL ); /** Submits synchronous interrupt transfer to an interrupt endpoint of a USB device. Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param EndPointAddress The combination of an endpoint number and an endpoint direction of the target USB device. @param DeviceSpeed Indicates device speed. @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of sending or receiving. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength On input, the size, in bytes, of the data buffer specified by Data. On output, the number of bytes transferred. @param DataToggle A pointer to the data toggle value. @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is allowed to complete. @param Translator A pointr to the transaction translator data. @param TransferResult A pointer to the detailed result information from the synchronous interrupt transfer. @retval EFI_SUCCESS The synchronous interrupt transfer was completed successfully. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The synchronous interrupt transfer could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The synchronous interrupt transfer failed due to timeout. @retval EFI_DEVICE_ERROR The synchronous interrupt transfer failed due to host controller or device error. Caller should check TransferResult for detailed error information. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult ); #define EFI_USB_MAX_ISO_BUFFER_NUM 7 #define EFI_USB_MAX_ISO_BUFFER_NUM1 2 /** Submits isochronous transfer to an isochronous endpoint of a USB device. This function is used to submit isochronous transfer to a target endpoint of a USB device. The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers are used when working with isochronous date. It provides periodic, continuous communication between the host and a device. Isochronous transfers can beused only by full-speed, high-speed, and super-speed devices. High-speed isochronous transfers can be performed using multiple data buffers. The number of buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For full-speed isochronous transfers this value is ignored. Data represents a list of pointers to the data buffers. For full-speed isochronous transfers only the data pointed by Data[0]shall be used. For high-speed isochronous transfers and for the split transactions depending on DataLengththere several data buffers canbe used. For the high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM. For split transactions performed on full-speed device by high-speed host controller the total number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1. If the isochronous transfer is successful, then EFI_SUCCESSis returned. The isochronous transfer is designed to be completed within one USB frame time, if it cannot be completed, EFI_TIMEOUT is returned. If an error other than timeout occurs during the USB transfer, then EFI_DEVICE_ERROR is returned and the detailed status code will be returned in TransferResult. EFI_INVALID_PARAMETERis returned if one of the following conditionsis satisfied: - Data is NULL. - DataLength is 0. - DeviceSpeed is not one of the supported values listed above. - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed devices, and 1024 or less for high-speed and super-speed devices. - TransferResult is NULL. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param EndPointAddress The combination of an endpoint number and an endpoint direction of the target USB device. @param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL, EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER. @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of sending or receiving. @param DataBuffersNumber Number of data buffers prepared for the transfer. @param Data Array of pointers to the buffers of data that will be transmitted to USB device or received from USB device. @param DataLength Specifies the length, in bytes, of the data to be sent to or received from the USB device. @param Translator A pointer to the transaction translator data. @param TransferResult A pointer to the detailed result information of the isochronous transfer. @retval EFI_SUCCESS The isochronous transfer was completed successfully. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The isochronous transfer could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The isochronous transfer cannot be completed within the one USB frame time. @retval EFI_DEVICE_ERROR The isochronous transfer failed due to host controller or device error. Caller should check TransferResult for detailed error information. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult ); /** Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device. This is an asynchronous type of USB isochronous transfer. If the caller submits a USB isochronous transfer request through this function, this function will return immediately. When the isochronous transfer completes, the IsochronousCallbackfunction will be triggered, the caller can know the transfer results. If the transfer is successful, the caller can get the data received or sent in this callback function. The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers are used when working with isochronous date. It provides periodic, continuous communication between the host and a device. Isochronous transfers can be used only by full-speed, high-speed, and super-speed devices. High-speed isochronous transfers can be performed using multiple data buffers. The number of buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For full-speed isochronous transfers this value is ignored. Data represents a list of pointers to the data buffers. For full-speed isochronous transfers only the data pointed by Data[0] shall be used. For high-speed isochronous transfers and for the split transactions depending on DataLength there several data buffers can be used. For the high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM. For split transactions performed on full-speed device by high-speed host controller the total number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1. EFI_INVALID_PARAMETER is returned if one of the following conditionsis satisfied: - Data is NULL. - DataLength is 0. - DeviceSpeed is not one of the supported values listed above. - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed devices and 1024 or less for high-speed and super-speed devices. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param DeviceAddress Represents the address of the target device on the USB. @param EndPointAddress The combination of an endpoint number and an endpoint direction of the target USB device. @param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL, EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER. @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of sending or receiving. @param DataBuffersNumber Number of data buffers prepared for the transfer. @param Data Array of pointers to the buffers of data that will be transmitted to USB device or received from USB device. @param DataLength Specifies the length, in bytes, of the data to be sent to or received from the USB device. @param Translator A pointer to the transaction translator data. @param IsochronousCallback The Callback function. This function is called if the requested isochronous transfer is completed. @param Context Data passed to the IsochronousCallback function. This is an optional parameter and may be NULL. @retval EFI_SUCCESS The asynchronous isochronous transfer request has been successfully submitted or canceled. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_OUT_OF_RESOURCES The asynchronous isochronous transfer could not be submitted due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, IN VOID *Context OPTIONAL ); /** Retrieves the current status of a USB root hub port. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param PortNumber Specifies the root hub port from which the status is to be retrieved. This value is zero based. @param PortStatus A pointer to the current port status bits and port status change bits. @retval EFI_SUCCESS The status of the USB root hub port specified by PortNumber was returned in PortStatus. @retval EFI_INVALID_PARAMETER PortNumber is invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, OUT EFI_USB_PORT_STATUS *PortStatus ); /** Sets a feature for the specified root hub port. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param PortNumber Specifies the root hub port whose feature is requested to be set. This value is zero based. @param PortFeature Indicates the feature selector associated with the feature set request. @retval EFI_SUCCESS The feature specified by PortFeature was set for the USB root hub port specified by PortNumber. @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, IN EFI_USB_PORT_FEATURE PortFeature ); /** Clears a feature for the specified root hub port. @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. @param PortNumber Specifies the root hub port whose feature is requested to be cleared. This value is zero based. @param PortFeature Indicates the feature selector associated with the feature clear request. @retval EFI_SUCCESS The feature specified by PortFeature was cleared for the USB root hub port specified by PortNumber. @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function. **/ typedef EFI_STATUS (EFIAPI *EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE)( IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, IN EFI_USB_PORT_FEATURE PortFeature ); /// /// The EFI_USB2_HC_PROTOCOL provides USB host controller management, basic /// data transactions over a USB bus, and USB root hub access. A device driver /// that wishes to manage a USB bus in a system retrieves the EFI_USB2_HC_PROTOCOL /// instance that is associated with the USB bus to be managed. A device handle /// for a USB host controller will minimally contain an EFI_DEVICE_PATH_PROTOCOL /// instance, and an EFI_USB2_HC_PROTOCOL instance. /// struct _EFI_USB2_HC_PROTOCOL { EFI_USB2_HC_PROTOCOL_GET_CAPABILITY GetCapability; EFI_USB2_HC_PROTOCOL_RESET Reset; EFI_USB2_HC_PROTOCOL_GET_STATE GetState; EFI_USB2_HC_PROTOCOL_SET_STATE SetState; EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER ControlTransfer; EFI_USB2_HC_PROTOCOL_BULK_TRANSFER BulkTransfer; EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER AsyncInterruptTransfer; EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER SyncInterruptTransfer; EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER IsochronousTransfer; EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER AsyncIsochronousTransfer; EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS GetRootHubPortStatus; EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE SetRootHubPortFeature; EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE ClearRootHubPortFeature; /// /// The major revision number of the USB host controller. The revision information /// indicates the release of the Universal Serial Bus Specification with which the /// host controller is compliant. /// UINT16 MajorRevision; /// /// The minor revision number of the USB host controller. The revision information /// indicates the release of the Universal Serial Bus Specification with which the /// host controller is compliant. /// UINT16 MinorRevision; }; extern EFI_GUID gEfiUsb2HcProtocolGuid; #endif /** @file EFI Usb I/O Protocol as defined in UEFI specification. This protocol is used by code, typically drivers, running in the EFI boot services environment to access USB devices like USB keyboards, mice and mass storage devices. In particular, functions for managing devices on USB buses are defined here. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __USB_IO_H__ #define __USB_IO_H__ #include // // Global ID for the USB I/O Protocol // #define EFI_USB_IO_PROTOCOL_GUID \ { \ 0x2B2F68D6, 0x0CD2, 0x44cf, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ } typedef struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL; // // Related Definition for EFI USB I/O protocol // // // USB standard descriptors and reqeust // typedef USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST; typedef USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR; typedef USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR; typedef USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR; typedef USB_ENDPOINT_DESCRIPTOR EFI_USB_ENDPOINT_DESCRIPTOR; /// /// USB data transfer direction /// typedef enum { EfiUsbDataIn, EfiUsbDataOut, EfiUsbNoData } EFI_USB_DATA_DIRECTION; // // USB Transfer Results // #define EFI_USB_NOERROR 0x00 #define EFI_USB_ERR_NOTEXECUTE 0x01 #define EFI_USB_ERR_STALL 0x02 #define EFI_USB_ERR_BUFFER 0x04 #define EFI_USB_ERR_BABBLE 0x08 #define EFI_USB_ERR_NAK 0x10 #define EFI_USB_ERR_CRC 0x20 #define EFI_USB_ERR_TIMEOUT 0x40 #define EFI_USB_ERR_BITSTUFF 0x80 #define EFI_USB_ERR_SYSTEM 0x100 /** Async USB transfer callback routine. @param Data Data received or sent via the USB Asynchronous Transfer, if the transfer completed successfully. @param DataLength The length of Data received or sent via the Asynchronous Transfer, if transfer successfully completes. @param Context Data passed from UsbAsyncInterruptTransfer() request. @param Status Indicates the result of the asynchronous transfer. @retval EFI_SUCCESS The asynchronous USB transfer request has been successfully executed. @retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed. **/ typedef EFI_STATUS (EFIAPI *EFI_ASYNC_USB_TRANSFER_CALLBACK)( IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status ); // // Prototype for EFI USB I/O protocol // /** This function is used to manage a USB device with a control transfer pipe. A control transfer is typically used to perform device initialization and configuration. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param Request A pointer to the USB device request that will be sent to the USB device. @param Direction Indicates the data direction. @param Timeout Indicating the transfer should be completed within this time frame. The units are in milliseconds. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength The size, in bytes, of the data buffer specified by Data. @param Status A pointer to the result of the USB transfer. @retval EFI_SUCCESS The control transfer has been successfully executed. @retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in Status. @retval EFI_INVALID_PARAMETE One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_TIMEOUT The control transfer fails due to timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_CONTROL_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN EFI_USB_DEVICE_REQUEST *Request, IN EFI_USB_DATA_DIRECTION Direction, IN UINT32 Timeout, IN OUT VOID *Data OPTIONAL, IN UINTN DataLength OPTIONAL, OUT UINT32 *Status ); /** This function is used to manage a USB device with the bulk transfer pipe. Bulk Transfers are typically used to transfer large amounts of data to/from USB devices. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceEndpoint The destination USB device endpoint to which the device request is being sent. DeviceEndpoint must be between 0x01 and 0x0F or between 0x81 and 0x8F, otherwise EFI_INVALID_PARAMETER is returned. If the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER is returned. The MSB of this parameter indicates the endpoint direction. The number "1" stands for an IN endpoint, and "0" stands for an OUT endpoint. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength The size, in bytes, of the data buffer specified by Data. On input, the size, in bytes, of the data buffer specified by Data. On output, the number of bytes that were actually transferred. @param Timeout Indicating the transfer should be completed within this time frame. The units are in milliseconds. If Timeout is 0, then the caller must wait for the function to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. @param Status This parameter indicates the USB transfer status. @retval EFI_SUCCESS The bulk transfer has been successfully executed. @retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in Status. @retval EFI_INVALID_PARAMETE One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The control transfer fails due to timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_BULK_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 DeviceEndpoint, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN UINTN Timeout, OUT UINT32 *Status ); /** This function is used to manage a USB device with an interrupt transfer pipe. An Asynchronous Interrupt Transfer is typically used to query a device's status at a fixed rate. For example, keyboard, mouse, and hub devices use this type of transfer to query their interrupt endpoints at a fixed rate. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceEndpoint The destination USB device endpoint to which the device request is being sent. DeviceEndpoint must be between 0x01 and 0x0F or between 0x81 and 0x8F, otherwise EFI_INVALID_PARAMETER is returned. If the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER is returned. The MSB of this parameter indicates the endpoint direction. The number "1" stands for an IN endpoint, and "0" stands for an OUT endpoint. @param IsNewTransfer If TRUE, a new transfer will be submitted to USB controller. If FALSE, the interrupt transfer is deleted from the device's interrupt transfer queue. @param PollingInterval Indicates the periodic rate, in milliseconds, that the transfer is to be executed.This parameter is required when IsNewTransfer is TRUE. The value must be between 1 to 255, otherwise EFI_INVALID_PARAMETER is returned. The units are in milliseconds. @param DataLength Specifies the length, in bytes, of the data to be received from the USB device. This parameter is only required when IsNewTransfer is TRUE. @param InterruptCallback The Callback function. This function is called if the asynchronous interrupt transfer is completed. This parameter is required when IsNewTransfer is TRUE. @param Context Data passed to the InterruptCallback function. This is an optional parameter and may be NULL. @retval EFI_SUCCESS The asynchronous USB transfer request transfer has been successfully executed. @retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 DeviceEndpoint, IN BOOLEAN IsNewTransfer, IN UINTN PollingInterval OPTIONAL, IN UINTN DataLength OPTIONAL, IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack OPTIONAL, IN VOID *Context OPTIONAL ); /** This function is used to manage a USB device with an interrupt transfer pipe. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceEndpoint The destination USB device endpoint to which the device request is being sent. DeviceEndpoint must be between 0x01 and 0x0F or between 0x81 and 0x8F, otherwise EFI_INVALID_PARAMETER is returned. If the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER is returned. The MSB of this parameter indicates the endpoint direction. The number "1" stands for an IN endpoint, and "0" stands for an OUT endpoint. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength On input, then size, in bytes, of the buffer Data. On output, the amount of data actually transferred. @param Timeout The time out, in seconds, for this transfer. If Timeout is 0, then the caller must wait for the function to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. If the transfer is not completed in this time frame, then EFI_TIMEOUT is returned. @param Status This parameter indicates the USB transfer status. @retval EFI_SUCCESS The sync interrupt transfer has been successfully executed. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_DEVICE_ERROR The sync interrupt transfer request failed. @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The transfer fails due to timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_SYNC_INTERRUPT_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 DeviceEndpoint, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN UINTN Timeout, OUT UINT32 *Status ); /** This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous transfer is typically used to transfer streaming data. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceEndpoint The destination USB device endpoint to which the device request is being sent. DeviceEndpoint must be between 0x01 and 0x0F or between 0x81 and 0x8F, otherwise EFI_INVALID_PARAMETER is returned. If the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER is returned. The MSB of this parameter indicates the endpoint direction. The number "1" stands for an IN endpoint, and "0" stands for an OUT endpoint. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength The size, in bytes, of the data buffer specified by Data. @param Status This parameter indicates the USB transfer status. @retval EFI_SUCCESS The isochronous transfer has been successfully executed. @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid. @retval EFI_DEVICE_ERROR The transfer failed due to the reason other than timeout, The error status is returned in Status. @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. @retval EFI_TIMEOUT The transfer fails due to timeout. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_ISOCHRONOUS_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 DeviceEndpoint, IN OUT VOID *Data, IN UINTN DataLength, OUT UINT32 *Status ); /** This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous transfer is typically used to transfer streaming data. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceEndpoint The destination USB device endpoint to which the device request is being sent. DeviceEndpoint must be between 0x01 and 0x0F or between 0x81 and 0x8F, otherwise EFI_INVALID_PARAMETER is returned. If the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER is returned. The MSB of this parameter indicates the endpoint direction. The number "1" stands for an IN endpoint, and "0" stands for an OUT endpoint. @param Data A pointer to the buffer of data that will be transmitted to USB device or received from USB device. @param DataLength The size, in bytes, of the data buffer specified by Data. This is an optional parameter and may be NULL. @param IsochronousCallback The IsochronousCallback() function.This function is called if the requested isochronous transfer is completed. @param Context Data passed to the IsochronousCallback() function. @retval EFI_SUCCESS The asynchronous isochronous transfer has been successfully submitted to the system. @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid. @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 DeviceEndpoint, IN OUT VOID *Data, IN UINTN DataLength, IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, IN VOID *Context OPTIONAL ); /** Resets and reconfigures the USB controller. This function will work for all USB devices except USB Hub Controllers. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @retval EFI_SUCCESS The USB controller was reset. @retval EFI_INVALID_PARAMETER If the controller specified by This is a USB hub. @retval EFI_DEVICE_ERROR An error occurred during the reconfiguration process. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_PORT_RESET)( IN EFI_USB_IO_PROTOCOL *This ); /** Retrieves the USB Device Descriptor. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param DeviceDescriptor A pointer to the caller allocated USB Device Descriptor. @retval EFI_SUCCESS The device descriptor was retrieved successfully. @retval EFI_INVALID_PARAMETER DeviceDescriptor is NULL. @retval EFI_NOT_FOUND The device descriptor was not found. The device may not be configured. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_DEVICE_DESCRIPTOR)( IN EFI_USB_IO_PROTOCOL *This, OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor ); /** Retrieves the USB Device Descriptor. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param ConfigurationDescriptor A pointer to the caller allocated USB Active Configuration Descriptor. @retval EFI_SUCCESS The active configuration descriptor was retrieved successfully. @retval EFI_INVALID_PARAMETER ConfigurationDescriptor is NULL. @retval EFI_NOT_FOUND An active configuration descriptor cannot be found. The device may not be configured. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_CONFIG_DESCRIPTOR)( IN EFI_USB_IO_PROTOCOL *This, OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor ); /** Retrieves the Interface Descriptor for a USB Device Controller. As stated earlier, an interface within a USB device is equivalently to a USB Controller within the current configuration. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param InterfaceDescriptor A pointer to the caller allocated USB Interface Descriptor within the configuration setting. @retval EFI_SUCCESS The interface descriptor retrieved successfully. @retval EFI_INVALID_PARAMETER InterfaceDescriptor is NULL. @retval EFI_NOT_FOUND The interface descriptor cannot be found. The device may not be correctly configured. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_INTERFACE_DESCRIPTOR)( IN EFI_USB_IO_PROTOCOL *This, OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor ); /** Retrieves an Endpoint Descriptor within a USB Controller. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param EndpointIndex Indicates which endpoint descriptor to retrieve. @param EndpointDescriptor A pointer to the caller allocated USB Endpoint Descriptor of a USB controller. @retval EFI_SUCCESS The endpoint descriptor was retrieved successfully. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_NOT_FOUND The endpoint descriptor cannot be found. The device may not be correctly configured. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR)( IN EFI_USB_IO_PROTOCOL *This, IN UINT8 EndpointIndex, OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor ); /** Retrieves a string stored in a USB Device. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param LangID The Language ID for the string being retrieved. @param StringID The ID of the string being retrieved. @param String A pointer to a buffer allocated by this function with AllocatePool() to store the string.If this function returns EFI_SUCCESS, it stores the string the caller wants to get. The caller should release the string buffer with FreePool() after the string is not used any more. @retval EFI_SUCCESS The string was retrieved successfully. @retval EFI_NOT_FOUND The string specified by LangID and StringID was not found. @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the return buffer String. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_STRING_DESCRIPTOR)( IN EFI_USB_IO_PROTOCOL *This, IN UINT16 LangID, IN UINT8 StringID, OUT CHAR16 **String ); /** Retrieves all the language ID codes that the USB device supports. @param This A pointer to the EFI_USB_IO_PROTOCOL instance. @param LangIDTable Language ID for the string the caller wants to get. This is a 16-bit ID defined by Microsoft. This buffer pointer is allocated and maintained by the USB Bus Driver, the caller should not modify its contents. @param TableSize The size, in bytes, of the table LangIDTable. @retval EFI_SUCCESS The support languages were retrieved successfully. **/ typedef EFI_STATUS (EFIAPI *EFI_USB_IO_GET_SUPPORTED_LANGUAGE)( IN EFI_USB_IO_PROTOCOL *This, OUT UINT16 **LangIDTable, OUT UINT16 *TableSize ); /// /// The EFI_USB_IO_PROTOCOL provides four basic transfers types described /// in the USB 1.1 Specification. These include control transfer, interrupt /// transfer, bulk transfer and isochronous transfer. The EFI_USB_IO_PROTOCOL /// also provides some basic USB device/controller management and configuration /// interfaces. A USB device driver uses the services of this protocol to manage USB devices. /// struct _EFI_USB_IO_PROTOCOL { // // IO transfer // EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer; EFI_USB_IO_BULK_TRANSFER UsbBulkTransfer; EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER UsbAsyncInterruptTransfer; EFI_USB_IO_SYNC_INTERRUPT_TRANSFER UsbSyncInterruptTransfer; EFI_USB_IO_ISOCHRONOUS_TRANSFER UsbIsochronousTransfer; EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER UsbAsyncIsochronousTransfer; // // Common device request // EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor; EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor; EFI_USB_IO_GET_INTERFACE_DESCRIPTOR UsbGetInterfaceDescriptor; EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR UsbGetEndpointDescriptor; EFI_USB_IO_GET_STRING_DESCRIPTOR UsbGetStringDescriptor; EFI_USB_IO_GET_SUPPORTED_LANGUAGE UsbGetSupportedLanguages; // // Reset controller's parent port // EFI_USB_IO_PORT_RESET UsbPortReset; }; extern EFI_GUID gEfiUsbIoProtocolGuid; #endif /** @file Variable Architectural Protocol as defined in PI Specification VOLUME 2 DXE This provides the services required to get and set environment variables. This protocol must be produced by a runtime DXE driver and may be consumed only by the DXE Foundation. The DXE driver that produces this protocol must be a runtime driver. This driver is responsible for initializing the GetVariable(), GetNextVariableName(), and SetVariable() fields of the UEFI Runtime Services Table. After the three fields of the UEFI Runtime Services Table have been initialized, the driver must install the EFI_VARIABLE_ARCH_PROTOCOL_GUID on a new handle with a NULL interface pointer. The installation of this protocol informs the DXE Foundation that the read-only and the volatile environment variable related services are now available and that the DXE Foundation must update the 32-bit CRC of the UEFI Runtime Services Table. The full complement of environment variable services are not available until both this protocol and EFI_VARIABLE_WRITE_ARCH_PROTOCOL are installed. DXE drivers that require read-only access or read/write access to volatile environment variables must have this architectural protocol in their dependency expressions. DXE drivers that require write access to nonvolatile environment variables must have the EFI_VARIABLE_WRITE_ARCH_PROTOCOL in their dependency expressions. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_VARIABLE_ARCH_H__ #define __ARCH_PROTOCOL_VARIABLE_ARCH_H__ /// /// Global ID for the Variable Architectural Protocol /// #define EFI_VARIABLE_ARCH_PROTOCOL_GUID \ { 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } extern EFI_GUID gEfiVariableArchProtocolGuid; #endif /** @file Variable Write Architectural Protocol as defined in PI Specification VOLUME 2 DXE This provides the services required to set nonvolatile environment variables. This protocol must be produced by a runtime DXE driver and may be consumed only by the DXE Foundation. The DXE driver that produces this protocol must be a runtime driver. This driver may update the SetVariable() field of the UEFI Runtime Services Table. After the UEFI Runtime Services Table has been initialized, the driver must install the EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID on a new handle with a NULL interface pointer. The installation of this protocol informs the DXE Foundation that the write services for nonvolatile environment variables are now available and that the DXE Foundation must update the 32-bit CRC of the UEFI Runtime Services Table. The full complement of environment variable services are not available until both this protocol and EFI_VARIABLE_ARCH_PROTOCOL are installed. DXE drivers that require read-only access or read/write access to volatile environment variables must have the EFI_VARIABLE_WRITE_ARCH_PROTOCOL in their dependency expressions. DXE drivers that require write access to nonvolatile environment variables must have this architectural protocol in their dependency expressions. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__ #define __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__ /// /// Global ID for the Variable Write Architectural Protocol /// #define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \ { 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53 } } extern EFI_GUID gEfiVariableWriteArchProtocolGuid; #endif /** @file EFI VLAN Config protocol is to provide manageability interface for VLAN configuration. Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: This Protocol is introduced in UEFI Specification 2.2 **/ #ifndef __EFI_VLANCONFIG_PROTOCOL_H__ #define __EFI_VLANCONFIG_PROTOCOL_H__ #define EFI_VLAN_CONFIG_PROTOCOL_GUID \ { \ 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74 } \ } typedef struct _EFI_VLAN_CONFIG_PROTOCOL EFI_VLAN_CONFIG_PROTOCOL; /// /// EFI_VLAN_FIND_DATA /// typedef struct { UINT16 VlanId; ///< Vlan Identifier. UINT8 Priority; ///< Priority of this VLAN. } EFI_VLAN_FIND_DATA; /** Create a VLAN device or modify the configuration parameter of an already-configured VLAN. The Set() function is used to create a new VLAN device or change the VLAN configuration parameters. If the VlanId hasn't been configured in the physical Ethernet device, a new VLAN device will be created. If a VLAN with this VlanId is already configured, then related configuration will be updated as the input parameters. If VlanId is zero, the VLAN device will send and receive untagged frames. Otherwise, the VLAN device will send and receive VLAN-tagged frames containing the VlanId. If VlanId is out of scope of (0-4094), EFI_INVALID_PARAMETER is returned. If Priority is out of the scope of (0-7), then EFI_INVALID_PARAMETER is returned. If there is not enough system memory to perform the registration, then EFI_OUT_OF_RESOURCES is returned. @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. @param[in] VlanId A unique identifier (1-4094) of the VLAN which is being created or modified, or zero (0). @param[in] Priority 3 bit priority in VLAN header. Priority 0 is default value. If VlanId is zero (0), Priority is ignored. @retval EFI_SUCCESS The VLAN is successfully configured. @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: - This is NULL. - VlanId is an invalid VLAN Identifier. - Priority is invalid. @retval EFI_OUT_OF_RESOURCES There is not enough system memory to perform the registration. **/ typedef EFI_STATUS (EFIAPI *EFI_VLAN_CONFIG_SET)( IN EFI_VLAN_CONFIG_PROTOCOL *This, IN UINT16 VlanId, IN UINT8 Priority ); /** Find configuration information for specified VLAN or all configured VLANs. The Find() function is used to find the configuration information for matching VLAN and allocate a buffer into which those entries are copied. @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. @param[in] VlanId Pointer to VLAN identifier. Set to NULL to find all configured VLANs. @param[out] NumberOfVlan The number of VLANs which is found by the specified criteria. @param[out] Entries The buffer which receive the VLAN configuration. @retval EFI_SUCCESS The VLAN is successfully found. @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: - This is NULL. - Specified VlanId is invalid. @retval EFI_NOT_FOUND No matching VLAN is found. **/ typedef EFI_STATUS (EFIAPI *EFI_VLAN_CONFIG_FIND)( IN EFI_VLAN_CONFIG_PROTOCOL *This, IN UINT16 *VlanId OPTIONAL, OUT UINT16 *NumberOfVlan, OUT EFI_VLAN_FIND_DATA **Entries ); /** Remove the configured VLAN device. The Remove() function is used to remove the specified VLAN device. If the VlanId is out of the scope of (0-4094), EFI_INVALID_PARAMETER is returned. If specified VLAN hasn't been previously configured, EFI_NOT_FOUND is returned. @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. @param[in] VlanId Identifier (0-4094) of the VLAN to be removed. @retval EFI_SUCCESS The VLAN is successfully removed. @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: - This is NULL. - VlanId is an invalid parameter. @retval EFI_NOT_FOUND The to-be-removed VLAN does not exist. **/ typedef EFI_STATUS (EFIAPI *EFI_VLAN_CONFIG_REMOVE)( IN EFI_VLAN_CONFIG_PROTOCOL *This, IN UINT16 VlanId ); /// /// EFI_VLAN_CONFIG_PROTOCOL /// provide manageability interface for VLAN setting. The intended /// VLAN tagging implementation is IEEE802.1Q. /// struct _EFI_VLAN_CONFIG_PROTOCOL { EFI_VLAN_CONFIG_SET Set; EFI_VLAN_CONFIG_FIND Find; EFI_VLAN_CONFIG_REMOVE Remove; }; extern EFI_GUID gEfiVlanConfigProtocolGuid; #endif /** @file Watchdog Timer Architectural Protocol as defined in PI Specification VOLUME 2 DXE Used to provide system watchdog timer services Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __ARCH_PROTOCOL_WATCHDOG_TIMER_H__ #define __ARCH_PROTOCOL_WATCHDOG_TIMER_H__ /// /// Global ID for the Watchdog Timer Architectural Protocol /// #define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \ { 0x665E3FF5, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } /// /// Declare forward reference for the Timer Architectural Protocol /// typedef struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL EFI_WATCHDOG_TIMER_ARCH_PROTOCOL; /** A function of this type is called when the watchdog timer fires if a handler has been registered. @param Time The time in 100 ns units that has passed since the watchdog timer was armed. For the notify function to be called, this must be greater than TimerPeriod. @return None. **/ typedef VOID (EFIAPI *EFI_WATCHDOG_TIMER_NOTIFY)( IN UINT64 Time ); /** This function registers a handler that is to be invoked when the watchdog timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the Runtime Service ResetSystem() when the watchdog timer fires. If a NotifyFunction is registered, then the NotifyFunction will be called before the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then the watchdog handler is unregistered. If a watchdog handler is registered, then EFI_SUCCESS is returned. If an attempt is made to register a handler when a handler is already registered, then EFI_ALREADY_STARTED is returned. If an attempt is made to uninstall a handler when a handler is not installed, then return EFI_INVALID_PARAMETER. @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. @param NotifyFunction The function to call when the watchdog timer fires. If this is NULL, then the handler will be unregistered. @retval EFI_SUCCESS The watchdog timer handler was registered or unregistered. @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered. @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered. **/ typedef EFI_STATUS (EFIAPI *EFI_WATCHDOG_TIMER_REGISTER_HANDLER)( IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction ); /** This function sets the amount of time to wait before firing the watchdog timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog timer is disabled. @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog timer is fired. If TimerPeriod is zero, then the watchdog timer is disabled. @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time 100 nS units. @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device error. **/ typedef EFI_STATUS (EFIAPI *EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)( IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, IN UINT64 TimerPeriod ); /** This function retrieves the amount of time the system will wait before firing the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned. @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. @param TimerPeriod A pointer to the amount of time in 100 nS units that the system will wait before the watchdog timer is fired. If TimerPeriod of zero is returned, then the watchdog timer is disabled. @retval EFI_SUCCESS The amount of time that the system will wait before firing the watchdog timer was returned in TimerPeriod. @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)( IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, OUT UINT64 *TimerPeriod ); /// /// This protocol provides the services required to implement the Boot Service /// SetWatchdogTimer(). It provides a service to set the amount of time to wait /// before firing the watchdog timer, and it also provides a service to register /// a handler that is invoked when the watchdog timer fires. This protocol can /// implement the watchdog timer by using the event and timer Boot Services, or /// it can make use of custom hardware. When the watchdog timer fires, control /// will be passed to a handler if one has been registered. If no handler has /// been registered, or the registered handler returns, then the system will be /// reset by calling the Runtime Service ResetSystem(). /// struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL { EFI_WATCHDOG_TIMER_REGISTER_HANDLER RegisterHandler; EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD SetTimerPeriod; EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD GetTimerPeriod; }; extern EFI_GUID gEfiWatchdogTimerArchProtocolGuid; #endif /* $FreeBSD$ */ /*- Files in this directory and subdirectories are subject to the following copyright unless superceded or supplemented by additional specific license terms found in the file headers of individual files. Copyright (c) 1998-2000 Intel Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 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. THIS SOFTWARE IS PROVIDED ``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 INTEL 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. THE EFI SPECIFICATION AND ALL OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE. */ /* * Root include file for Mde Package UEFI, UEFI_APPLICATION type modules. * * This is the include file for any module of type UEFI and UEFI_APPLICATION. * Uefi modules only use types defined via this include file and can be ported * easily to any environment. * * Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
* SPDX-License-Identifier: BSD-2-Clause-Patent * */ #ifndef __PI_UEFI_H__ #define __PI_UEFI_H__ #include #include #endif /* __PI_UEFI_H__ */ /** @file UEFI ACPI Data Table Definition. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_ACPI_DATA_TABLE_H__ #define __UEFI_ACPI_DATA_TABLE_H__ #include #pragma pack(1) typedef struct { EFI_ACPI_DESCRIPTION_HEADER Header; GUID Identifier; UINT16 DataOffset; } EFI_ACPI_DATA_TABLE; #pragma pack() #endif /** @file Defines data types and constants introduced in UEFI. Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_BASETYPE_H__ #define __UEFI_BASETYPE_H__ #include // // Basic data type definitions introduced in UEFI. // /// /// 128-bit buffer containing a unique identifier value. /// typedef GUID EFI_GUID; /// /// Function return status for EFI API. /// typedef RETURN_STATUS EFI_STATUS; /// /// A collection of related interfaces. /// typedef VOID *EFI_HANDLE; /// /// Handle to an event structure. /// typedef VOID *EFI_EVENT; /// /// Task priority level. /// typedef UINTN EFI_TPL; /// /// Logical block address. /// typedef UINT64 EFI_LBA; /// /// 64-bit physical memory address. /// typedef UINT64 EFI_PHYSICAL_ADDRESS; /// /// 64-bit virtual memory address. /// typedef UINT64 EFI_VIRTUAL_ADDRESS; /// /// EFI Time Abstraction: /// Year: 1900 - 9999 /// Month: 1 - 12 /// Day: 1 - 31 /// Hour: 0 - 23 /// Minute: 0 - 59 /// Second: 0 - 59 /// Nanosecond: 0 - 999,999,999 /// TimeZone: -1440 to 1440 or 2047 /// typedef struct { UINT16 Year; UINT8 Month; UINT8 Day; UINT8 Hour; UINT8 Minute; UINT8 Second; UINT8 Pad1; UINT32 Nanosecond; INT16 TimeZone; UINT8 Daylight; UINT8 Pad2; } EFI_TIME; /// /// 4-byte buffer. An IPv4 internet protocol address. /// typedef IPv4_ADDRESS EFI_IPv4_ADDRESS; /// /// 16-byte buffer. An IPv6 internet protocol address. /// typedef IPv6_ADDRESS EFI_IPv6_ADDRESS; /// /// 32-byte buffer containing a network Media Access Control address. /// typedef struct { UINT8 Addr[32]; } EFI_MAC_ADDRESS; /// /// 16-byte buffer aligned on a 4-byte boundary. /// An IPv4 or IPv6 internet protocol address. /// typedef union { UINT32 Addr[4]; EFI_IPv4_ADDRESS v4; EFI_IPv6_ADDRESS v6; } EFI_IP_ADDRESS; /// /// Enumeration of EFI_STATUS. ///@{ #define EFI_SUCCESS RETURN_SUCCESS #define EFI_LOAD_ERROR RETURN_LOAD_ERROR #define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER #define EFI_UNSUPPORTED RETURN_UNSUPPORTED #define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE #define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL #define EFI_NOT_READY RETURN_NOT_READY #define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR #define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED #define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES #define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED #define EFI_VOLUME_FULL RETURN_VOLUME_FULL #define EFI_NO_MEDIA RETURN_NO_MEDIA #define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED #define EFI_NOT_FOUND RETURN_NOT_FOUND #define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED #define EFI_NO_RESPONSE RETURN_NO_RESPONSE #define EFI_NO_MAPPING RETURN_NO_MAPPING #define EFI_TIMEOUT RETURN_TIMEOUT #define EFI_NOT_STARTED RETURN_NOT_STARTED #define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED #define EFI_ABORTED RETURN_ABORTED #define EFI_ICMP_ERROR RETURN_ICMP_ERROR #define EFI_TFTP_ERROR RETURN_TFTP_ERROR #define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR #define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION #define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION #define EFI_CRC_ERROR RETURN_CRC_ERROR #define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA #define EFI_END_OF_FILE RETURN_END_OF_FILE #define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE #define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA #define EFI_HTTP_ERROR RETURN_HTTP_ERROR #define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH #define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE #define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE #define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL #define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA #define EFI_WARN_FILE_SYSTEM RETURN_WARN_FILE_SYSTEM ///@} /// /// Define macro to encode the status code. /// #define EFIERR(_a) ENCODE_ERROR(_a) #define EFI_ERROR(A) RETURN_ERROR(A) /// /// ICMP error definitions ///@{ #define EFI_NETWORK_UNREACHABLE EFIERR(100) #define EFI_HOST_UNREACHABLE EFIERR(101) #define EFI_PROTOCOL_UNREACHABLE EFIERR(102) #define EFI_PORT_UNREACHABLE EFIERR(103) ///@} /// /// Tcp connection status definitions ///@{ #define EFI_CONNECTION_FIN EFIERR(104) #define EFI_CONNECTION_RESET EFIERR(105) #define EFI_CONNECTION_REFUSED EFIERR(106) ///@} // // The EFI memory allocation functions work in units of EFI_PAGEs that are // 4KB. This should in no way be confused with the page size of the processor. // An EFI_PAGE is just the quanta of memory in EFI. // #define EFI_PAGE_SIZE SIZE_4KB #define EFI_PAGE_MASK 0xFFF #define EFI_PAGE_SHIFT 12 /** Macro that converts a size, in bytes, to a number of EFI_PAGESs. @param Size A size in bytes. This parameter is assumed to be type UINTN. Passing in a parameter that is larger than UINTN may produce unexpected results. @return The number of EFI_PAGESs associated with the number of bytes specified by Size. **/ #define EFI_SIZE_TO_PAGES(Size) (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0)) /** Macro that converts a number of EFI_PAGEs to a size in bytes. @param Pages The number of EFI_PAGES. This parameter is assumed to be type UINTN. Passing in a parameter that is larger than UINTN may produce unexpected results. @return The number of bytes associated with the number of EFI_PAGEs specified by Pages. **/ #define EFI_PAGES_TO_SIZE(Pages) ((Pages) << EFI_PAGE_SHIFT) /// /// PE32+ Machine type for IA32 UEFI images. /// #define EFI_IMAGE_MACHINE_IA32 0x014C /// /// PE32+ Machine type for IA64 UEFI images. /// #define EFI_IMAGE_MACHINE_IA64 0x0200 /// /// PE32+ Machine type for EBC UEFI images. /// #define EFI_IMAGE_MACHINE_EBC 0x0EBC /// /// PE32+ Machine type for X64 UEFI images. /// #define EFI_IMAGE_MACHINE_X64 0x8664 /// /// PE32+ Machine type for ARM mixed ARM and Thumb/Thumb2 images. /// #define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2 /// /// PE32+ Machine type for AARCH64 A64 images. /// #define EFI_IMAGE_MACHINE_AARCH64 0xAA64 /// /// PE32+ Machine type for RISC-V 32/64/128 /// #define EFI_IMAGE_MACHINE_RISCV32 0x5032 #define EFI_IMAGE_MACHINE_RISCV64 0x5064 #define EFI_IMAGE_MACHINE_RISCV128 0x5128 #if !defined (EFI_IMAGE_MACHINE_TYPE_VALUE) && !defined (EFI_IMAGE_MACHINE_CROSS_TYPE_VALUE) #if defined (MDE_CPU_IA32) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ ((Machine) == EFI_IMAGE_MACHINE_IA32) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64) #elif defined (MDE_CPU_X64) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ ((Machine) == EFI_IMAGE_MACHINE_X64) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32) #elif defined (MDE_CPU_ARM) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) #elif defined (MDE_CPU_AARCH64) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ ((Machine) == EFI_IMAGE_MACHINE_AARCH64) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) #elif defined (MDE_CPU_RISCV64) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ ((Machine) == EFI_IMAGE_MACHINE_RISCV64) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) #elif defined (MDE_CPU_EBC) /// /// This is just to make sure you can cross compile with the EBC compiler. /// It does not make sense to have a PE loader coded in EBC. /// #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) #else #error Unknown Processor Type #endif #else #if defined (EFI_IMAGE_MACHINE_TYPE_VALUE) #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_TYPE_VALUE) #else #define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) (FALSE) #endif #if defined (EFI_IMAGE_MACHINE_CROSS_TYPE_VALUE) #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_CROSS_TYPE_VALUE) #else #define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) #endif #endif #endif /** @file EFI Guid Partition Table Format Definition. Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_GPT_H__ #define __UEFI_GPT_H__ /// /// The primary GUID Partition Table Header must be /// located in LBA 1 (i.e., the second logical block). /// #define PRIMARY_PART_HEADER_LBA 1 /// /// EFI Partition Table Signature: "EFI PART". /// #define EFI_PTAB_HEADER_ID SIGNATURE_64 ('E','F','I',' ','P','A','R','T') /// /// Minimum bytes reserve for EFI entry array buffer. /// #define EFI_GPT_PART_ENTRY_MIN_SIZE 16384 #pragma pack(1) /// /// GPT Partition Table Header. /// typedef struct { /// /// The table header for the GPT partition Table. /// This header contains EFI_PTAB_HEADER_ID. /// EFI_TABLE_HEADER Header; /// /// The LBA that contains this data structure. /// EFI_LBA MyLBA; /// /// LBA address of the alternate GUID Partition Table Header. /// EFI_LBA AlternateLBA; /// /// The first usable logical block that may be used /// by a partition described by a GUID Partition Entry. /// EFI_LBA FirstUsableLBA; /// /// The last usable logical block that may be used /// by a partition described by a GUID Partition Entry. /// EFI_LBA LastUsableLBA; /// /// GUID that can be used to uniquely identify the disk. /// EFI_GUID DiskGUID; /// /// The starting LBA of the GUID Partition Entry array. /// EFI_LBA PartitionEntryLBA; /// /// The number of Partition Entries in the GUID Partition Entry array. /// UINT32 NumberOfPartitionEntries; /// /// The size, in bytes, of each the GUID Partition /// Entry structures in the GUID Partition Entry /// array. This field shall be set to a value of 128 x 2^n where n is /// an integer greater than or equal to zero (e.g., 128, 256, 512, etc.). /// UINT32 SizeOfPartitionEntry; /// /// The CRC32 of the GUID Partition Entry array. /// Starts at PartitionEntryLBA and is /// computed over a byte length of /// NumberOfPartitionEntries * SizeOfPartitionEntry. /// UINT32 PartitionEntryArrayCRC32; } EFI_PARTITION_TABLE_HEADER; /// /// GPT Partition Entry. /// typedef struct { /// /// Unique ID that defines the purpose and type of this Partition. A value of /// zero defines that this partition entry is not being used. /// EFI_GUID PartitionTypeGUID; /// /// GUID that is unique for every partition entry. Every partition ever /// created will have a unique GUID. /// This GUID must be assigned when the GUID Partition Entry is created. /// EFI_GUID UniquePartitionGUID; /// /// Starting LBA of the partition defined by this entry /// EFI_LBA StartingLBA; /// /// Ending LBA of the partition defined by this entry. /// EFI_LBA EndingLBA; /// /// Attribute bits, all bits reserved by UEFI /// Bit 0: If this bit is set, the partition is required for the platform to function. The owner/creator of the /// partition indicates that deletion or modification of the contents can result in loss of platform /// features or failure for the platform to boot or operate. The system cannot function normally if /// this partition is removed, and it should be considered part of the hardware of the system. /// Actions such as running diagnostics, system recovery, or even OS install or boot, could /// potentially stop working if this partition is removed. Unless OS software or firmware /// recognizes this partition, it should never be removed or modified as the UEFI firmware or /// platform hardware may become non-functional. /// Bit 1: If this bit is set, then firmware must not produce an EFI_BLOCK_IO_PROTOCOL device for /// this partition. By not producing an EFI_BLOCK_IO_PROTOCOL partition, file system /// mappings will not be created for this partition in UEFI. /// Bit 2: This bit is set aside to let systems with traditional PC-AT BIOS firmware implementations /// inform certain limited, special-purpose software running on these systems that a GPT /// partition may be bootable. The UEFI boot manager must ignore this bit when selecting /// a UEFI-compliant application, e.g., an OS loader. /// Bits 3-47: Undefined and must be zero. Reserved for expansion by future versions of the UEFI /// specification. /// Bits 48-63: Reserved for GUID specific use. The use of these bits will vary depending on the /// PartitionTypeGUID. Only the owner of the PartitionTypeGUID is allowed /// to modify these bits. They must be preserved if Bits 0-47 are modified.. /// UINT64 Attributes; /// /// Null-terminated name of the partition. /// CHAR16 PartitionName[36]; } EFI_PARTITION_ENTRY; #pragma pack() #endif /** @file This file defines the encoding for the VFR (Visual Form Representation) language. IFR is primarily consumed by the EFI presentation engine, and produced by EFI internal application and drivers as well as all add-in card option-ROM drivers Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: These definitions are from UEFI 2.1 and 2.2. **/ #ifndef __UEFI_INTERNAL_FORMREPRESENTATION_H__ #define __UEFI_INTERNAL_FORMREPRESENTATION_H__ #include /// /// The following types are currently defined: /// typedef VOID *EFI_HII_HANDLE; typedef CHAR16 *EFI_STRING; typedef UINT16 EFI_IMAGE_ID; typedef UINT16 EFI_QUESTION_ID; typedef UINT16 EFI_STRING_ID; typedef UINT16 EFI_FORM_ID; typedef UINT16 EFI_VARSTORE_ID; typedef UINT16 EFI_ANIMATION_ID; typedef UINT16 EFI_DEFAULT_ID; typedef UINT32 EFI_HII_FONT_STYLE; #pragma pack(1) // // Definitions for Package Lists and Package Headers // Section 27.3.1 // /// /// The header found at the start of each package list. /// typedef struct { EFI_GUID PackageListGuid; UINT32 PackageLength; } EFI_HII_PACKAGE_LIST_HEADER; /// /// The header found at the start of each package. /// typedef struct { UINT32 Length : 24; UINT32 Type : 8; // UINT8 Data[...]; } EFI_HII_PACKAGE_HEADER; // // Value of HII package type // #define EFI_HII_PACKAGE_TYPE_ALL 0x00 #define EFI_HII_PACKAGE_TYPE_GUID 0x01 #define EFI_HII_PACKAGE_FORMS 0x02 #define EFI_HII_PACKAGE_STRINGS 0x04 #define EFI_HII_PACKAGE_FONTS 0x05 #define EFI_HII_PACKAGE_IMAGES 0x06 #define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07 #define EFI_HII_PACKAGE_DEVICE_PATH 0x08 #define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x09 #define EFI_HII_PACKAGE_ANIMATIONS 0x0A #define EFI_HII_PACKAGE_END 0xDF #define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0 #define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF // // Definitions for Simplified Font Package // /// /// Contents of EFI_NARROW_GLYPH.Attributes. ///@{ #define EFI_GLYPH_NON_SPACING 0x01 #define EFI_GLYPH_WIDE 0x02 #define EFI_GLYPH_HEIGHT 19 #define EFI_GLYPH_WIDTH 8 ///@} /// /// The EFI_NARROW_GLYPH has a preferred dimension (w x h) of 8 x 19 pixels. /// typedef struct { /// /// The Unicode representation of the glyph. The term weight is the /// technical term for a character code. /// CHAR16 UnicodeWeight; /// /// The data element containing the glyph definitions. /// UINT8 Attributes; /// /// The column major glyph representation of the character. Bits /// with values of one indicate that the corresponding pixel is to be /// on when normally displayed; those with zero are off. /// UINT8 GlyphCol1[EFI_GLYPH_HEIGHT]; } EFI_NARROW_GLYPH; /// /// The EFI_WIDE_GLYPH has a preferred dimension (w x h) of 16 x 19 pixels, which is large enough /// to accommodate logographic characters. /// typedef struct { /// /// The Unicode representation of the glyph. The term weight is the /// technical term for a character code. /// CHAR16 UnicodeWeight; /// /// The data element containing the glyph definitions. /// UINT8 Attributes; /// /// The column major glyph representation of the character. Bits /// with values of one indicate that the corresponding pixel is to be /// on when normally displayed; those with zero are off. /// UINT8 GlyphCol1[EFI_GLYPH_HEIGHT]; /// /// The column major glyph representation of the character. Bits /// with values of one indicate that the corresponding pixel is to be /// on when normally displayed; those with zero are off. /// UINT8 GlyphCol2[EFI_GLYPH_HEIGHT]; /// /// Ensures that sizeof (EFI_WIDE_GLYPH) is twice the /// sizeof (EFI_NARROW_GLYPH). The contents of Pad must /// be zero. /// UINT8 Pad[3]; } EFI_WIDE_GLYPH; /// /// A simplified font package consists of a font header /// followed by a series of glyph structures. /// typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; UINT16 NumberOfNarrowGlyphs; UINT16 NumberOfWideGlyphs; // EFI_NARROW_GLYPH NarrowGlyphs[]; // EFI_WIDE_GLYPH WideGlyphs[]; } EFI_HII_SIMPLE_FONT_PACKAGE_HDR; // // Definitions for Font Package // Section 27.3.3 // // // Value for font style // #define EFI_HII_FONT_STYLE_NORMAL 0x00000000 #define EFI_HII_FONT_STYLE_BOLD 0x00000001 #define EFI_HII_FONT_STYLE_ITALIC 0x00000002 #define EFI_HII_FONT_STYLE_EMBOSS 0x00010000 #define EFI_HII_FONT_STYLE_OUTLINE 0x00020000 #define EFI_HII_FONT_STYLE_SHADOW 0x00040000 #define EFI_HII_FONT_STYLE_UNDERLINE 0x00080000 #define EFI_HII_FONT_STYLE_DBL_UNDER 0x00100000 typedef struct _EFI_HII_GLYPH_INFO { UINT16 Width; UINT16 Height; INT16 OffsetX; INT16 OffsetY; INT16 AdvanceX; } EFI_HII_GLYPH_INFO; /// /// The fixed header consists of a standard record header, /// then the character values in this section, the flags /// (including the encoding method) and the offsets of the glyph /// information, the glyph bitmaps and the character map. /// typedef struct _EFI_HII_FONT_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; UINT32 HdrSize; UINT32 GlyphBlockOffset; EFI_HII_GLYPH_INFO Cell; EFI_HII_FONT_STYLE FontStyle; CHAR16 FontFamily[1]; } EFI_HII_FONT_PACKAGE_HDR; // // Value of different glyph info block types // #define EFI_HII_GIBT_END 0x00 #define EFI_HII_GIBT_GLYPH 0x10 #define EFI_HII_GIBT_GLYPHS 0x11 #define EFI_HII_GIBT_GLYPH_DEFAULT 0x12 #define EFI_HII_GIBT_GLYPHS_DEFAULT 0x13 #define EFI_HII_GIBT_GLYPH_VARIABILITY 0x14 #define EFI_HII_GIBT_DUPLICATE 0x20 #define EFI_HII_GIBT_SKIP2 0x21 #define EFI_HII_GIBT_SKIP1 0x22 #define EFI_HII_GIBT_DEFAULTS 0x23 #define EFI_HII_GIBT_EXT1 0x30 #define EFI_HII_GIBT_EXT2 0x31 #define EFI_HII_GIBT_EXT4 0x32 typedef struct _EFI_HII_GLYPH_BLOCK { UINT8 BlockType; } EFI_HII_GLYPH_BLOCK; // // Definition of different glyph info block types // typedef struct _EFI_HII_GIBT_DEFAULTS_BLOCK { EFI_HII_GLYPH_BLOCK Header; EFI_HII_GLYPH_INFO Cell; } EFI_HII_GIBT_DEFAULTS_BLOCK; typedef struct _EFI_HII_GIBT_DUPLICATE_BLOCK { EFI_HII_GLYPH_BLOCK Header; CHAR16 CharValue; } EFI_HII_GIBT_DUPLICATE_BLOCK; typedef struct _EFI_GLYPH_GIBT_END_BLOCK { EFI_HII_GLYPH_BLOCK Header; } EFI_GLYPH_GIBT_END_BLOCK; typedef struct _EFI_HII_GIBT_EXT1_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT8 BlockType2; UINT8 Length; } EFI_HII_GIBT_EXT1_BLOCK; typedef struct _EFI_HII_GIBT_EXT2_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT8 BlockType2; UINT16 Length; } EFI_HII_GIBT_EXT2_BLOCK; typedef struct _EFI_HII_GIBT_EXT4_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT8 BlockType2; UINT32 Length; } EFI_HII_GIBT_EXT4_BLOCK; typedef struct _EFI_HII_GIBT_GLYPH_BLOCK { EFI_HII_GLYPH_BLOCK Header; EFI_HII_GLYPH_INFO Cell; UINT8 BitmapData[1]; } EFI_HII_GIBT_GLYPH_BLOCK; typedef struct _EFI_HII_GIBT_GLYPHS_BLOCK { EFI_HII_GLYPH_BLOCK Header; EFI_HII_GLYPH_INFO Cell; UINT16 Count; UINT8 BitmapData[1]; } EFI_HII_GIBT_GLYPHS_BLOCK; typedef struct _EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT8 BitmapData[1]; } EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK; typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT16 Count; UINT8 BitmapData[1]; } EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK; typedef struct _EFI_HII_GIBT_VARIABILITY_BLOCK { EFI_HII_GLYPH_BLOCK Header; EFI_HII_GLYPH_INFO Cell; UINT8 GlyphPackInBits; UINT8 BitmapData[1]; } EFI_HII_GIBT_VARIABILITY_BLOCK; typedef struct _EFI_HII_GIBT_SKIP1_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT8 SkipCount; } EFI_HII_GIBT_SKIP1_BLOCK; typedef struct _EFI_HII_GIBT_SKIP2_BLOCK { EFI_HII_GLYPH_BLOCK Header; UINT16 SkipCount; } EFI_HII_GIBT_SKIP2_BLOCK; // // Definitions for Device Path Package // Section 27.3.4 // /// /// The device path package is used to carry a device path /// associated with the package list. /// typedef struct _EFI_HII_DEVICE_PATH_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; // EFI_DEVICE_PATH_PROTOCOL DevicePath[]; } EFI_HII_DEVICE_PATH_PACKAGE_HDR; // // Definitions for GUID Package // Section 27.3.5 // /// /// The GUID package is used to carry data where the format is defined by a GUID. /// typedef struct _EFI_HII_GUID_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; EFI_GUID Guid; // Data per GUID definition may follow } EFI_HII_GUID_PACKAGE_HDR; // // Definitions for String Package // Section 27.3.6 // #define UEFI_CONFIG_LANG "x-UEFI" #define UEFI_CONFIG_LANG_2 "x-i-UEFI" /// /// The fixed header consists of a standard record header and then the string identifiers /// contained in this section and the offsets of the string and language information. /// typedef struct _EFI_HII_STRING_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; UINT32 HdrSize; UINT32 StringInfoOffset; CHAR16 LanguageWindow[16]; EFI_STRING_ID LanguageName; CHAR8 Language[1]; } EFI_HII_STRING_PACKAGE_HDR; typedef struct { UINT8 BlockType; } EFI_HII_STRING_BLOCK; // // Value of different string information block types // #define EFI_HII_SIBT_END 0x00 #define EFI_HII_SIBT_STRING_SCSU 0x10 #define EFI_HII_SIBT_STRING_SCSU_FONT 0x11 #define EFI_HII_SIBT_STRINGS_SCSU 0x12 #define EFI_HII_SIBT_STRINGS_SCSU_FONT 0x13 #define EFI_HII_SIBT_STRING_UCS2 0x14 #define EFI_HII_SIBT_STRING_UCS2_FONT 0x15 #define EFI_HII_SIBT_STRINGS_UCS2 0x16 #define EFI_HII_SIBT_STRINGS_UCS2_FONT 0x17 #define EFI_HII_SIBT_DUPLICATE 0x20 #define EFI_HII_SIBT_SKIP2 0x21 #define EFI_HII_SIBT_SKIP1 0x22 #define EFI_HII_SIBT_EXT1 0x30 #define EFI_HII_SIBT_EXT2 0x31 #define EFI_HII_SIBT_EXT4 0x32 #define EFI_HII_SIBT_FONT 0x40 // // Definition of different string information block types // typedef struct _EFI_HII_SIBT_DUPLICATE_BLOCK { EFI_HII_STRING_BLOCK Header; EFI_STRING_ID StringId; } EFI_HII_SIBT_DUPLICATE_BLOCK; typedef struct _EFI_HII_SIBT_END_BLOCK { EFI_HII_STRING_BLOCK Header; } EFI_HII_SIBT_END_BLOCK; typedef struct _EFI_HII_SIBT_EXT1_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 BlockType2; UINT8 Length; } EFI_HII_SIBT_EXT1_BLOCK; typedef struct _EFI_HII_SIBT_EXT2_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 BlockType2; UINT16 Length; } EFI_HII_SIBT_EXT2_BLOCK; typedef struct _EFI_HII_SIBT_EXT4_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 BlockType2; UINT32 Length; } EFI_HII_SIBT_EXT4_BLOCK; typedef struct _EFI_HII_SIBT_FONT_BLOCK { EFI_HII_SIBT_EXT2_BLOCK Header; UINT8 FontId; UINT16 FontSize; EFI_HII_FONT_STYLE FontStyle; CHAR16 FontName[1]; } EFI_HII_SIBT_FONT_BLOCK; typedef struct _EFI_HII_SIBT_SKIP1_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 SkipCount; } EFI_HII_SIBT_SKIP1_BLOCK; typedef struct _EFI_HII_SIBT_SKIP2_BLOCK { EFI_HII_STRING_BLOCK Header; UINT16 SkipCount; } EFI_HII_SIBT_SKIP2_BLOCK; typedef struct _EFI_HII_SIBT_STRING_SCSU_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 StringText[1]; } EFI_HII_SIBT_STRING_SCSU_BLOCK; typedef struct _EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 FontIdentifier; UINT8 StringText[1]; } EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK; typedef struct _EFI_HII_SIBT_STRINGS_SCSU_BLOCK { EFI_HII_STRING_BLOCK Header; UINT16 StringCount; UINT8 StringText[1]; } EFI_HII_SIBT_STRINGS_SCSU_BLOCK; typedef struct _EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 FontIdentifier; UINT16 StringCount; UINT8 StringText[1]; } EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK; typedef struct _EFI_HII_SIBT_STRING_UCS2_BLOCK { EFI_HII_STRING_BLOCK Header; CHAR16 StringText[1]; } EFI_HII_SIBT_STRING_UCS2_BLOCK; typedef struct _EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 FontIdentifier; CHAR16 StringText[1]; } EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK; typedef struct _EFI_HII_SIBT_STRINGS_UCS2_BLOCK { EFI_HII_STRING_BLOCK Header; UINT16 StringCount; CHAR16 StringText[1]; } EFI_HII_SIBT_STRINGS_UCS2_BLOCK; typedef struct _EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK { EFI_HII_STRING_BLOCK Header; UINT8 FontIdentifier; UINT16 StringCount; CHAR16 StringText[1]; } EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK; // // Definitions for Image Package // Section 27.3.7 // typedef struct _EFI_HII_IMAGE_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; UINT32 ImageInfoOffset; UINT32 PaletteInfoOffset; } EFI_HII_IMAGE_PACKAGE_HDR; typedef struct _EFI_HII_IMAGE_BLOCK { UINT8 BlockType; } EFI_HII_IMAGE_BLOCK; // // Value of different image information block types // #define EFI_HII_IIBT_END 0x00 #define EFI_HII_IIBT_IMAGE_1BIT 0x10 #define EFI_HII_IIBT_IMAGE_1BIT_TRANS 0x11 #define EFI_HII_IIBT_IMAGE_4BIT 0x12 #define EFI_HII_IIBT_IMAGE_4BIT_TRANS 0x13 #define EFI_HII_IIBT_IMAGE_8BIT 0x14 #define EFI_HII_IIBT_IMAGE_8BIT_TRANS 0x15 #define EFI_HII_IIBT_IMAGE_24BIT 0x16 #define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17 #define EFI_HII_IIBT_IMAGE_JPEG 0x18 #define EFI_HII_IIBT_IMAGE_PNG 0x19 #define EFI_HII_IIBT_DUPLICATE 0x20 #define EFI_HII_IIBT_SKIP2 0x21 #define EFI_HII_IIBT_SKIP1 0x22 #define EFI_HII_IIBT_EXT1 0x30 #define EFI_HII_IIBT_EXT2 0x31 #define EFI_HII_IIBT_EXT4 0x32 // // Definition of different image information block types // typedef struct _EFI_HII_IIBT_END_BLOCK { EFI_HII_IMAGE_BLOCK Header; } EFI_HII_IIBT_END_BLOCK; typedef struct _EFI_HII_IIBT_EXT1_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 BlockType2; UINT8 Length; } EFI_HII_IIBT_EXT1_BLOCK; typedef struct _EFI_HII_IIBT_EXT2_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 BlockType2; UINT16 Length; } EFI_HII_IIBT_EXT2_BLOCK; typedef struct _EFI_HII_IIBT_EXT4_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 BlockType2; UINT32 Length; } EFI_HII_IIBT_EXT4_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BASE { UINT16 Width; UINT16 Height; UINT8 Data[1]; } EFI_HII_IIBT_IMAGE_1BIT_BASE; typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_1BIT_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK; typedef struct _EFI_HII_RGB_PIXEL { UINT8 b; UINT8 g; UINT8 r; } EFI_HII_RGB_PIXEL; typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BASE { UINT16 Width; UINT16 Height; EFI_HII_RGB_PIXEL Bitmap[1]; } EFI_HII_IIBT_IMAGE_24BIT_BASE; typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BLOCK { EFI_HII_IMAGE_BLOCK Header; EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_24BIT_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK { EFI_HII_IMAGE_BLOCK Header; EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BASE { UINT16 Width; UINT16 Height; UINT8 Data[1]; } EFI_HII_IIBT_IMAGE_4BIT_BASE; typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_4BIT_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_8BIT_BASE { UINT16 Width; UINT16 Height; UINT8 Data[1]; } EFI_HII_IIBT_IMAGE_8BIT_BASE; typedef struct _EFI_HII_IIBT_IMAGE_8BIT_PALETTE_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_8BIT_BLOCK; typedef struct _EFI_HII_IIBT_IMAGE_8BIT_TRANS_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 PaletteIndex; EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap; } EFI_HII_IIBT_IMAGE_8BIT_TRAN_BLOCK; typedef struct _EFI_HII_IIBT_DUPLICATE_BLOCK { EFI_HII_IMAGE_BLOCK Header; EFI_IMAGE_ID ImageId; } EFI_HII_IIBT_DUPLICATE_BLOCK; typedef struct _EFI_HII_IIBT_JPEG_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT32 Size; UINT8 Data[1]; } EFI_HII_IIBT_JPEG_BLOCK; typedef struct _EFI_HII_IIBT_PNG_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT32 Size; UINT8 Data[1]; } EFI_HII_IIBT_PNG_BLOCK; typedef struct _EFI_HII_IIBT_SKIP1_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT8 SkipCount; } EFI_HII_IIBT_SKIP1_BLOCK; typedef struct _EFI_HII_IIBT_SKIP2_BLOCK { EFI_HII_IMAGE_BLOCK Header; UINT16 SkipCount; } EFI_HII_IIBT_SKIP2_BLOCK; // // Definitions for Palette Information // typedef struct _EFI_HII_IMAGE_PALETTE_INFO_HEADER { UINT16 PaletteCount; } EFI_HII_IMAGE_PALETTE_INFO_HEADER; typedef struct _EFI_HII_IMAGE_PALETTE_INFO { UINT16 PaletteSize; EFI_HII_RGB_PIXEL PaletteValue[1]; } EFI_HII_IMAGE_PALETTE_INFO; // // Definitions for Forms Package // Section 27.3.8 // /// /// The Form package is used to carry form-based encoding data. /// typedef struct _EFI_HII_FORM_PACKAGE_HDR { EFI_HII_PACKAGE_HEADER Header; // EFI_IFR_OP_HEADER OpCodeHeader; // More op-codes follow } EFI_HII_FORM_PACKAGE_HDR; typedef struct { UINT8 Hour; UINT8 Minute; UINT8 Second; } EFI_HII_TIME; typedef struct { UINT16 Year; UINT8 Month; UINT8 Day; } EFI_HII_DATE; typedef struct { EFI_QUESTION_ID QuestionId; EFI_FORM_ID FormId; EFI_GUID FormSetGuid; EFI_STRING_ID DevicePath; } EFI_HII_REF; typedef union { UINT8 u8; UINT16 u16; UINT32 u32; UINT64 u64; BOOLEAN b; EFI_HII_TIME time; EFI_HII_DATE date; EFI_STRING_ID string; ///< EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION EFI_HII_REF ref; ///< EFI_IFR_TYPE_REF // UINT8 buffer[]; ///< EFI_IFR_TYPE_BUFFER } EFI_IFR_TYPE_VALUE; // // IFR Opcodes // #define EFI_IFR_FORM_OP 0x01 #define EFI_IFR_SUBTITLE_OP 0x02 #define EFI_IFR_TEXT_OP 0x03 #define EFI_IFR_IMAGE_OP 0x04 #define EFI_IFR_ONE_OF_OP 0x05 #define EFI_IFR_CHECKBOX_OP 0x06 #define EFI_IFR_NUMERIC_OP 0x07 #define EFI_IFR_PASSWORD_OP 0x08 #define EFI_IFR_ONE_OF_OPTION_OP 0x09 #define EFI_IFR_SUPPRESS_IF_OP 0x0A #define EFI_IFR_LOCKED_OP 0x0B #define EFI_IFR_ACTION_OP 0x0C #define EFI_IFR_RESET_BUTTON_OP 0x0D #define EFI_IFR_FORM_SET_OP 0x0E #define EFI_IFR_REF_OP 0x0F #define EFI_IFR_NO_SUBMIT_IF_OP 0x10 #define EFI_IFR_INCONSISTENT_IF_OP 0x11 #define EFI_IFR_EQ_ID_VAL_OP 0x12 #define EFI_IFR_EQ_ID_ID_OP 0x13 #define EFI_IFR_EQ_ID_VAL_LIST_OP 0x14 #define EFI_IFR_AND_OP 0x15 #define EFI_IFR_OR_OP 0x16 #define EFI_IFR_NOT_OP 0x17 #define EFI_IFR_RULE_OP 0x18 #define EFI_IFR_GRAY_OUT_IF_OP 0x19 #define EFI_IFR_DATE_OP 0x1A #define EFI_IFR_TIME_OP 0x1B #define EFI_IFR_STRING_OP 0x1C #define EFI_IFR_REFRESH_OP 0x1D #define EFI_IFR_DISABLE_IF_OP 0x1E #define EFI_IFR_ANIMATION_OP 0x1F #define EFI_IFR_TO_LOWER_OP 0x20 #define EFI_IFR_TO_UPPER_OP 0x21 #define EFI_IFR_MAP_OP 0x22 #define EFI_IFR_ORDERED_LIST_OP 0x23 #define EFI_IFR_VARSTORE_OP 0x24 #define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25 #define EFI_IFR_VARSTORE_EFI_OP 0x26 #define EFI_IFR_VARSTORE_DEVICE_OP 0x27 #define EFI_IFR_VERSION_OP 0x28 #define EFI_IFR_END_OP 0x29 #define EFI_IFR_MATCH_OP 0x2A #define EFI_IFR_GET_OP 0x2B #define EFI_IFR_SET_OP 0x2C #define EFI_IFR_READ_OP 0x2D #define EFI_IFR_WRITE_OP 0x2E #define EFI_IFR_EQUAL_OP 0x2F #define EFI_IFR_NOT_EQUAL_OP 0x30 #define EFI_IFR_GREATER_THAN_OP 0x31 #define EFI_IFR_GREATER_EQUAL_OP 0x32 #define EFI_IFR_LESS_THAN_OP 0x33 #define EFI_IFR_LESS_EQUAL_OP 0x34 #define EFI_IFR_BITWISE_AND_OP 0x35 #define EFI_IFR_BITWISE_OR_OP 0x36 #define EFI_IFR_BITWISE_NOT_OP 0x37 #define EFI_IFR_SHIFT_LEFT_OP 0x38 #define EFI_IFR_SHIFT_RIGHT_OP 0x39 #define EFI_IFR_ADD_OP 0x3A #define EFI_IFR_SUBTRACT_OP 0x3B #define EFI_IFR_MULTIPLY_OP 0x3C #define EFI_IFR_DIVIDE_OP 0x3D #define EFI_IFR_MODULO_OP 0x3E #define EFI_IFR_RULE_REF_OP 0x3F #define EFI_IFR_QUESTION_REF1_OP 0x40 #define EFI_IFR_QUESTION_REF2_OP 0x41 #define EFI_IFR_UINT8_OP 0x42 #define EFI_IFR_UINT16_OP 0x43 #define EFI_IFR_UINT32_OP 0x44 #define EFI_IFR_UINT64_OP 0x45 #define EFI_IFR_TRUE_OP 0x46 #define EFI_IFR_FALSE_OP 0x47 #define EFI_IFR_TO_UINT_OP 0x48 #define EFI_IFR_TO_STRING_OP 0x49 #define EFI_IFR_TO_BOOLEAN_OP 0x4A #define EFI_IFR_MID_OP 0x4B #define EFI_IFR_FIND_OP 0x4C #define EFI_IFR_TOKEN_OP 0x4D #define EFI_IFR_STRING_REF1_OP 0x4E #define EFI_IFR_STRING_REF2_OP 0x4F #define EFI_IFR_CONDITIONAL_OP 0x50 #define EFI_IFR_QUESTION_REF3_OP 0x51 #define EFI_IFR_ZERO_OP 0x52 #define EFI_IFR_ONE_OP 0x53 #define EFI_IFR_ONES_OP 0x54 #define EFI_IFR_UNDEFINED_OP 0x55 #define EFI_IFR_LENGTH_OP 0x56 #define EFI_IFR_DUP_OP 0x57 #define EFI_IFR_THIS_OP 0x58 #define EFI_IFR_SPAN_OP 0x59 #define EFI_IFR_VALUE_OP 0x5A #define EFI_IFR_DEFAULT_OP 0x5B #define EFI_IFR_DEFAULTSTORE_OP 0x5C #define EFI_IFR_FORM_MAP_OP 0x5D #define EFI_IFR_CATENATE_OP 0x5E #define EFI_IFR_GUID_OP 0x5F #define EFI_IFR_SECURITY_OP 0x60 #define EFI_IFR_MODAL_TAG_OP 0x61 #define EFI_IFR_REFRESH_ID_OP 0x62 #define EFI_IFR_WARNING_IF_OP 0x63 #define EFI_IFR_MATCH2_OP 0x64 // // Definitions of IFR Standard Headers // Section 27.3.8.2 // typedef struct _EFI_IFR_OP_HEADER { UINT8 OpCode; UINT8 Length : 7; UINT8 Scope : 1; } EFI_IFR_OP_HEADER; typedef struct _EFI_IFR_STATEMENT_HEADER { EFI_STRING_ID Prompt; EFI_STRING_ID Help; } EFI_IFR_STATEMENT_HEADER; typedef struct _EFI_IFR_QUESTION_HEADER { EFI_IFR_STATEMENT_HEADER Header; EFI_QUESTION_ID QuestionId; EFI_VARSTORE_ID VarStoreId; union { EFI_STRING_ID VarName; UINT16 VarOffset; } VarStoreInfo; UINT8 Flags; } EFI_IFR_QUESTION_HEADER; // // Flag values of EFI_IFR_QUESTION_HEADER // #define EFI_IFR_FLAG_READ_ONLY 0x01 #define EFI_IFR_FLAG_CALLBACK 0x04 #define EFI_IFR_FLAG_RESET_REQUIRED 0x10 #define EFI_IFR_FLAG_REST_STYLE 0x20 #define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40 #define EFI_IFR_FLAG_OPTIONS_ONLY 0x80 // // Definition for Opcode Reference // Section 27.3.8.3 // typedef struct _EFI_IFR_DEFAULTSTORE { EFI_IFR_OP_HEADER Header; EFI_STRING_ID DefaultName; UINT16 DefaultId; } EFI_IFR_DEFAULTSTORE; // // Default Identifier of default store // #define EFI_HII_DEFAULT_CLASS_STANDARD 0x0000 #define EFI_HII_DEFAULT_CLASS_MANUFACTURING 0x0001 #define EFI_HII_DEFAULT_CLASS_SAFE 0x0002 #define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000 #define EFI_HII_DEFAULT_CLASS_PLATFORM_END 0x7fff #define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000 #define EFI_HII_DEFAULT_CLASS_HARDWARE_END 0xbfff #define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000 #define EFI_HII_DEFAULT_CLASS_FIRMWARE_END 0xffff typedef struct _EFI_IFR_VARSTORE { EFI_IFR_OP_HEADER Header; EFI_GUID Guid; EFI_VARSTORE_ID VarStoreId; UINT16 Size; UINT8 Name[1]; } EFI_IFR_VARSTORE; typedef struct _EFI_IFR_VARSTORE_EFI { EFI_IFR_OP_HEADER Header; EFI_VARSTORE_ID VarStoreId; EFI_GUID Guid; UINT32 Attributes; UINT16 Size; UINT8 Name[1]; } EFI_IFR_VARSTORE_EFI; typedef struct _EFI_IFR_VARSTORE_NAME_VALUE { EFI_IFR_OP_HEADER Header; EFI_VARSTORE_ID VarStoreId; EFI_GUID Guid; } EFI_IFR_VARSTORE_NAME_VALUE; typedef struct _EFI_IFR_FORM_SET { EFI_IFR_OP_HEADER Header; EFI_GUID Guid; EFI_STRING_ID FormSetTitle; EFI_STRING_ID Help; UINT8 Flags; // EFI_GUID ClassGuid[]; } EFI_IFR_FORM_SET; typedef struct _EFI_IFR_END { EFI_IFR_OP_HEADER Header; } EFI_IFR_END; typedef struct _EFI_IFR_FORM { EFI_IFR_OP_HEADER Header; UINT16 FormId; EFI_STRING_ID FormTitle; } EFI_IFR_FORM; typedef struct _EFI_IFR_IMAGE { EFI_IFR_OP_HEADER Header; EFI_IMAGE_ID Id; } EFI_IFR_IMAGE; typedef struct _EFI_IFR_MODAL_TAG { EFI_IFR_OP_HEADER Header; } EFI_IFR_MODAL_TAG; typedef struct _EFI_IFR_LOCKED { EFI_IFR_OP_HEADER Header; } EFI_IFR_LOCKED; typedef struct _EFI_IFR_RULE { EFI_IFR_OP_HEADER Header; UINT8 RuleId; } EFI_IFR_RULE; typedef struct _EFI_IFR_DEFAULT { EFI_IFR_OP_HEADER Header; UINT16 DefaultId; UINT8 Type; EFI_IFR_TYPE_VALUE Value; } EFI_IFR_DEFAULT; typedef struct _EFI_IFR_DEFAULT_2 { EFI_IFR_OP_HEADER Header; UINT16 DefaultId; UINT8 Type; } EFI_IFR_DEFAULT_2; typedef struct _EFI_IFR_VALUE { EFI_IFR_OP_HEADER Header; } EFI_IFR_VALUE; typedef struct _EFI_IFR_SUBTITLE { EFI_IFR_OP_HEADER Header; EFI_IFR_STATEMENT_HEADER Statement; UINT8 Flags; } EFI_IFR_SUBTITLE; #define EFI_IFR_FLAGS_HORIZONTAL 0x01 typedef struct _EFI_IFR_CHECKBOX { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 Flags; } EFI_IFR_CHECKBOX; #define EFI_IFR_CHECKBOX_DEFAULT 0x01 #define EFI_IFR_CHECKBOX_DEFAULT_MFG 0x02 typedef struct _EFI_IFR_TEXT { EFI_IFR_OP_HEADER Header; EFI_IFR_STATEMENT_HEADER Statement; EFI_STRING_ID TextTwo; } EFI_IFR_TEXT; typedef struct _EFI_IFR_REF { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; EFI_FORM_ID FormId; } EFI_IFR_REF; typedef struct _EFI_IFR_REF2 { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; EFI_FORM_ID FormId; EFI_QUESTION_ID QuestionId; } EFI_IFR_REF2; typedef struct _EFI_IFR_REF3 { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; EFI_FORM_ID FormId; EFI_QUESTION_ID QuestionId; EFI_GUID FormSetId; } EFI_IFR_REF3; typedef struct _EFI_IFR_REF4 { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; EFI_FORM_ID FormId; EFI_QUESTION_ID QuestionId; EFI_GUID FormSetId; EFI_STRING_ID DevicePath; } EFI_IFR_REF4; typedef struct _EFI_IFR_REF5 { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; } EFI_IFR_REF5; typedef struct _EFI_IFR_RESET_BUTTON { EFI_IFR_OP_HEADER Header; EFI_IFR_STATEMENT_HEADER Statement; EFI_DEFAULT_ID DefaultId; } EFI_IFR_RESET_BUTTON; typedef struct _EFI_IFR_ACTION { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; EFI_STRING_ID QuestionConfig; } EFI_IFR_ACTION; typedef struct _EFI_IFR_ACTION_1 { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; } EFI_IFR_ACTION_1; typedef struct _EFI_IFR_DATE { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 Flags; } EFI_IFR_DATE; // // Flags that describe the behavior of the question. // #define EFI_QF_DATE_YEAR_SUPPRESS 0x01 #define EFI_QF_DATE_MONTH_SUPPRESS 0x02 #define EFI_QF_DATE_DAY_SUPPRESS 0x04 #define EFI_QF_DATE_STORAGE 0x30 #define QF_DATE_STORAGE_NORMAL 0x00 #define QF_DATE_STORAGE_TIME 0x10 #define QF_DATE_STORAGE_WAKEUP 0x20 typedef union { struct { UINT8 MinValue; UINT8 MaxValue; UINT8 Step; } u8; struct { UINT16 MinValue; UINT16 MaxValue; UINT16 Step; } u16; struct { UINT32 MinValue; UINT32 MaxValue; UINT32 Step; } u32; struct { UINT64 MinValue; UINT64 MaxValue; UINT64 Step; } u64; } MINMAXSTEP_DATA; typedef struct _EFI_IFR_NUMERIC { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 Flags; MINMAXSTEP_DATA data; } EFI_IFR_NUMERIC; // // Flags related to the numeric question // #define EFI_IFR_NUMERIC_SIZE 0x03 #define EFI_IFR_NUMERIC_SIZE_1 0x00 #define EFI_IFR_NUMERIC_SIZE_2 0x01 #define EFI_IFR_NUMERIC_SIZE_4 0x02 #define EFI_IFR_NUMERIC_SIZE_8 0x03 #define EFI_IFR_DISPLAY 0x30 #define EFI_IFR_DISPLAY_INT_DEC 0x00 #define EFI_IFR_DISPLAY_UINT_DEC 0x10 #define EFI_IFR_DISPLAY_UINT_HEX 0x20 typedef struct _EFI_IFR_ONE_OF { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 Flags; MINMAXSTEP_DATA data; } EFI_IFR_ONE_OF; typedef struct _EFI_IFR_STRING { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 MinSize; UINT8 MaxSize; UINT8 Flags; } EFI_IFR_STRING; #define EFI_IFR_STRING_MULTI_LINE 0x01 typedef struct _EFI_IFR_PASSWORD { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT16 MinSize; UINT16 MaxSize; } EFI_IFR_PASSWORD; typedef struct _EFI_IFR_ORDERED_LIST { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 MaxContainers; UINT8 Flags; } EFI_IFR_ORDERED_LIST; #define EFI_IFR_UNIQUE_SET 0x01 #define EFI_IFR_NO_EMPTY_SET 0x02 typedef struct _EFI_IFR_TIME { EFI_IFR_OP_HEADER Header; EFI_IFR_QUESTION_HEADER Question; UINT8 Flags; } EFI_IFR_TIME; // // A bit-mask that determines which unique settings are active for this opcode. // #define QF_TIME_HOUR_SUPPRESS 0x01 #define QF_TIME_MINUTE_SUPPRESS 0x02 #define QF_TIME_SECOND_SUPPRESS 0x04 #define QF_TIME_STORAGE 0x30 #define QF_TIME_STORAGE_NORMAL 0x00 #define QF_TIME_STORAGE_TIME 0x10 #define QF_TIME_STORAGE_WAKEUP 0x20 typedef struct _EFI_IFR_DISABLE_IF { EFI_IFR_OP_HEADER Header; } EFI_IFR_DISABLE_IF; typedef struct _EFI_IFR_SUPPRESS_IF { EFI_IFR_OP_HEADER Header; } EFI_IFR_SUPPRESS_IF; typedef struct _EFI_IFR_GRAY_OUT_IF { EFI_IFR_OP_HEADER Header; } EFI_IFR_GRAY_OUT_IF; typedef struct _EFI_IFR_INCONSISTENT_IF { EFI_IFR_OP_HEADER Header; EFI_STRING_ID Error; } EFI_IFR_INCONSISTENT_IF; typedef struct _EFI_IFR_NO_SUBMIT_IF { EFI_IFR_OP_HEADER Header; EFI_STRING_ID Error; } EFI_IFR_NO_SUBMIT_IF; typedef struct _EFI_IFR_WARNING_IF { EFI_IFR_OP_HEADER Header; EFI_STRING_ID Warning; UINT8 TimeOut; } EFI_IFR_WARNING_IF; typedef struct _EFI_IFR_REFRESH { EFI_IFR_OP_HEADER Header; UINT8 RefreshInterval; } EFI_IFR_REFRESH; typedef struct _EFI_IFR_VARSTORE_DEVICE { EFI_IFR_OP_HEADER Header; EFI_STRING_ID DevicePath; } EFI_IFR_VARSTORE_DEVICE; typedef struct _EFI_IFR_ONE_OF_OPTION { EFI_IFR_OP_HEADER Header; EFI_STRING_ID Option; UINT8 Flags; UINT8 Type; EFI_IFR_TYPE_VALUE Value; } EFI_IFR_ONE_OF_OPTION; // // Types of the option's value. // #define EFI_IFR_TYPE_NUM_SIZE_8 0x00 #define EFI_IFR_TYPE_NUM_SIZE_16 0x01 #define EFI_IFR_TYPE_NUM_SIZE_32 0x02 #define EFI_IFR_TYPE_NUM_SIZE_64 0x03 #define EFI_IFR_TYPE_BOOLEAN 0x04 #define EFI_IFR_TYPE_TIME 0x05 #define EFI_IFR_TYPE_DATE 0x06 #define EFI_IFR_TYPE_STRING 0x07 #define EFI_IFR_TYPE_OTHER 0x08 #define EFI_IFR_TYPE_UNDEFINED 0x09 #define EFI_IFR_TYPE_ACTION 0x0A #define EFI_IFR_TYPE_BUFFER 0x0B #define EFI_IFR_TYPE_REF 0x0C #define EFI_IFR_OPTION_DEFAULT 0x10 #define EFI_IFR_OPTION_DEFAULT_MFG 0x20 typedef struct _EFI_IFR_GUID { EFI_IFR_OP_HEADER Header; EFI_GUID Guid; // Optional Data Follows } EFI_IFR_GUID; typedef struct _EFI_IFR_REFRESH_ID { EFI_IFR_OP_HEADER Header; EFI_GUID RefreshEventGroupId; } EFI_IFR_REFRESH_ID; typedef struct _EFI_IFR_DUP { EFI_IFR_OP_HEADER Header; } EFI_IFR_DUP; typedef struct _EFI_IFR_EQ_ID_ID { EFI_IFR_OP_HEADER Header; EFI_QUESTION_ID QuestionId1; EFI_QUESTION_ID QuestionId2; } EFI_IFR_EQ_ID_ID; typedef struct _EFI_IFR_EQ_ID_VAL { EFI_IFR_OP_HEADER Header; EFI_QUESTION_ID QuestionId; UINT16 Value; } EFI_IFR_EQ_ID_VAL; typedef struct _EFI_IFR_EQ_ID_VAL_LIST { EFI_IFR_OP_HEADER Header; EFI_QUESTION_ID QuestionId; UINT16 ListLength; UINT16 ValueList[1]; } EFI_IFR_EQ_ID_VAL_LIST; typedef struct _EFI_IFR_UINT8 { EFI_IFR_OP_HEADER Header; UINT8 Value; } EFI_IFR_UINT8; typedef struct _EFI_IFR_UINT16 { EFI_IFR_OP_HEADER Header; UINT16 Value; } EFI_IFR_UINT16; typedef struct _EFI_IFR_UINT32 { EFI_IFR_OP_HEADER Header; UINT32 Value; } EFI_IFR_UINT32; typedef struct _EFI_IFR_UINT64 { EFI_IFR_OP_HEADER Header; UINT64 Value; } EFI_IFR_UINT64; typedef struct _EFI_IFR_QUESTION_REF1 { EFI_IFR_OP_HEADER Header; EFI_QUESTION_ID QuestionId; } EFI_IFR_QUESTION_REF1; typedef struct _EFI_IFR_QUESTION_REF2 { EFI_IFR_OP_HEADER Header; } EFI_IFR_QUESTION_REF2; typedef struct _EFI_IFR_QUESTION_REF3 { EFI_IFR_OP_HEADER Header; } EFI_IFR_QUESTION_REF3; typedef struct _EFI_IFR_QUESTION_REF3_2 { EFI_IFR_OP_HEADER Header; EFI_STRING_ID DevicePath; } EFI_IFR_QUESTION_REF3_2; typedef struct _EFI_IFR_QUESTION_REF3_3 { EFI_IFR_OP_HEADER Header; EFI_STRING_ID DevicePath; EFI_GUID Guid; } EFI_IFR_QUESTION_REF3_3; typedef struct _EFI_IFR_RULE_REF { EFI_IFR_OP_HEADER Header; UINT8 RuleId; } EFI_IFR_RULE_REF; typedef struct _EFI_IFR_STRING_REF1 { EFI_IFR_OP_HEADER Header; EFI_STRING_ID StringId; } EFI_IFR_STRING_REF1; typedef struct _EFI_IFR_STRING_REF2 { EFI_IFR_OP_HEADER Header; } EFI_IFR_STRING_REF2; typedef struct _EFI_IFR_THIS { EFI_IFR_OP_HEADER Header; } EFI_IFR_THIS; typedef struct _EFI_IFR_TRUE { EFI_IFR_OP_HEADER Header; } EFI_IFR_TRUE; typedef struct _EFI_IFR_FALSE { EFI_IFR_OP_HEADER Header; } EFI_IFR_FALSE; typedef struct _EFI_IFR_ONE { EFI_IFR_OP_HEADER Header; } EFI_IFR_ONE; typedef struct _EFI_IFR_ONES { EFI_IFR_OP_HEADER Header; } EFI_IFR_ONES; typedef struct _EFI_IFR_ZERO { EFI_IFR_OP_HEADER Header; } EFI_IFR_ZERO; typedef struct _EFI_IFR_UNDEFINED { EFI_IFR_OP_HEADER Header; } EFI_IFR_UNDEFINED; typedef struct _EFI_IFR_VERSION { EFI_IFR_OP_HEADER Header; } EFI_IFR_VERSION; typedef struct _EFI_IFR_LENGTH { EFI_IFR_OP_HEADER Header; } EFI_IFR_LENGTH; typedef struct _EFI_IFR_NOT { EFI_IFR_OP_HEADER Header; } EFI_IFR_NOT; typedef struct _EFI_IFR_BITWISE_NOT { EFI_IFR_OP_HEADER Header; } EFI_IFR_BITWISE_NOT; typedef struct _EFI_IFR_TO_BOOLEAN { EFI_IFR_OP_HEADER Header; } EFI_IFR_TO_BOOLEAN; /// /// For EFI_IFR_TO_STRING, when converting from /// unsigned integers, these flags control the format: /// 0 = unsigned decimal. /// 1 = signed decimal. /// 2 = hexadecimal (lower-case alpha). /// 3 = hexadecimal (upper-case alpha). ///@{ #define EFI_IFR_STRING_UNSIGNED_DEC 0 #define EFI_IFR_STRING_SIGNED_DEC 1 #define EFI_IFR_STRING_LOWERCASE_HEX 2 #define EFI_IFR_STRING_UPPERCASE_HEX 3 ///@} /// /// When converting from a buffer, these flags control the format: /// 0 = ASCII. /// 8 = Unicode. ///@{ #define EFI_IFR_STRING_ASCII 0 #define EFI_IFR_STRING_UNICODE 8 ///@} typedef struct _EFI_IFR_TO_STRING { EFI_IFR_OP_HEADER Header; UINT8 Format; } EFI_IFR_TO_STRING; typedef struct _EFI_IFR_TO_UINT { EFI_IFR_OP_HEADER Header; } EFI_IFR_TO_UINT; typedef struct _EFI_IFR_TO_UPPER { EFI_IFR_OP_HEADER Header; } EFI_IFR_TO_UPPER; typedef struct _EFI_IFR_TO_LOWER { EFI_IFR_OP_HEADER Header; } EFI_IFR_TO_LOWER; typedef struct _EFI_IFR_ADD { EFI_IFR_OP_HEADER Header; } EFI_IFR_ADD; typedef struct _EFI_IFR_AND { EFI_IFR_OP_HEADER Header; } EFI_IFR_AND; typedef struct _EFI_IFR_BITWISE_AND { EFI_IFR_OP_HEADER Header; } EFI_IFR_BITWISE_AND; typedef struct _EFI_IFR_BITWISE_OR { EFI_IFR_OP_HEADER Header; } EFI_IFR_BITWISE_OR; typedef struct _EFI_IFR_CATENATE { EFI_IFR_OP_HEADER Header; } EFI_IFR_CATENATE; typedef struct _EFI_IFR_DIVIDE { EFI_IFR_OP_HEADER Header; } EFI_IFR_DIVIDE; typedef struct _EFI_IFR_EQUAL { EFI_IFR_OP_HEADER Header; } EFI_IFR_EQUAL; typedef struct _EFI_IFR_GREATER_EQUAL { EFI_IFR_OP_HEADER Header; } EFI_IFR_GREATER_EQUAL; typedef struct _EFI_IFR_GREATER_THAN { EFI_IFR_OP_HEADER Header; } EFI_IFR_GREATER_THAN; typedef struct _EFI_IFR_LESS_EQUAL { EFI_IFR_OP_HEADER Header; } EFI_IFR_LESS_EQUAL; typedef struct _EFI_IFR_LESS_THAN { EFI_IFR_OP_HEADER Header; } EFI_IFR_LESS_THAN; typedef struct _EFI_IFR_MATCH { EFI_IFR_OP_HEADER Header; } EFI_IFR_MATCH; typedef struct _EFI_IFR_MATCH2 { EFI_IFR_OP_HEADER Header; EFI_GUID SyntaxType; } EFI_IFR_MATCH2; typedef struct _EFI_IFR_MULTIPLY { EFI_IFR_OP_HEADER Header; } EFI_IFR_MULTIPLY; typedef struct _EFI_IFR_MODULO { EFI_IFR_OP_HEADER Header; } EFI_IFR_MODULO; typedef struct _EFI_IFR_NOT_EQUAL { EFI_IFR_OP_HEADER Header; } EFI_IFR_NOT_EQUAL; typedef struct _EFI_IFR_OR { EFI_IFR_OP_HEADER Header; } EFI_IFR_OR; typedef struct _EFI_IFR_SHIFT_LEFT { EFI_IFR_OP_HEADER Header; } EFI_IFR_SHIFT_LEFT; typedef struct _EFI_IFR_SHIFT_RIGHT { EFI_IFR_OP_HEADER Header; } EFI_IFR_SHIFT_RIGHT; typedef struct _EFI_IFR_SUBTRACT { EFI_IFR_OP_HEADER Header; } EFI_IFR_SUBTRACT; typedef struct _EFI_IFR_CONDITIONAL { EFI_IFR_OP_HEADER Header; } EFI_IFR_CONDITIONAL; // // Flags governing the matching criteria of EFI_IFR_FIND // #define EFI_IFR_FF_CASE_SENSITIVE 0x00 #define EFI_IFR_FF_CASE_INSENSITIVE 0x01 typedef struct _EFI_IFR_FIND { EFI_IFR_OP_HEADER Header; UINT8 Format; } EFI_IFR_FIND; typedef struct _EFI_IFR_MID { EFI_IFR_OP_HEADER Header; } EFI_IFR_MID; typedef struct _EFI_IFR_TOKEN { EFI_IFR_OP_HEADER Header; } EFI_IFR_TOKEN; // // Flags specifying whether to find the first matching string // or the first non-matching string. // #define EFI_IFR_FLAGS_FIRST_MATCHING 0x00 #define EFI_IFR_FLAGS_FIRST_NON_MATCHING 0x01 typedef struct _EFI_IFR_SPAN { EFI_IFR_OP_HEADER Header; UINT8 Flags; } EFI_IFR_SPAN; typedef struct _EFI_IFR_SECURITY { /// /// Standard opcode header, where Header.Op = EFI_IFR_SECURITY_OP. /// EFI_IFR_OP_HEADER Header; /// /// Security permission level. /// EFI_GUID Permissions; } EFI_IFR_SECURITY; typedef struct _EFI_IFR_FORM_MAP_METHOD { /// /// The string identifier which provides the human-readable name of /// the configuration method for this standards map form. /// EFI_STRING_ID MethodTitle; /// /// Identifier which uniquely specifies the configuration methods /// associated with this standards map form. /// EFI_GUID MethodIdentifier; } EFI_IFR_FORM_MAP_METHOD; typedef struct _EFI_IFR_FORM_MAP { /// /// The sequence that defines the type of opcode as well as the length /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP. /// EFI_IFR_OP_HEADER Header; /// /// The unique identifier for this particular form. /// EFI_FORM_ID FormId; /// /// One or more configuration method's name and unique identifier. /// // EFI_IFR_FORM_MAP_METHOD Methods[]; } EFI_IFR_FORM_MAP; typedef struct _EFI_IFR_SET { /// /// The sequence that defines the type of opcode as well as the length /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP. /// EFI_IFR_OP_HEADER Header; /// /// Specifies the identifier of a previously declared variable store to /// use when storing the question's value. /// EFI_VARSTORE_ID VarStoreId; union { /// /// A 16-bit Buffer Storage offset. /// EFI_STRING_ID VarName; /// /// A Name Value or EFI Variable name (VarName). /// UINT16 VarOffset; } VarStoreInfo; /// /// Specifies the type used for storage. /// UINT8 VarStoreType; } EFI_IFR_SET; typedef struct _EFI_IFR_GET { /// /// The sequence that defines the type of opcode as well as the length /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP. /// EFI_IFR_OP_HEADER Header; /// /// Specifies the identifier of a previously declared variable store to /// use when retrieving the value. /// EFI_VARSTORE_ID VarStoreId; union { /// /// A 16-bit Buffer Storage offset. /// EFI_STRING_ID VarName; /// /// A Name Value or EFI Variable name (VarName). /// UINT16 VarOffset; } VarStoreInfo; /// /// Specifies the type used for storage. /// UINT8 VarStoreType; } EFI_IFR_GET; typedef struct _EFI_IFR_READ { EFI_IFR_OP_HEADER Header; } EFI_IFR_READ; typedef struct _EFI_IFR_WRITE { EFI_IFR_OP_HEADER Header; } EFI_IFR_WRITE; typedef struct _EFI_IFR_MAP { EFI_IFR_OP_HEADER Header; } EFI_IFR_MAP; // // Definitions for Keyboard Package // Releated definitions are in Section of EFI_HII_DATABASE_PROTOCOL // /// /// Each enumeration values maps a physical key on a keyboard. /// typedef enum { EfiKeyLCtrl, EfiKeyA0, EfiKeyLAlt, EfiKeySpaceBar, EfiKeyA2, EfiKeyA3, EfiKeyA4, EfiKeyRCtrl, EfiKeyLeftArrow, EfiKeyDownArrow, EfiKeyRightArrow, EfiKeyZero, EfiKeyPeriod, EfiKeyEnter, EfiKeyLShift, EfiKeyB0, EfiKeyB1, EfiKeyB2, EfiKeyB3, EfiKeyB4, EfiKeyB5, EfiKeyB6, EfiKeyB7, EfiKeyB8, EfiKeyB9, EfiKeyB10, EfiKeyRShift, EfiKeyUpArrow, EfiKeyOne, EfiKeyTwo, EfiKeyThree, EfiKeyCapsLock, EfiKeyC1, EfiKeyC2, EfiKeyC3, EfiKeyC4, EfiKeyC5, EfiKeyC6, EfiKeyC7, EfiKeyC8, EfiKeyC9, EfiKeyC10, EfiKeyC11, EfiKeyC12, EfiKeyFour, EfiKeyFive, EfiKeySix, EfiKeyPlus, EfiKeyTab, EfiKeyD1, EfiKeyD2, EfiKeyD3, EfiKeyD4, EfiKeyD5, EfiKeyD6, EfiKeyD7, EfiKeyD8, EfiKeyD9, EfiKeyD10, EfiKeyD11, EfiKeyD12, EfiKeyD13, EfiKeyDel, EfiKeyEnd, EfiKeyPgDn, EfiKeySeven, EfiKeyEight, EfiKeyNine, EfiKeyE0, EfiKeyE1, EfiKeyE2, EfiKeyE3, EfiKeyE4, EfiKeyE5, EfiKeyE6, EfiKeyE7, EfiKeyE8, EfiKeyE9, EfiKeyE10, EfiKeyE11, EfiKeyE12, EfiKeyBackSpace, EfiKeyIns, EfiKeyHome, EfiKeyPgUp, EfiKeyNLck, EfiKeySlash, EfiKeyAsterisk, EfiKeyMinus, EfiKeyEsc, EfiKeyF1, EfiKeyF2, EfiKeyF3, EfiKeyF4, EfiKeyF5, EfiKeyF6, EfiKeyF7, EfiKeyF8, EfiKeyF9, EfiKeyF10, EfiKeyF11, EfiKeyF12, EfiKeyPrint, EfiKeySLck, EfiKeyPause } EFI_KEY; typedef struct { /// /// Used to describe a physical key on a keyboard. /// EFI_KEY Key; /// /// Unicode character code for the Key. /// CHAR16 Unicode; /// /// Unicode character code for the key with the shift key being held down. /// CHAR16 ShiftedUnicode; /// /// Unicode character code for the key with the Alt-GR being held down. /// CHAR16 AltGrUnicode; /// /// Unicode character code for the key with the Alt-GR and shift keys being held down. /// CHAR16 ShiftedAltGrUnicode; /// /// Modifier keys are defined to allow for special functionality that is not necessarily /// accomplished by a printable character. Many of these modifier keys are flags to toggle /// certain state bits on and off inside of a keyboard driver. /// UINT16 Modifier; UINT16 AffectedAttribute; } EFI_KEY_DESCRIPTOR; /// /// A key which is affected by all the standard shift modifiers. /// Most keys would be expected to have this bit active. /// #define EFI_AFFECTED_BY_STANDARD_SHIFT 0x0001 /// /// This key is affected by the caps lock so that if a keyboard driver /// would need to disambiguate between a key which had a "1" defined /// versus an "a" character. Having this bit turned on would tell /// the keyboard driver to use the appropriate shifted state or not. /// #define EFI_AFFECTED_BY_CAPS_LOCK 0x0002 /// /// Similar to the case of CAPS lock, if this bit is active, the key /// is affected by the num lock being turned on. /// #define EFI_AFFECTED_BY_NUM_LOCK 0x0004 typedef struct { UINT16 LayoutLength; EFI_GUID Guid; UINT32 LayoutDescriptorStringOffset; UINT8 DescriptorCount; // EFI_KEY_DESCRIPTOR Descriptors[]; } EFI_HII_KEYBOARD_LAYOUT; typedef struct { EFI_HII_PACKAGE_HEADER Header; UINT16 LayoutCount; // EFI_HII_KEYBOARD_LAYOUT Layout[]; } EFI_HII_KEYBOARD_PACKAGE_HDR; // // Modifier values // #define EFI_NULL_MODIFIER 0x0000 #define EFI_LEFT_CONTROL_MODIFIER 0x0001 #define EFI_RIGHT_CONTROL_MODIFIER 0x0002 #define EFI_LEFT_ALT_MODIFIER 0x0003 #define EFI_RIGHT_ALT_MODIFIER 0x0004 #define EFI_ALT_GR_MODIFIER 0x0005 #define EFI_INSERT_MODIFIER 0x0006 #define EFI_DELETE_MODIFIER 0x0007 #define EFI_PAGE_DOWN_MODIFIER 0x0008 #define EFI_PAGE_UP_MODIFIER 0x0009 #define EFI_HOME_MODIFIER 0x000A #define EFI_END_MODIFIER 0x000B #define EFI_LEFT_SHIFT_MODIFIER 0x000C #define EFI_RIGHT_SHIFT_MODIFIER 0x000D #define EFI_CAPS_LOCK_MODIFIER 0x000E #define EFI_NUM_LOCK_MODIFIER 0x000F #define EFI_LEFT_ARROW_MODIFIER 0x0010 #define EFI_RIGHT_ARROW_MODIFIER 0x0011 #define EFI_DOWN_ARROW_MODIFIER 0x0012 #define EFI_UP_ARROW_MODIFIER 0x0013 #define EFI_NS_KEY_MODIFIER 0x0014 #define EFI_NS_KEY_DEPENDENCY_MODIFIER 0x0015 #define EFI_FUNCTION_KEY_ONE_MODIFIER 0x0016 #define EFI_FUNCTION_KEY_TWO_MODIFIER 0x0017 #define EFI_FUNCTION_KEY_THREE_MODIFIER 0x0018 #define EFI_FUNCTION_KEY_FOUR_MODIFIER 0x0019 #define EFI_FUNCTION_KEY_FIVE_MODIFIER 0x001A #define EFI_FUNCTION_KEY_SIX_MODIFIER 0x001B #define EFI_FUNCTION_KEY_SEVEN_MODIFIER 0x001C #define EFI_FUNCTION_KEY_EIGHT_MODIFIER 0x001D #define EFI_FUNCTION_KEY_NINE_MODIFIER 0x001E #define EFI_FUNCTION_KEY_TEN_MODIFIER 0x001F #define EFI_FUNCTION_KEY_ELEVEN_MODIFIER 0x0020 #define EFI_FUNCTION_KEY_TWELVE_MODIFIER 0x0021 // // Keys that have multiple control functions based on modifier // settings are handled in the keyboard driver implementation. // For instance, PRINT_KEY might have a modifier held down and // is still a nonprinting character, but might have an alternate // control function like SYSREQUEST // #define EFI_PRINT_MODIFIER 0x0022 #define EFI_SYS_REQUEST_MODIFIER 0x0023 #define EFI_SCROLL_LOCK_MODIFIER 0x0024 #define EFI_PAUSE_MODIFIER 0x0025 #define EFI_BREAK_MODIFIER 0x0026 #define EFI_LEFT_LOGO_MODIFIER 0x0027 #define EFI_RIGHT_LOGO_MODIFIER 0x0028 #define EFI_MENU_MODIFIER 0x0029 /// /// Animation IFR opcode /// typedef struct _EFI_IFR_ANIMATION { /// /// Standard opcode header, where Header.OpCode is /// EFI_IFR_ANIMATION_OP. /// EFI_IFR_OP_HEADER Header; /// /// Animation identifier in the HII database. /// EFI_ANIMATION_ID Id; } EFI_IFR_ANIMATION; /// /// HII animation package header. /// typedef struct _EFI_HII_ANIMATION_PACKAGE_HDR { /// /// Standard package header, where Header.Type = EFI_HII_PACKAGE_ANIMATIONS. /// EFI_HII_PACKAGE_HEADER Header; /// /// Offset, relative to this header, of the animation information. If /// this is zero, then there are no animation sequences in the package. /// UINT32 AnimationInfoOffset; } EFI_HII_ANIMATION_PACKAGE_HDR; /// /// Animation information is encoded as a series of blocks, /// with each block prefixed by a single byte header EFI_HII_ANIMATION_BLOCK. /// typedef struct _EFI_HII_ANIMATION_BLOCK { UINT8 BlockType; // UINT8 BlockBody[]; } EFI_HII_ANIMATION_BLOCK; /// /// Animation block types. /// #define EFI_HII_AIBT_END 0x00 #define EFI_HII_AIBT_OVERLAY_IMAGES 0x10 #define EFI_HII_AIBT_CLEAR_IMAGES 0x11 #define EFI_HII_AIBT_RESTORE_SCRN 0x12 #define EFI_HII_AIBT_OVERLAY_IMAGES_LOOP 0x18 #define EFI_HII_AIBT_CLEAR_IMAGES_LOOP 0x19 #define EFI_HII_AIBT_RESTORE_SCRN_LOOP 0x1A #define EFI_HII_AIBT_DUPLICATE 0x20 #define EFI_HII_AIBT_SKIP2 0x21 #define EFI_HII_AIBT_SKIP1 0x22 #define EFI_HII_AIBT_EXT1 0x30 #define EFI_HII_AIBT_EXT2 0x31 #define EFI_HII_AIBT_EXT4 0x32 /// /// Extended block headers used for variable sized animation records /// which need an explicit length. /// typedef struct _EFI_HII_AIBT_EXT1_BLOCK { /// /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT1. /// EFI_HII_ANIMATION_BLOCK Header; /// /// The block type. /// UINT8 BlockType2; /// /// Size of the animation block, in bytes, including the animation block header. /// UINT8 Length; } EFI_HII_AIBT_EXT1_BLOCK; typedef struct _EFI_HII_AIBT_EXT2_BLOCK { /// /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT2. /// EFI_HII_ANIMATION_BLOCK Header; /// /// The block type /// UINT8 BlockType2; /// /// Size of the animation block, in bytes, including the animation block header. /// UINT16 Length; } EFI_HII_AIBT_EXT2_BLOCK; typedef struct _EFI_HII_AIBT_EXT4_BLOCK { /// /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT4. /// EFI_HII_ANIMATION_BLOCK Header; /// /// The block type /// UINT8 BlockType2; /// /// Size of the animation block, in bytes, including the animation block header. /// UINT32 Length; } EFI_HII_AIBT_EXT4_BLOCK; typedef struct _EFI_HII_ANIMATION_CELL { /// /// The X offset from the upper left hand corner of the logical /// window to position the indexed image. /// UINT16 OffsetX; /// /// The Y offset from the upper left hand corner of the logical /// window to position the indexed image. /// UINT16 OffsetY; /// /// The image to display at the specified offset from the upper left /// hand corner of the logical window. /// EFI_IMAGE_ID ImageId; /// /// The number of milliseconds to delay after displaying the indexed /// image and before continuing on to the next linked image. If value /// is zero, no delay. /// UINT16 Delay; } EFI_HII_ANIMATION_CELL; /// /// An animation block to describe an animation sequence that does not cycle, and /// where one image is simply displayed over the previous image. /// typedef struct _EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK { /// /// This is image that is to be reference by the image protocols, if the /// animation function is not supported or disabled. This image can /// be one particular image from the animation sequence (if any one /// of the animation frames has a complete image) or an alternate /// image that can be displayed alone. If the value is zero, no image /// is displayed. /// EFI_IMAGE_ID DftImageId; /// /// The overall width of the set of images (logical window width). /// UINT16 Width; /// /// The overall height of the set of images (logical window height). /// UINT16 Height; /// /// The number of EFI_HII_ANIMATION_CELL contained in the /// animation sequence. /// UINT16 CellCount; /// /// An array of CellCount animation cells. /// EFI_HII_ANIMATION_CELL AnimationCell[1]; } EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK; /// /// An animation block to describe an animation sequence that does not cycle, /// and where the logical window is cleared to the specified color before /// the next image is displayed. /// typedef struct _EFI_HII_AIBT_CLEAR_IMAGES_BLOCK { /// /// This is image that is to be reference by the image protocols, if the /// animation function is not supported or disabled. This image can /// be one particular image from the animation sequence (if any one /// of the animation frames has a complete image) or an alternate /// image that can be displayed alone. If the value is zero, no image /// is displayed. /// EFI_IMAGE_ID DftImageId; /// /// The overall width of the set of images (logical window width). /// UINT16 Width; /// /// The overall height of the set of images (logical window height). /// UINT16 Height; /// /// The number of EFI_HII_ANIMATION_CELL contained in the /// animation sequence. /// UINT16 CellCount; /// /// The color to clear the logical window to before displaying the /// indexed image. /// EFI_HII_RGB_PIXEL BackgndColor; /// /// An array of CellCount animation cells. /// EFI_HII_ANIMATION_CELL AnimationCell[1]; } EFI_HII_AIBT_CLEAR_IMAGES_BLOCK; /// /// An animation block to describe an animation sequence that does not cycle, /// and where the screen is restored to the original state before the next /// image is displayed. /// typedef struct _EFI_HII_AIBT_RESTORE_SCRN_BLOCK { /// /// This is image that is to be reference by the image protocols, if the /// animation function is not supported or disabled. This image can /// be one particular image from the animation sequence (if any one /// of the animation frames has a complete image) or an alternate /// image that can be displayed alone. If the value is zero, no image /// is displayed. /// EFI_IMAGE_ID DftImageId; /// /// The overall width of the set of images (logical window width). /// UINT16 Width; /// /// The overall height of the set of images (logical window height). /// UINT16 Height; /// /// The number of EFI_HII_ANIMATION_CELL contained in the /// animation sequence. /// UINT16 CellCount; /// /// An array of CellCount animation cells. /// EFI_HII_ANIMATION_CELL AnimationCell[1]; } EFI_HII_AIBT_RESTORE_SCRN_BLOCK; /// /// An animation block to describe an animation sequence that continuously cycles, /// and where one image is simply displayed over the previous image. /// typedef EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK EFI_HII_AIBT_OVERLAY_IMAGES_LOOP_BLOCK; /// /// An animation block to describe an animation sequence that continuously cycles, /// and where the logical window is cleared to the specified color before /// the next image is displayed. /// typedef EFI_HII_AIBT_CLEAR_IMAGES_BLOCK EFI_HII_AIBT_CLEAR_IMAGES_LOOP_BLOCK; /// /// An animation block to describe an animation sequence that continuously cycles, /// and where the screen is restored to the original state before /// the next image is displayed. /// typedef EFI_HII_AIBT_RESTORE_SCRN_BLOCK EFI_HII_AIBT_RESTORE_SCRN_LOOP_BLOCK; /// /// Assigns a new character value to a previously defined animation sequence. /// typedef struct _EFI_HII_AIBT_DUPLICATE_BLOCK { /// /// The previously defined animation ID with the exact same /// animation information. /// EFI_ANIMATION_ID AnimationId; } EFI_HII_AIBT_DUPLICATE_BLOCK; /// /// Skips animation IDs. /// typedef struct _EFI_HII_AIBT_SKIP1_BLOCK { /// /// The unsigned 8-bit value to add to AnimationIdCurrent. /// UINT8 SkipCount; } EFI_HII_AIBT_SKIP1_BLOCK; /// /// Skips animation IDs. /// typedef struct _EFI_HII_AIBT_SKIP2_BLOCK { /// /// The unsigned 16-bit value to add to AnimationIdCurrent. /// UINT16 SkipCount; } EFI_HII_AIBT_SKIP2_BLOCK; #pragma pack() /// /// References to string tokens must use this macro to enable scanning for /// token usages. /// /// /// STRING_TOKEN is not defined in UEFI specification. But it is placed /// here for the easy access by C files and VFR source files. /// #define STRING_TOKEN(t) t /// /// IMAGE_TOKEN is not defined in UEFI specification. But it is placed /// here for the easy access by C files and VFR source files. /// #define IMAGE_TOKEN(t) t #endif /** @file This includes some definitions introduced in UEFI that will be used in both PEI and DXE phases. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_MULTIPHASE_H__ #define __UEFI_MULTIPHASE_H__ /// /// Attributes of variable. /// #define EFI_VARIABLE_NON_VOLATILE 0x00000001 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 #define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 /// /// This attribute is identified by the mnemonic 'HR' /// elsewhere in this specification. /// #define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 /// /// Attributes of Authenticated Variable /// #define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 #define EFI_VARIABLE_APPEND_WRITE 0x00000040 /// /// NOTE: EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated and should be considered reserved. /// #define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 #ifndef VFRCOMPILE #include /// /// Enumeration of memory types introduced in UEFI. /// typedef enum { /// /// Not used. /// EfiReservedMemoryType, /// /// The code portions of a loaded application. /// (Note that UEFI OS loaders are UEFI applications.) /// EfiLoaderCode, /// /// The data portions of a loaded application and the default data allocation /// type used by an application to allocate pool memory. /// EfiLoaderData, /// /// The code portions of a loaded Boot Services Driver. /// EfiBootServicesCode, /// /// The data portions of a loaded Boot Serves Driver, and the default data /// allocation type used by a Boot Services Driver to allocate pool memory. /// EfiBootServicesData, /// /// The code portions of a loaded Runtime Services Driver. /// EfiRuntimeServicesCode, /// /// The data portions of a loaded Runtime Services Driver and the default /// data allocation type used by a Runtime Services Driver to allocate pool memory. /// EfiRuntimeServicesData, /// /// Free (unallocated) memory. /// EfiConventionalMemory, /// /// Memory in which errors have been detected. /// EfiUnusableMemory, /// /// Memory that holds the ACPI tables. /// EfiACPIReclaimMemory, /// /// Address space reserved for use by the firmware. /// EfiACPIMemoryNVS, /// /// Used by system firmware to request that a memory-mapped IO region /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services. /// EfiMemoryMappedIO, /// /// System memory-mapped IO region that is used to translate memory /// cycles to IO cycles by the processor. /// EfiMemoryMappedIOPortSpace, /// /// Address space reserved by the firmware for code that is part of the processor. /// EfiPalCode, /// /// A memory region that operates as EfiConventionalMemory, /// however it happens to also support byte-addressable non-volatility. /// EfiPersistentMemory, /// /// A memory region that represents unaccepted memory, that must be /// accepted by the boot target before it can be used. Unless otherwise noted, all /// other EFI memory types are accepted. For platforms that support unaccepted /// memory, all unaccepted valid memory will be reported as unaccepted in the /// memory map. Unreported physical address ranges must be treated as not- /// present memory. /// EfiUnacceptedMemoryType, EfiMaxMemoryType } EFI_MEMORY_TYPE; /// /// Enumeration of reset types. /// typedef enum { /// /// Used to induce a system-wide reset. This sets all circuitry within the /// system to its initial state. This type of reset is asynchronous to system /// operation and operates withgout regard to cycle boundaries. EfiColdReset /// is tantamount to a system power cycle. /// EfiResetCold, /// /// Used to induce a system-wide initialization. The processors are set to their /// initial state, and pending cycles are not corrupted. If the system does /// not support this reset type, then an EfiResetCold must be performed. /// EfiResetWarm, /// /// Used to induce an entry into a power state equivalent to the ACPI G2/S5 or G3 /// state. If the system does not support this reset type, then when the system /// is rebooted, it should exhibit the EfiResetCold attributes. /// EfiResetShutdown, /// /// Used to induce a system-wide reset. The exact type of the reset is defined by /// the EFI_GUID that follows the Null-terminated Unicode string passed into /// ResetData. If the platform does not recognize the EFI_GUID in ResetData the /// platform must pick a supported reset type to perform. The platform may /// optionally log the parameters from any non-normal reset that occurs. /// EfiResetPlatformSpecific } EFI_RESET_TYPE; /// /// Data structure that precedes all of the standard EFI table types. /// typedef struct { /// /// A 64-bit signature that identifies the type of table that follows. /// Unique signatures have been generated for the EFI System Table, /// the EFI Boot Services Table, and the EFI Runtime Services Table. /// UINT64 Signature; /// /// The revision of the EFI Specification to which this table /// conforms. The upper 16 bits of this field contain the major /// revision value, and the lower 16 bits contain the minor revision /// value. The minor revision values are limited to the range of 00..99. /// UINT32 Revision; /// /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER. /// UINT32 HeaderSize; /// /// The 32-bit CRC for the entire table. This value is computed by /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes. /// UINT32 CRC32; /// /// Reserved field that must be set to 0. /// UINT32 Reserved; } EFI_TABLE_HEADER; /// /// AuthInfo is a WIN_CERTIFICATE using the wCertificateType /// WIN_CERTIFICATE_UEFI_GUID and the CertType /// EFI_CERT_TYPE_RSA2048_SHA256_GUID. If the attribute specifies /// authenticated access, then the Data buffer should begin with an /// authentication descriptor prior to the data payload and DataSize /// should reflect the the data.and descriptor size. The caller /// shall digest the Monotonic Count value and the associated data /// for the variable update using the SHA-256 1-way hash algorithm. /// The ensuing the 32-byte digest will be signed using the private /// key associated w/ the public/private 2048-bit RSA key-pair. The /// WIN_CERTIFICATE shall be used to describe the signature of the /// Variable data *Data. In addition, the signature will also /// include the MonotonicCount value to guard against replay attacks. /// typedef struct { /// /// Included in the signature of /// AuthInfo.Used to ensure freshness/no /// replay. Incremented during each /// "Write" access. /// UINT64 MonotonicCount; /// /// Provides the authorization for the variable /// access. It is a signature across the /// variable data and the Monotonic Count /// value. Caller uses Private key that is /// associated with a public key that has been /// provisioned via the key exchange. /// WIN_CERTIFICATE_UEFI_GUID AuthInfo; } EFI_VARIABLE_AUTHENTICATION; /// /// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is /// set, then the Data buffer shall begin with an instance of a complete (and serialized) /// EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new /// variable value and DataSize shall reflect the combined size of the descriptor and the new /// variable value. The authentication descriptor is not part of the variable data and is not /// returned by subsequent calls to GetVariable(). /// typedef struct { /// /// For the TimeStamp value, components Pad1, Nanosecond, TimeZone, Daylight and /// Pad2 shall be set to 0. This means that the time shall always be expressed in GMT. /// EFI_TIME TimeStamp; /// /// Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted. /// WIN_CERTIFICATE_UEFI_GUID AuthInfo; } EFI_VARIABLE_AUTHENTICATION_2; #endif // VFRCOMPILE #endif /** @file This header file contains all of the PXE type definitions, structure prototypes, global variables and constants that are needed for porting PXE to EFI. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Revision Reference: 32/64-bit PXE specification: alpha-4, 99-Dec-17. **/ #ifndef __EFI_PXE_H__ #define __EFI_PXE_H__ #pragma pack(1) #define PXE_BUSTYPE(a, b, c, d) \ ( \ (((PXE_UINT32) (d) & 0xFF) << 24) | (((PXE_UINT32) (c) & 0xFF) << 16) | (((PXE_UINT32) (b) & 0xFF) << 8) | \ ((PXE_UINT32) (a) & 0xFF) \ ) /// /// UNDI ROM ID and devive ID signature. /// #define PXE_BUSTYPE_PXE PXE_BUSTYPE ('!', 'P', 'X', 'E') /// /// BUS ROM ID signatures. /// #define PXE_BUSTYPE_PCI PXE_BUSTYPE ('P', 'C', 'I', 'R') #define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE ('P', 'C', 'C', 'R') #define PXE_BUSTYPE_USB PXE_BUSTYPE ('U', 'S', 'B', 'R') #define PXE_BUSTYPE_1394 PXE_BUSTYPE ('1', '3', '9', '4') #define PXE_SWAP_UINT16(n) ((((PXE_UINT16) (n) & 0x00FF) << 8) | (((PXE_UINT16) (n) & 0xFF00) >> 8)) #define PXE_SWAP_UINT32(n) \ ((((PXE_UINT32)(n) & 0x000000FF) << 24) | \ (((PXE_UINT32)(n) & 0x0000FF00) << 8) | \ (((PXE_UINT32)(n) & 0x00FF0000) >> 8) | \ (((PXE_UINT32)(n) & 0xFF000000) >> 24)) #define PXE_SWAP_UINT64(n) \ ((((PXE_UINT64)(n) & 0x00000000000000FFULL) << 56) | \ (((PXE_UINT64)(n) & 0x000000000000FF00ULL) << 40) | \ (((PXE_UINT64)(n) & 0x0000000000FF0000ULL) << 24) | \ (((PXE_UINT64)(n) & 0x00000000FF000000ULL) << 8) | \ (((PXE_UINT64)(n) & 0x000000FF00000000ULL) >> 8) | \ (((PXE_UINT64)(n) & 0x0000FF0000000000ULL) >> 24) | \ (((PXE_UINT64)(n) & 0x00FF000000000000ULL) >> 40) | \ (((PXE_UINT64)(n) & 0xFF00000000000000ULL) >> 56)) #define PXE_CPBSIZE_NOT_USED 0 ///< zero #define PXE_DBSIZE_NOT_USED 0 ///< zero #define PXE_CPBADDR_NOT_USED (PXE_UINT64) 0 ///< zero #define PXE_DBADDR_NOT_USED (PXE_UINT64) 0 ///< zero #define PXE_CONST CONST #define PXE_VOLATILE volatile typedef VOID PXE_VOID; typedef UINT8 PXE_UINT8; typedef UINT16 PXE_UINT16; typedef UINT32 PXE_UINT32; typedef UINTN PXE_UINTN; /// /// Typedef unsigned long PXE_UINT64. /// typedef UINT64 PXE_UINT64; typedef PXE_UINT8 PXE_BOOL; #define PXE_FALSE 0 ///< zero #define PXE_TRUE (!PXE_FALSE) typedef PXE_UINT16 PXE_OPCODE; /// /// Return UNDI operational state. /// #define PXE_OPCODE_GET_STATE 0x0000 /// /// Change UNDI operational state from Stopped to Started. /// #define PXE_OPCODE_START 0x0001 /// /// Change UNDI operational state from Started to Stopped. /// #define PXE_OPCODE_STOP 0x0002 /// /// Get UNDI initialization information. /// #define PXE_OPCODE_GET_INIT_INFO 0x0003 /// /// Get NIC configuration information. /// #define PXE_OPCODE_GET_CONFIG_INFO 0x0004 /// /// Changed UNDI operational state from Started to Initialized. /// #define PXE_OPCODE_INITIALIZE 0x0005 /// /// Re-initialize the NIC H/W. /// #define PXE_OPCODE_RESET 0x0006 /// /// Change the UNDI operational state from Initialized to Started. /// #define PXE_OPCODE_SHUTDOWN 0x0007 /// /// Read & change state of external interrupt enables. /// #define PXE_OPCODE_INTERRUPT_ENABLES 0x0008 /// /// Read & change state of packet receive filters. /// #define PXE_OPCODE_RECEIVE_FILTERS 0x0009 /// /// Read & change station MAC address. /// #define PXE_OPCODE_STATION_ADDRESS 0x000A /// /// Read traffic statistics. /// #define PXE_OPCODE_STATISTICS 0x000B /// /// Convert multicast IP address to multicast MAC address. /// #define PXE_OPCODE_MCAST_IP_TO_MAC 0x000C /// /// Read or change non-volatile storage on the NIC. /// #define PXE_OPCODE_NVDATA 0x000D /// /// Get & clear interrupt status. /// #define PXE_OPCODE_GET_STATUS 0x000E /// /// Fill media header in packet for transmit. /// #define PXE_OPCODE_FILL_HEADER 0x000F /// /// Transmit packet(s). /// #define PXE_OPCODE_TRANSMIT 0x0010 /// /// Receive packet. /// #define PXE_OPCODE_RECEIVE 0x0011 /// /// Last valid PXE UNDI OpCode number. /// #define PXE_OPCODE_LAST_VALID 0x0011 typedef PXE_UINT16 PXE_OPFLAGS; #define PXE_OPFLAGS_NOT_USED 0x0000 // // ////////////////////////////////////// // UNDI Get State // // No OpFlags //////////////////////////////////////// // UNDI Start // // No OpFlags //////////////////////////////////////// // UNDI Stop // // No OpFlags //////////////////////////////////////// // UNDI Get Init Info // // No Opflags //////////////////////////////////////// // UNDI Get Config Info // // No Opflags /// /// UNDI Initialize /// #define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK 0x0001 #define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE 0x0000 #define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE 0x0001 /// /// /// UNDI Reset /// #define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS 0x0001 #define PXE_OPFLAGS_RESET_DISABLE_FILTERS 0x0002 /// /// UNDI Shutdown. /// /// No OpFlags. /// /// UNDI Interrupt Enables. /// /// /// Select whether to enable or disable external interrupt signals. /// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS. /// #define PXE_OPFLAGS_INTERRUPT_OPMASK 0xC000 #define PXE_OPFLAGS_INTERRUPT_ENABLE 0x8000 #define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000 #define PXE_OPFLAGS_INTERRUPT_READ 0x0000 /// /// Enable receive interrupts. An external interrupt will be generated /// after a complete non-error packet has been received. /// #define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001 /// /// Enable transmit interrupts. An external interrupt will be generated /// after a complete non-error packet has been transmitted. /// #define PXE_OPFLAGS_INTERRUPT_TRANSMIT 0x0002 /// /// Enable command interrupts. An external interrupt will be generated /// when command execution stops. /// #define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004 /// /// Generate software interrupt. Setting this bit generates an external /// interrupt, if it is supported by the hardware. /// #define PXE_OPFLAGS_INTERRUPT_SOFTWARE 0x0008 /// /// UNDI Receive Filters. /// /// /// Select whether to enable or disable receive filters. /// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE. /// #define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK 0xC000 #define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE 0x8000 #define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE 0x4000 #define PXE_OPFLAGS_RECEIVE_FILTER_READ 0x0000 /// /// To reset the contents of the multicast MAC address filter list, /// set this OpFlag: /// #define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000 /// /// Enable unicast packet receiving. Packets sent to the current station /// MAC address will be received. /// #define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST 0x0001 /// /// Enable broadcast packet receiving. Packets sent to the broadcast /// MAC address will be received. /// #define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST 0x0002 /// /// Enable filtered multicast packet receiving. Packets sent to any /// of the multicast MAC addresses in the multicast MAC address filter /// list will be received. If the filter list is empty, no multicast /// #define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004 /// /// Enable promiscuous packet receiving. All packets will be received. /// #define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS 0x0008 /// /// Enable promiscuous multicast packet receiving. All multicast /// packets will be received. /// #define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST 0x0010 /// /// UNDI Station Address. /// #define PXE_OPFLAGS_STATION_ADDRESS_READ 0x0000 #define PXE_OPFLAGS_STATION_ADDRESS_WRITE 0x0000 #define PXE_OPFLAGS_STATION_ADDRESS_RESET 0x0001 /// /// UNDI Statistics. /// #define PXE_OPFLAGS_STATISTICS_READ 0x0000 #define PXE_OPFLAGS_STATISTICS_RESET 0x0001 /// /// UNDI MCast IP to MAC. /// /// /// Identify the type of IP address in the CPB. /// #define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK 0x0003 #define PXE_OPFLAGS_MCAST_IPV4_TO_MAC 0x0000 #define PXE_OPFLAGS_MCAST_IPV6_TO_MAC 0x0001 /// /// UNDI NvData. /// /// /// Select the type of non-volatile data operation. /// #define PXE_OPFLAGS_NVDATA_OPMASK 0x0001 #define PXE_OPFLAGS_NVDATA_READ 0x0000 #define PXE_OPFLAGS_NVDATA_WRITE 0x0001 /// /// UNDI Get Status. /// /// /// Return current interrupt status. This will also clear any interrupts /// that are currently set. This can be used in a polling routine. The /// interrupt flags are still set and cleared even when the interrupts /// are disabled. /// #define PXE_OPFLAGS_GET_INTERRUPT_STATUS 0x0001 /// /// Return list of transmitted buffers for recycling. Transmit buffers /// must not be changed or unallocated until they have recycled. After /// issuing a transmit command, wait for a transmit complete interrupt. /// When a transmit complete interrupt is received, read the transmitted /// buffers. Do not plan on getting one buffer per interrupt. Some /// NICs and UNDIs may transmit multiple buffers per interrupt. /// #define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002 /// /// Return current media status. /// #define PXE_OPFLAGS_GET_MEDIA_STATUS 0x0004 /// /// UNDI Fill Header. /// #define PXE_OPFLAGS_FILL_HEADER_OPMASK 0x0001 #define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED 0x0001 #define PXE_OPFLAGS_FILL_HEADER_WHOLE 0x0000 /// /// UNDI Transmit. /// /// /// S/W UNDI only. Return after the packet has been transmitted. A /// transmit complete interrupt will still be generated and the transmit /// buffer will have to be recycled. /// #define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK 0x0001 #define PXE_OPFLAGS_TRANSMIT_BLOCK 0x0001 #define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK 0x0000 #define PXE_OPFLAGS_TRANSMIT_OPMASK 0x0002 #define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002 #define PXE_OPFLAGS_TRANSMIT_WHOLE 0x0000 /// /// UNDI Receive. /// /// No OpFlags. /// /// /// PXE STATFLAGS. /// typedef PXE_UINT16 PXE_STATFLAGS; #define PXE_STATFLAGS_INITIALIZE 0x0000 /// /// Common StatFlags that can be returned by all commands. /// /// /// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be /// implemented by all UNDIs. COMMAND_QUEUED is only needed by UNDIs /// that support command queuing. /// #define PXE_STATFLAGS_STATUS_MASK 0xC000 #define PXE_STATFLAGS_COMMAND_COMPLETE 0xC000 #define PXE_STATFLAGS_COMMAND_FAILED 0x8000 #define PXE_STATFLAGS_COMMAND_QUEUED 0x4000 /// /// UNDI Get State. /// #define PXE_STATFLAGS_GET_STATE_MASK 0x0003 #define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002 #define PXE_STATFLAGS_GET_STATE_STARTED 0x0001 #define PXE_STATFLAGS_GET_STATE_STOPPED 0x0000 /// /// UNDI Start. /// /// No additional StatFlags. /// /// /// UNDI Get Init Info. /// #define PXE_STATFLAGS_CABLE_DETECT_MASK 0x0001 #define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED 0x0000 #define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED 0x0001 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK 0x0002 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED 0x0000 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED 0x0002 /// /// UNDI Initialize. /// #define PXE_STATFLAGS_INITIALIZED_NO_MEDIA 0x0001 /// /// UNDI Reset. /// #define PXE_STATFLAGS_RESET_NO_MEDIA 0x0001 /// /// UNDI Shutdown. /// /// No additional StatFlags. /// /// UNDI Interrupt Enables. /// /// /// If set, receive interrupts are enabled. /// #define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001 /// /// If set, transmit interrupts are enabled. /// #define PXE_STATFLAGS_INTERRUPT_TRANSMIT 0x0002 /// /// If set, command interrupts are enabled. /// #define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004 /// /// UNDI Receive Filters. /// /// /// If set, unicast packets will be received. /// #define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST 0x0001 /// /// If set, broadcast packets will be received. /// #define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST 0x0002 /// /// If set, multicast packets that match up with the multicast address /// filter list will be received. /// #define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004 /// /// If set, all packets will be received. /// #define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS 0x0008 /// /// If set, all multicast packets will be received. /// #define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST 0x0010 /// /// UNDI Station Address. /// /// No additional StatFlags. /// /// /// UNDI Statistics. /// /// No additional StatFlags. /// /// //// UNDI MCast IP to MAC. //// //// No additional StatFlags. /// /// UNDI NvData. /// /// No additional StatFlags. /// /// /// UNDI Get Status. /// /// /// Use to determine if an interrupt has occurred. /// #define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F #define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS 0x0000 /// /// If set, at least one receive interrupt occurred. /// #define PXE_STATFLAGS_GET_STATUS_RECEIVE 0x0001 /// /// If set, at least one transmit interrupt occurred. /// #define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002 /// /// If set, at least one command interrupt occurred. /// #define PXE_STATFLAGS_GET_STATUS_COMMAND 0x0004 /// /// If set, at least one software interrupt occurred. /// #define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008 /// /// This flag is set if the transmitted buffer queue is empty. This flag /// will be set if all transmitted buffer addresses get written into the DB. /// #define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY 0x0010 /// /// This flag is set if no transmitted buffer addresses were written /// into the DB. (This could be because DBsize was too small.) /// #define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN 0x0020 /// /// This flag is set if there is no media detected. /// #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA 0x0040 /// /// UNDI Fill Header. /// /// No additional StatFlags. /// /// /// UNDI Transmit. /// /// No additional StatFlags. /// /// UNDI Receive /// . /// /// No additional StatFlags. /// typedef PXE_UINT16 PXE_STATCODE; #define PXE_STATCODE_INITIALIZE 0x0000 /// /// Common StatCodes returned by all UNDI commands, UNDI protocol functions /// and BC protocol functions. /// #define PXE_STATCODE_SUCCESS 0x0000 #define PXE_STATCODE_INVALID_CDB 0x0001 #define PXE_STATCODE_INVALID_CPB 0x0002 #define PXE_STATCODE_BUSY 0x0003 #define PXE_STATCODE_QUEUE_FULL 0x0004 #define PXE_STATCODE_ALREADY_STARTED 0x0005 #define PXE_STATCODE_NOT_STARTED 0x0006 #define PXE_STATCODE_NOT_SHUTDOWN 0x0007 #define PXE_STATCODE_ALREADY_INITIALIZED 0x0008 #define PXE_STATCODE_NOT_INITIALIZED 0x0009 #define PXE_STATCODE_DEVICE_FAILURE 0x000A #define PXE_STATCODE_NVDATA_FAILURE 0x000B #define PXE_STATCODE_UNSUPPORTED 0x000C #define PXE_STATCODE_BUFFER_FULL 0x000D #define PXE_STATCODE_INVALID_PARAMETER 0x000E #define PXE_STATCODE_INVALID_UNDI 0x000F #define PXE_STATCODE_IPV4_NOT_SUPPORTED 0x0010 #define PXE_STATCODE_IPV6_NOT_SUPPORTED 0x0011 #define PXE_STATCODE_NOT_ENOUGH_MEMORY 0x0012 #define PXE_STATCODE_NO_DATA 0x0013 typedef PXE_UINT16 PXE_IFNUM; /// /// This interface number must be passed to the S/W UNDI Start command. /// #define PXE_IFNUM_START 0x0000 /// /// This interface number is returned by the S/W UNDI Get State and /// Start commands if information in the CDB, CPB or DB is invalid. /// #define PXE_IFNUM_INVALID 0x0000 typedef PXE_UINT16 PXE_CONTROL; /// /// Setting this flag directs the UNDI to queue this command for later /// execution if the UNDI is busy and it supports command queuing. /// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error /// is returned. If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL /// error is returned. /// #define PXE_CONTROL_QUEUE_IF_BUSY 0x0002 /// /// These two bit values are used to determine if there are more UNDI /// CDB structures following this one. If the link bit is set, there /// must be a CDB structure following this one. Execution will start /// on the next CDB structure as soon as this one completes successfully. /// If an error is generated by this command, execution will stop. /// #define PXE_CONTROL_LINK 0x0001 #define PXE_CONTROL_LAST_CDB_IN_LIST 0x0000 typedef PXE_UINT8 PXE_FRAME_TYPE; #define PXE_FRAME_TYPE_NONE 0x00 #define PXE_FRAME_TYPE_UNICAST 0x01 #define PXE_FRAME_TYPE_BROADCAST 0x02 #define PXE_FRAME_TYPE_FILTERED_MULTICAST 0x03 #define PXE_FRAME_TYPE_PROMISCUOUS 0x04 #define PXE_FRAME_TYPE_PROMISCUOUS_MULTICAST 0x05 #define PXE_FRAME_TYPE_MULTICAST PXE_FRAME_TYPE_FILTERED_MULTICAST typedef PXE_UINT32 PXE_IPV4; typedef PXE_UINT32 PXE_IPV6[4]; #define PXE_MAC_LENGTH 32 typedef PXE_UINT8 PXE_MAC_ADDR[PXE_MAC_LENGTH]; typedef PXE_UINT8 PXE_IFTYPE; typedef UINT16 PXE_MEDIA_PROTOCOL; /// /// This information is from the ARP section of RFC 1700. /// /// 1 Ethernet (10Mb) [JBP] /// 2 Experimental Ethernet (3Mb) [JBP] /// 3 Amateur Radio AX.25 [PXK] /// 4 Proteon ProNET Token Ring [JBP] /// 5 Chaos [GXP] /// 6 IEEE 802 Networks [JBP] /// 7 ARCNET [JBP] /// 8 Hyperchannel [JBP] /// 9 Lanstar [TU] /// 10 Autonet Short Address [MXB1] /// 11 LocalTalk [JKR1] /// 12 LocalNet (IBM* PCNet or SYTEK* LocalNET) [JXM] /// 13 Ultra link [RXD2] /// 14 SMDS [GXC1] /// 15 Frame Relay [AGM] /// 16 Asynchronous Transmission Mode (ATM) [JXB2] /// 17 HDLC [JBP] /// 18 Fibre Channel [Yakov Rekhter] /// 19 Asynchronous Transmission Mode (ATM) [Mark Laubach] /// 20 Serial Line [JBP] /// 21 Asynchronous Transmission Mode (ATM) [MXB1] /// /// * Other names and brands may be claimed as the property of others. /// #define PXE_IFTYPE_ETHERNET 0x01 #define PXE_IFTYPE_TOKENRING 0x04 #define PXE_IFTYPE_FIBRE_CHANNEL 0x12 typedef struct s_pxe_hw_undi { PXE_UINT32 Signature; ///< PXE_ROMID_SIGNATURE. PXE_UINT8 Len; ///< sizeof(PXE_HW_UNDI). PXE_UINT8 Fudge; ///< makes 8-bit cksum equal zero. PXE_UINT8 Rev; ///< PXE_ROMID_REV. PXE_UINT8 IFcnt; ///< physical connector count lower byte. PXE_UINT8 MajorVer; ///< PXE_ROMID_MAJORVER. PXE_UINT8 MinorVer; ///< PXE_ROMID_MINORVER. PXE_UINT8 IFcntExt; ///< physical connector count upper byte. PXE_UINT8 reserved; ///< zero, not used. PXE_UINT32 Implementation; ///< implementation flags. ///< reserved ///< vendor use. ///< UINT32 Status; ///< status port. ///< UINT32 Command; ///< command port. ///< UINT64 CDBaddr; ///< CDB address port. ///< } PXE_HW_UNDI; /// /// Status port bit definitions. /// /// /// UNDI operation state. /// #define PXE_HWSTAT_STATE_MASK 0xC0000000 #define PXE_HWSTAT_BUSY 0xC0000000 #define PXE_HWSTAT_INITIALIZED 0x80000000 #define PXE_HWSTAT_STARTED 0x40000000 #define PXE_HWSTAT_STOPPED 0x00000000 /// /// If set, last command failed. /// #define PXE_HWSTAT_COMMAND_FAILED 0x20000000 /// /// If set, identifies enabled receive filters. /// #define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000 #define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED 0x00000800 #define PXE_HWSTAT_BROADCAST_RX_ENABLED 0x00000400 #define PXE_HWSTAT_MULTICAST_RX_ENABLED 0x00000200 #define PXE_HWSTAT_UNICAST_RX_ENABLED 0x00000100 /// /// If set, identifies enabled external interrupts. /// #define PXE_HWSTAT_SOFTWARE_INT_ENABLED 0x00000080 #define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED 0x00000040 #define PXE_HWSTAT_PACKET_RX_INT_ENABLED 0x00000020 #define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010 /// /// If set, identifies pending interrupts. /// #define PXE_HWSTAT_SOFTWARE_INT_PENDING 0x00000008 #define PXE_HWSTAT_TX_COMPLETE_INT_PENDING 0x00000004 #define PXE_HWSTAT_PACKET_RX_INT_PENDING 0x00000002 #define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001 /// /// Command port definitions. /// /// /// If set, CDB identified in CDBaddr port is given to UNDI. /// If not set, other bits in this word will be processed. /// #define PXE_HWCMD_ISSUE_COMMAND 0x80000000 #define PXE_HWCMD_INTS_AND_FILTS 0x00000000 /// /// Use these to enable/disable receive filters. /// #define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000 #define PXE_HWCMD_PROMISCUOUS_RX_ENABLE 0x00000800 #define PXE_HWCMD_BROADCAST_RX_ENABLE 0x00000400 #define PXE_HWCMD_MULTICAST_RX_ENABLE 0x00000200 #define PXE_HWCMD_UNICAST_RX_ENABLE 0x00000100 /// /// Use these to enable/disable external interrupts. /// #define PXE_HWCMD_SOFTWARE_INT_ENABLE 0x00000080 #define PXE_HWCMD_TX_COMPLETE_INT_ENABLE 0x00000040 #define PXE_HWCMD_PACKET_RX_INT_ENABLE 0x00000020 #define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010 /// /// Use these to clear pending external interrupts. /// #define PXE_HWCMD_CLEAR_SOFTWARE_INT 0x00000008 #define PXE_HWCMD_CLEAR_TX_COMPLETE_INT 0x00000004 #define PXE_HWCMD_CLEAR_PACKET_RX_INT 0x00000002 #define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT 0x00000001 typedef struct s_pxe_sw_undi { PXE_UINT32 Signature; ///< PXE_ROMID_SIGNATURE. PXE_UINT8 Len; ///< sizeof(PXE_SW_UNDI). PXE_UINT8 Fudge; ///< makes 8-bit cksum zero. PXE_UINT8 Rev; ///< PXE_ROMID_REV. PXE_UINT8 IFcnt; ///< physical connector count lower byte. PXE_UINT8 MajorVer; ///< PXE_ROMID_MAJORVER. PXE_UINT8 MinorVer; ///< PXE_ROMID_MINORVER. PXE_UINT8 IFcntExt; ///< physical connector count upper byte. PXE_UINT8 reserved1; ///< zero, not used. PXE_UINT32 Implementation; ///< Implementation flags. PXE_UINT64 EntryPoint; ///< API entry point. PXE_UINT8 reserved2[3]; ///< zero, not used. PXE_UINT8 BusCnt; ///< number of bustypes supported. PXE_UINT32 BusType[1]; ///< list of supported bustypes. } PXE_SW_UNDI; typedef union u_pxe_undi { PXE_HW_UNDI hw; PXE_SW_UNDI sw; } PXE_UNDI; /// /// Signature of !PXE structure. /// #define PXE_ROMID_SIGNATURE PXE_BUSTYPE ('!', 'P', 'X', 'E') /// /// !PXE structure format revision /// . #define PXE_ROMID_REV 0x02 /// /// UNDI command interface revision. These are the values that get sent /// in option 94 (Client Network Interface Identifier) in the DHCP Discover /// and PXE Boot Server Request packets. /// #define PXE_ROMID_MAJORVER 0x03 #define PXE_ROMID_MINORVER 0x01 /// /// Implementation flags. /// #define PXE_ROMID_IMP_HW_UNDI 0x80000000 #define PXE_ROMID_IMP_SW_VIRT_ADDR 0x40000000 #define PXE_ROMID_IMP_64BIT_DEVICE 0x00010000 #define PXE_ROMID_IMP_FRAG_SUPPORTED 0x00008000 #define PXE_ROMID_IMP_CMD_LINK_SUPPORTED 0x00004000 #define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED 0x00002000 #define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED 0x00001000 #define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK 0x00000C00 #define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE 0x00000C00 #define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE 0x00000800 #define PXE_ROMID_IMP_NVDATA_READ_ONLY 0x00000400 #define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE 0x00000000 #define PXE_ROMID_IMP_STATISTICS_SUPPORTED 0x00000200 #define PXE_ROMID_IMP_STATION_ADDR_SETTABLE 0x00000100 #define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED 0x00000080 #define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED 0x00000040 #define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED 0x00000020 #define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED 0x00000010 #define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED 0x00000008 #define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED 0x00000004 #define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED 0x00000002 #define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED 0x00000001 typedef struct s_pxe_cdb { PXE_OPCODE OpCode; PXE_OPFLAGS OpFlags; PXE_UINT16 CPBsize; PXE_UINT16 DBsize; PXE_UINT64 CPBaddr; PXE_UINT64 DBaddr; PXE_STATCODE StatCode; PXE_STATFLAGS StatFlags; PXE_UINT16 IFnum; PXE_CONTROL Control; } PXE_CDB; typedef union u_pxe_ip_addr { PXE_IPV6 IPv6; PXE_IPV4 IPv4; } PXE_IP_ADDR; typedef union pxe_device { /// /// PCI and PC Card NICs are both identified using bus, device /// and function numbers. For PC Card, this may require PC /// Card services to be loaded in the BIOS or preboot /// environment. /// struct { /// /// See S/W UNDI ROMID structure definition for PCI and /// PCC BusType definitions. /// PXE_UINT32 BusType; /// /// Bus, device & function numbers that locate this device. /// PXE_UINT16 Bus; PXE_UINT8 Device; PXE_UINT8 Function; } PCI, PCC; } PXE_DEVICE; /// /// cpb and db definitions /// #define MAX_PCI_CONFIG_LEN 64 ///< # of dwords. #define MAX_EEPROM_LEN 128 ///< # of dwords. #define MAX_XMIT_BUFFERS 32 ///< recycling Q length for xmit_done. #define MAX_MCAST_ADDRESS_CNT 8 typedef struct s_pxe_cpb_start_30 { /// /// PXE_VOID Delay(UINTN microseconds); /// /// UNDI will never request a delay smaller than 10 microseconds /// and will always request delays in increments of 10 microseconds. /// The Delay() CallBack routine must delay between n and n + 10 /// microseconds before returning control to the UNDI. /// /// This field cannot be set to zero. /// UINT64 Delay; /// /// PXE_VOID Block(UINT32 enable); /// /// UNDI may need to block multi-threaded/multi-processor access to /// critical code sections when programming or accessing the network /// device. To this end, a blocking service is needed by the UNDI. /// When UNDI needs a block, it will call Block() passing a non-zero /// value. When UNDI no longer needs a block, it will call Block() /// with a zero value. When called, if the Block() is already enabled, /// do not return control to the UNDI until the previous Block() is /// disabled. /// /// This field cannot be set to zero. /// UINT64 Block; /// /// PXE_VOID Virt2Phys(UINT64 virtual, UINT64 physical_ptr); /// /// UNDI will pass the virtual address of a buffer and the virtual /// address of a 64-bit physical buffer. Convert the virtual address /// to a physical address and write the result to the physical address /// buffer. If virtual and physical addresses are the same, just /// copy the virtual address to the physical address buffer. /// /// This field can be set to zero if virtual and physical addresses /// are equal. /// UINT64 Virt2Phys; /// /// PXE_VOID Mem_IO(UINT8 read_write, UINT8 len, UINT64 port, /// UINT64 buf_addr); /// /// UNDI will read or write the device io space using this call back /// function. It passes the number of bytes as the len parameter and it /// will be either 1,2,4 or 8. /// /// This field can not be set to zero. /// UINT64 Mem_IO; } PXE_CPB_START_30; typedef struct s_pxe_cpb_start_31 { /// /// PXE_VOID Delay(UINT64 UnqId, UINTN microseconds); /// /// UNDI will never request a delay smaller than 10 microseconds /// and will always request delays in increments of 10 microseconds. /// The Delay() CallBack routine must delay between n and n + 10 /// microseconds before returning control to the UNDI. /// /// This field cannot be set to zero. /// UINT64 Delay; /// /// PXE_VOID Block(UINT64 unq_id, UINT32 enable); /// /// UNDI may need to block multi-threaded/multi-processor access to /// critical code sections when programming or accessing the network /// device. To this end, a blocking service is needed by the UNDI. /// When UNDI needs a block, it will call Block() passing a non-zero /// value. When UNDI no longer needs a block, it will call Block() /// with a zero value. When called, if the Block() is already enabled, /// do not return control to the UNDI until the previous Block() is /// disabled. /// /// This field cannot be set to zero. /// UINT64 Block; /// /// PXE_VOID Virt2Phys(UINT64 UnqId, UINT64 virtual, UINT64 physical_ptr); /// /// UNDI will pass the virtual address of a buffer and the virtual /// address of a 64-bit physical buffer. Convert the virtual address /// to a physical address and write the result to the physical address /// buffer. If virtual and physical addresses are the same, just /// copy the virtual address to the physical address buffer. /// /// This field can be set to zero if virtual and physical addresses /// are equal. /// UINT64 Virt2Phys; /// /// PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port, /// UINT64 buf_addr); /// /// UNDI will read or write the device io space using this call back /// function. It passes the number of bytes as the len parameter and it /// will be either 1,2,4 or 8. /// /// This field can not be set to zero. /// UINT64 Mem_IO; /// /// PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size, /// UINT32 Direction, UINT64 mapped_addr); /// /// UNDI will pass the virtual address of a buffer, direction of the data /// flow from/to the mapped buffer (the constants are defined below) /// and a place holder (pointer) for the mapped address. /// This call will Map the given address to a physical DMA address and write /// the result to the mapped_addr pointer. If there is no need to /// map the given address to a lower address (i.e. the given address is /// associated with a physical address that is already compatible to be /// used with the DMA, it converts the given virtual address to it's /// physical address and write that in the mapped address pointer. /// /// This field can be set to zero if there is no mapping service available. /// UINT64 Map_Mem; /// /// PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size, /// UINT32 Direction, UINT64 mapped_addr); /// /// UNDI will pass the virtual and mapped addresses of a buffer. /// This call will un map the given address. /// /// This field can be set to zero if there is no unmapping service available. /// UINT64 UnMap_Mem; /// /// PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual, /// UINT32 size, UINT32 Direction, UINT64 mapped_addr); /// /// UNDI will pass the virtual and mapped addresses of a buffer. /// This call will synchronize the contents of both the virtual and mapped. /// buffers for the given Direction. /// /// This field can be set to zero if there is no service available. /// UINT64 Sync_Mem; /// /// protocol driver can provide anything for this Unique_ID, UNDI remembers /// that as just a 64bit value associated to the interface specified by /// the ifnum and gives it back as a parameter to all the call-back routines /// when calling for that interface! /// UINT64 Unique_ID; } PXE_CPB_START_31; #define TO_AND_FROM_DEVICE 0 #define FROM_DEVICE 1 #define TO_DEVICE 2 #define PXE_DELAY_MILLISECOND 1000 #define PXE_DELAY_SECOND 1000000 #define PXE_IO_READ 0 #define PXE_IO_WRITE 1 #define PXE_MEM_READ 2 #define PXE_MEM_WRITE 4 typedef struct s_pxe_db_get_init_info { /// /// Minimum length of locked memory buffer that must be given to /// the Initialize command. Giving UNDI more memory will generally /// give better performance. /// /// If MemoryRequired is zero, the UNDI does not need and will not /// use system memory to receive and transmit packets. /// PXE_UINT32 MemoryRequired; /// /// Maximum frame data length for Tx/Rx excluding the media header. /// PXE_UINT32 FrameDataLen; /// /// Supported link speeds are in units of mega bits. Common ethernet /// values are 10, 100 and 1000. Unused LinkSpeeds[] entries are zero /// filled. /// PXE_UINT32 LinkSpeeds[4]; /// /// Number of non-volatile storage items. /// PXE_UINT32 NvCount; /// /// Width of non-volatile storage item in bytes. 0, 1, 2 or 4 /// PXE_UINT16 NvWidth; /// /// Media header length. This is the typical media header length for /// this UNDI. This information is needed when allocating receive /// and transmit buffers. /// PXE_UINT16 MediaHeaderLen; /// /// Number of bytes in the NIC hardware (MAC) address. /// PXE_UINT16 HWaddrLen; /// /// Maximum number of multicast MAC addresses in the multicast /// MAC address filter list. /// PXE_UINT16 MCastFilterCnt; /// /// Default number and size of transmit and receive buffers that will /// be allocated by the UNDI. If MemoryRequired is non-zero, this /// allocation will come out of the memory buffer given to the Initialize /// command. If MemoryRequired is zero, this allocation will come out of /// memory on the NIC. /// PXE_UINT16 TxBufCnt; PXE_UINT16 TxBufSize; PXE_UINT16 RxBufCnt; PXE_UINT16 RxBufSize; /// /// Hardware interface types defined in the Assigned Numbers RFC /// and used in DHCP and ARP packets. /// See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros. /// PXE_UINT8 IFtype; /// /// Supported duplex. See PXE_DUPLEX_xxxxx #defines below. /// PXE_UINT8 SupportedDuplexModes; /// /// Supported loopback options. See PXE_LOOPBACK_xxxxx #defines below. /// PXE_UINT8 SupportedLoopBackModes; } PXE_DB_GET_INIT_INFO; #define PXE_MAX_TXRX_UNIT_ETHER 1500 #define PXE_HWADDR_LEN_ETHER 0x0006 #define PXE_MAC_HEADER_LEN_ETHER 0x000E #define PXE_DUPLEX_ENABLE_FULL_SUPPORTED 1 #define PXE_DUPLEX_FORCE_FULL_SUPPORTED 2 #define PXE_LOOPBACK_INTERNAL_SUPPORTED 1 #define PXE_LOOPBACK_EXTERNAL_SUPPORTED 2 typedef struct s_pxe_pci_config_info { /// /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union. /// For PCI bus devices, this field is set to PXE_BUSTYPE_PCI. /// UINT32 BusType; /// /// This identifies the PCI network device that this UNDI interface. /// is bound to. /// UINT16 Bus; UINT8 Device; UINT8 Function; /// /// This is a copy of the PCI configuration space for this /// network device. /// union { UINT8 Byte[256]; UINT16 Word[128]; UINT32 Dword[64]; } Config; } PXE_PCI_CONFIG_INFO; typedef struct s_pxe_pcc_config_info { /// /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union. /// For PCC bus devices, this field is set to PXE_BUSTYPE_PCC. /// PXE_UINT32 BusType; /// /// This identifies the PCC network device that this UNDI interface /// is bound to. /// PXE_UINT16 Bus; PXE_UINT8 Device; PXE_UINT8 Function; /// /// This is a copy of the PCC configuration space for this /// network device. /// union { PXE_UINT8 Byte[256]; PXE_UINT16 Word[128]; PXE_UINT32 Dword[64]; } Config; } PXE_PCC_CONFIG_INFO; typedef union u_pxe_db_get_config_info { PXE_PCI_CONFIG_INFO pci; PXE_PCC_CONFIG_INFO pcc; } PXE_DB_GET_CONFIG_INFO; typedef struct s_pxe_cpb_initialize { /// /// Address of first (lowest) byte of the memory buffer. This buffer must /// be in contiguous physical memory and cannot be swapped out. The UNDI /// will be using this for transmit and receive buffering. /// PXE_UINT64 MemoryAddr; /// /// MemoryLength must be greater than or equal to MemoryRequired /// returned by the Get Init Info command. /// PXE_UINT32 MemoryLength; /// /// Desired link speed in Mbit/sec. Common ethernet values are 10, 100 /// and 1000. Setting a value of zero will auto-detect and/or use the /// default link speed (operation depends on UNDI/NIC functionality). /// PXE_UINT32 LinkSpeed; /// /// Suggested number and size of receive and transmit buffers to /// allocate. If MemoryAddr and MemoryLength are non-zero, this /// allocation comes out of the supplied memory buffer. If MemoryAddr /// and MemoryLength are zero, this allocation comes out of memory /// on the NIC. /// /// If these fields are set to zero, the UNDI will allocate buffer /// counts and sizes as it sees fit. /// PXE_UINT16 TxBufCnt; PXE_UINT16 TxBufSize; PXE_UINT16 RxBufCnt; PXE_UINT16 RxBufSize; /// /// The following configuration parameters are optional and must be zero /// to use the default values. /// PXE_UINT8 DuplexMode; PXE_UINT8 LoopBackMode; } PXE_CPB_INITIALIZE; #define PXE_DUPLEX_DEFAULT 0x00 #define PXE_FORCE_FULL_DUPLEX 0x01 #define PXE_ENABLE_FULL_DUPLEX 0x02 #define PXE_FORCE_HALF_DUPLEX 0x04 #define PXE_DISABLE_FULL_DUPLEX 0x08 #define LOOPBACK_NORMAL 0 #define LOOPBACK_INTERNAL 1 #define LOOPBACK_EXTERNAL 2 typedef struct s_pxe_db_initialize { /// /// Actual amount of memory used from the supplied memory buffer. This /// may be less that the amount of memory suppllied and may be zero if /// the UNDI and network device do not use external memory buffers. /// /// Memory used by the UNDI and network device is allocated from the /// lowest memory buffer address. /// PXE_UINT32 MemoryUsed; /// /// Actual number and size of receive and transmit buffers that were /// allocated. /// PXE_UINT16 TxBufCnt; PXE_UINT16 TxBufSize; PXE_UINT16 RxBufCnt; PXE_UINT16 RxBufSize; } PXE_DB_INITIALIZE; typedef struct s_pxe_cpb_receive_filters { /// /// List of multicast MAC addresses. This list, if present, will /// replace the existing multicast MAC address filter list. /// PXE_MAC_ADDR MCastList[MAX_MCAST_ADDRESS_CNT]; } PXE_CPB_RECEIVE_FILTERS; typedef struct s_pxe_db_receive_filters { /// /// Filtered multicast MAC address list. /// PXE_MAC_ADDR MCastList[MAX_MCAST_ADDRESS_CNT]; } PXE_DB_RECEIVE_FILTERS; typedef struct s_pxe_cpb_station_address { /// /// If supplied and supported, the current station MAC address /// will be changed. /// PXE_MAC_ADDR StationAddr; } PXE_CPB_STATION_ADDRESS; typedef struct s_pxe_dpb_station_address { /// /// Current station MAC address. /// PXE_MAC_ADDR StationAddr; /// /// Station broadcast MAC address. /// PXE_MAC_ADDR BroadcastAddr; /// /// Permanent station MAC address. /// PXE_MAC_ADDR PermanentAddr; } PXE_DB_STATION_ADDRESS; typedef struct s_pxe_db_statistics { /// /// Bit field identifying what statistic data is collected by the /// UNDI/NIC. /// If bit 0x00 is set, Data[0x00] is collected. /// If bit 0x01 is set, Data[0x01] is collected. /// If bit 0x20 is set, Data[0x20] is collected. /// If bit 0x21 is set, Data[0x21] is collected. /// Etc. /// PXE_UINT64 Supported; /// /// Statistic data. /// PXE_UINT64 Data[64]; } PXE_DB_STATISTICS; /// /// Total number of frames received. Includes frames with errors and /// dropped frames. /// #define PXE_STATISTICS_RX_TOTAL_FRAMES 0x00 /// /// Number of valid frames received and copied into receive buffers. /// #define PXE_STATISTICS_RX_GOOD_FRAMES 0x01 /// /// Number of frames below the minimum length for the media. /// This would be <64 for ethernet. /// #define PXE_STATISTICS_RX_UNDERSIZE_FRAMES 0x02 /// /// Number of frames longer than the maxminum length for the /// media. This would be >1500 for ethernet. /// #define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03 /// /// Valid frames that were dropped because receive buffers were full. /// #define PXE_STATISTICS_RX_DROPPED_FRAMES 0x04 /// /// Number of valid unicast frames received and not dropped. /// #define PXE_STATISTICS_RX_UNICAST_FRAMES 0x05 /// /// Number of valid broadcast frames received and not dropped. /// #define PXE_STATISTICS_RX_BROADCAST_FRAMES 0x06 /// /// Number of valid mutlicast frames received and not dropped. /// #define PXE_STATISTICS_RX_MULTICAST_FRAMES 0x07 /// /// Number of frames w/ CRC or alignment errors. /// #define PXE_STATISTICS_RX_CRC_ERROR_FRAMES 0x08 /// /// Total number of bytes received. Includes frames with errors /// and dropped frames. /// #define PXE_STATISTICS_RX_TOTAL_BYTES 0x09 /// /// Transmit statistics. /// #define PXE_STATISTICS_TX_TOTAL_FRAMES 0x0A #define PXE_STATISTICS_TX_GOOD_FRAMES 0x0B #define PXE_STATISTICS_TX_UNDERSIZE_FRAMES 0x0C #define PXE_STATISTICS_TX_OVERSIZE_FRAMES 0x0D #define PXE_STATISTICS_TX_DROPPED_FRAMES 0x0E #define PXE_STATISTICS_TX_UNICAST_FRAMES 0x0F #define PXE_STATISTICS_TX_BROADCAST_FRAMES 0x10 #define PXE_STATISTICS_TX_MULTICAST_FRAMES 0x11 #define PXE_STATISTICS_TX_CRC_ERROR_FRAMES 0x12 #define PXE_STATISTICS_TX_TOTAL_BYTES 0x13 /// /// Number of collisions detection on this subnet. /// #define PXE_STATISTICS_COLLISIONS 0x14 /// /// Number of frames destined for unsupported protocol. /// #define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15 /// /// Number of valid frames received that were duplicated. /// #define PXE_STATISTICS_RX_DUPLICATED_FRAMES 0x16 /// /// Number of encrypted frames received that failed to decrypt. /// #define PXE_STATISTICS_RX_DECRYPT_ERROR_FRAMES 0x17 /// /// Number of frames that failed to transmit after exceeding the retry limit. /// #define PXE_STATISTICS_TX_ERROR_FRAMES 0x18 /// /// Number of frames transmitted successfully after more than one attempt. /// #define PXE_STATISTICS_TX_RETRY_FRAMES 0x19 typedef struct s_pxe_cpb_mcast_ip_to_mac { /// /// Multicast IP address to be converted to multicast MAC address. /// PXE_IP_ADDR IP; } PXE_CPB_MCAST_IP_TO_MAC; typedef struct s_pxe_db_mcast_ip_to_mac { /// /// Multicast MAC address. /// PXE_MAC_ADDR MAC; } PXE_DB_MCAST_IP_TO_MAC; typedef struct s_pxe_cpb_nvdata_sparse { /// /// NvData item list. Only items in this list will be updated. /// struct { /// /// Non-volatile storage address to be changed. /// PXE_UINT32 Addr; /// /// Data item to write into above storage address. /// union { PXE_UINT8 Byte; PXE_UINT16 Word; PXE_UINT32 Dword; } Data; } Item[MAX_EEPROM_LEN]; } PXE_CPB_NVDATA_SPARSE; /// /// When using bulk update, the size of the CPB structure must be /// the same size as the non-volatile NIC storage. /// typedef union u_pxe_cpb_nvdata_bulk { /// /// Array of byte-wide data items. /// PXE_UINT8 Byte[MAX_EEPROM_LEN << 2]; /// /// Array of word-wide data items. /// PXE_UINT16 Word[MAX_EEPROM_LEN << 1]; /// /// Array of dword-wide data items. /// PXE_UINT32 Dword[MAX_EEPROM_LEN]; } PXE_CPB_NVDATA_BULK; typedef struct s_pxe_db_nvdata { /// /// Arrays of data items from non-volatile storage. /// union { /// /// Array of byte-wide data items. /// PXE_UINT8 Byte[MAX_EEPROM_LEN << 2]; /// /// Array of word-wide data items. /// PXE_UINT16 Word[MAX_EEPROM_LEN << 1]; /// /// Array of dword-wide data items. /// PXE_UINT32 Dword[MAX_EEPROM_LEN]; } Data; } PXE_DB_NVDATA; typedef struct s_pxe_db_get_status { /// /// Length of next receive frame (header + data). If this is zero, /// there is no next receive frame available. /// PXE_UINT32 RxFrameLen; /// /// Reserved, set to zero. /// PXE_UINT32 reserved; /// /// Addresses of transmitted buffers that need to be recycled. /// PXE_UINT64 TxBuffer[MAX_XMIT_BUFFERS]; } PXE_DB_GET_STATUS; typedef struct s_pxe_cpb_fill_header { /// /// Source and destination MAC addresses. These will be copied into /// the media header without doing byte swapping. /// PXE_MAC_ADDR SrcAddr; PXE_MAC_ADDR DestAddr; /// /// Address of first byte of media header. The first byte of packet data /// follows the last byte of the media header. /// PXE_UINT64 MediaHeader; /// /// Length of packet data in bytes (not including the media header). /// PXE_UINT32 PacketLen; /// /// Protocol type. This will be copied into the media header without /// doing byte swapping. Protocol type numbers can be obtained from /// the Assigned Numbers RFC 1700. /// PXE_UINT16 Protocol; /// /// Length of the media header in bytes. /// PXE_UINT16 MediaHeaderLen; } PXE_CPB_FILL_HEADER; #define PXE_PROTOCOL_ETHERNET_IP 0x0800 #define PXE_PROTOCOL_ETHERNET_ARP 0x0806 #define MAX_XMIT_FRAGMENTS 16 typedef struct s_pxe_cpb_fill_header_fragmented { /// /// Source and destination MAC addresses. These will be copied into /// the media header without doing byte swapping. /// PXE_MAC_ADDR SrcAddr; PXE_MAC_ADDR DestAddr; /// /// Length of packet data in bytes (not including the media header). /// PXE_UINT32 PacketLen; /// /// Protocol type. This will be copied into the media header without /// doing byte swapping. Protocol type numbers can be obtained from /// the Assigned Numbers RFC 1700. /// PXE_MEDIA_PROTOCOL Protocol; /// /// Length of the media header in bytes. /// PXE_UINT16 MediaHeaderLen; /// /// Number of packet fragment descriptors. /// PXE_UINT16 FragCnt; /// /// Reserved, must be set to zero. /// PXE_UINT16 reserved; /// /// Array of packet fragment descriptors. The first byte of the media /// header is the first byte of the first fragment. /// struct { /// /// Address of this packet fragment. /// PXE_UINT64 FragAddr; /// /// Length of this packet fragment. /// PXE_UINT32 FragLen; /// /// Reserved, must be set to zero. /// PXE_UINT32 reserved; } FragDesc[MAX_XMIT_FRAGMENTS]; } PXE_CPB_FILL_HEADER_FRAGMENTED; typedef struct s_pxe_cpb_transmit { /// /// Address of first byte of frame buffer. This is also the first byte /// of the media header. /// PXE_UINT64 FrameAddr; /// /// Length of the data portion of the frame buffer in bytes. Do not /// include the length of the media header. /// PXE_UINT32 DataLen; /// /// Length of the media header in bytes. /// PXE_UINT16 MediaheaderLen; /// /// Reserved, must be zero. /// PXE_UINT16 reserved; } PXE_CPB_TRANSMIT; typedef struct s_pxe_cpb_transmit_fragments { /// /// Length of packet data in bytes (not including the media header). /// PXE_UINT32 FrameLen; /// /// Length of the media header in bytes. /// PXE_UINT16 MediaheaderLen; /// /// Number of packet fragment descriptors. /// PXE_UINT16 FragCnt; /// /// Array of frame fragment descriptors. The first byte of the first /// fragment is also the first byte of the media header. /// struct { /// /// Address of this frame fragment. /// PXE_UINT64 FragAddr; /// /// Length of this frame fragment. /// PXE_UINT32 FragLen; /// /// Reserved, must be set to zero. /// PXE_UINT32 reserved; } FragDesc[MAX_XMIT_FRAGMENTS]; } PXE_CPB_TRANSMIT_FRAGMENTS; typedef struct s_pxe_cpb_receive { /// /// Address of first byte of receive buffer. This is also the first byte /// of the frame header. /// PXE_UINT64 BufferAddr; /// /// Length of receive buffer. This must be large enough to hold the /// received frame (media header + data). If the length of smaller than /// the received frame, data will be lost. /// PXE_UINT32 BufferLen; /// /// Reserved, must be set to zero. /// PXE_UINT32 reserved; } PXE_CPB_RECEIVE; typedef struct s_pxe_db_receive { /// /// Source and destination MAC addresses from media header. /// PXE_MAC_ADDR SrcAddr; PXE_MAC_ADDR DestAddr; /// /// Length of received frame. May be larger than receive buffer size. /// The receive buffer will not be overwritten. This is how to tell /// if data was lost because the receive buffer was too small. /// PXE_UINT32 FrameLen; /// /// Protocol type from media header. /// PXE_MEDIA_PROTOCOL Protocol; /// /// Length of media header in received frame. /// PXE_UINT16 MediaHeaderLen; /// /// Type of receive frame. /// PXE_FRAME_TYPE Type; /// /// Reserved, must be zero. /// PXE_UINT8 reserved[7]; } PXE_DB_RECEIVE; #pragma pack() #endif /** @file Include file that supports UEFI. This include file must contain things defined in the UEFI 2.7 specification. If a code construct is defined in the UEFI 2.7 specification it must be included by this include file. Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __UEFI_SPEC_H__ #define __UEFI_SPEC_H__ #include #include #include #include #include /// /// Enumeration of EFI memory allocation types. /// typedef enum { /// /// Allocate any available range of pages that satisfies the request. /// AllocateAnyPages, /// /// Allocate any available range of pages whose uppermost address is less than /// or equal to a specified maximum address. /// AllocateMaxAddress, /// /// Allocate pages at a specified address. /// AllocateAddress, /// /// Maximum enumeration value that may be used for bounds checking. /// MaxAllocateType } EFI_ALLOCATE_TYPE; // // Bit definitions for EFI_TIME.Daylight // #define EFI_TIME_ADJUST_DAYLIGHT 0x01 #define EFI_TIME_IN_DAYLIGHT 0x02 /// /// Value definition for EFI_TIME.TimeZone. /// #define EFI_UNSPECIFIED_TIMEZONE 0x07FF // // Memory cacheability attributes // #define EFI_MEMORY_UC 0x0000000000000001ULL #define EFI_MEMORY_WC 0x0000000000000002ULL #define EFI_MEMORY_WT 0x0000000000000004ULL #define EFI_MEMORY_WB 0x0000000000000008ULL #define EFI_MEMORY_UCE 0x0000000000000010ULL // // Physical memory protection attributes // // Note: UEFI spec 2.5 and following: use EFI_MEMORY_RO as write-protected physical memory // protection attribute. Also, EFI_MEMORY_WP means cacheability attribute. // #define EFI_MEMORY_WP 0x0000000000001000ULL #define EFI_MEMORY_RP 0x0000000000002000ULL #define EFI_MEMORY_XP 0x0000000000004000ULL #define EFI_MEMORY_RO 0x0000000000020000ULL // // Physical memory persistence attribute. // The memory region supports byte-addressable non-volatility. // #define EFI_MEMORY_NV 0x0000000000008000ULL // // The memory region provides higher reliability relative to other memory in the system. // If all memory has the same reliability, then this bit is not used. // #define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000ULL // // Note: UEFI spec 2.8 and following: // // Specific-purpose memory (SPM). The memory is earmarked for // specific purposes such as for specific device drivers or applications. // The SPM attribute serves as a hint to the OS to avoid allocating this // memory for core OS data or code that can not be relocated. // #define EFI_MEMORY_SP 0x0000000000040000ULL // // If this flag is set, the memory region is capable of being // protected with the CPU's memory cryptographic // capabilities. If this flag is clear, the memory region is not // capable of being protected with the CPU's memory // cryptographic capabilities or the CPU does not support CPU // memory cryptographic capabilities. // #define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000ULL // // Runtime memory attribute // #define EFI_MEMORY_RUNTIME 0x8000000000000000ULL // // Attributes bitmasks, grouped by type // #define EFI_CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) #define EFI_MEMORY_ACCESS_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO) #define EFI_MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_ACCESS_MASK | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO) /// /// Memory descriptor version number. /// #define EFI_MEMORY_DESCRIPTOR_VERSION 1 /// /// Definition of an EFI memory descriptor. /// typedef struct { /// /// Type of the memory region. /// Type EFI_MEMORY_TYPE is defined in the /// AllocatePages() function description. /// UINT32 Type; /// /// Physical address of the first byte in the memory region. PhysicalStart must be /// aligned on a 4 KiB boundary, and must not be above 0xfffffffffffff000. Type /// EFI_PHYSICAL_ADDRESS is defined in the AllocatePages() function description /// EFI_PHYSICAL_ADDRESS PhysicalStart; /// /// Virtual address of the first byte in the memory region. /// VirtualStart must be aligned on a 4 KiB boundary, /// and must not be above 0xfffffffffffff000. /// EFI_VIRTUAL_ADDRESS VirtualStart; /// /// NumberOfPagesNumber of 4 KiB pages in the memory region. /// NumberOfPages must not be 0, and must not be any value /// that would represent a memory page with a start address, /// either physical or virtual, above 0xfffffffffffff000. /// UINT64 NumberOfPages; /// /// Attributes of the memory region that describe the bit mask of capabilities /// for that memory region, and not necessarily the current settings for that /// memory region. /// UINT64 Attribute; } EFI_MEMORY_DESCRIPTOR; /** Allocates memory pages from the system. @param[in] Type The type of allocation to perform. @param[in] MemoryType The type of memory to allocate. MemoryType values in the range 0x70000000..0x7FFFFFFF are reserved for OEM use. MemoryType values in the range 0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders that are provided by operating system vendors. @param[in] Pages The number of contiguous 4 KB pages to allocate. @param[in, out] Memory The pointer to a physical address. On input, the way in which the address is used depends on the value of Type. @retval EFI_SUCCESS The requested pages were allocated. @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or AllocateMaxAddress or AllocateAddress. 2) MemoryType is in the range EfiMaxMemoryType..0x6FFFFFFF. 3) Memory is NULL. 4) MemoryType is EfiPersistentMemory or EfiUnacceptedMemoryType. @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. @retval EFI_NOT_FOUND The requested pages could not be found. **/ typedef EFI_STATUS (EFIAPI *EFI_ALLOCATE_PAGES)( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *Memory ); /** Frees memory pages. @param[in] Memory The base physical address of the pages to be freed. @param[in] Pages The number of contiguous 4 KB pages to free. @retval EFI_SUCCESS The requested pages were freed. @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid. @retval EFI_NOT_FOUND The requested memory pages were not allocated with AllocatePages(). **/ typedef EFI_STATUS (EFIAPI *EFI_FREE_PAGES)( IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN Pages ); /** Returns the current memory map. @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the MemoryMap buffer. On input, this is the size of the buffer allocated by the caller. On output, it is the size of the buffer returned by the firmware if the buffer was large enough, or the size of the buffer needed to contain the map if the buffer was too small. @param[out] MemoryMap A pointer to the buffer in which firmware places the current memory map. @param[out] MapKey A pointer to the location in which firmware returns the key for the current memory map. @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number associated with the EFI_MEMORY_DESCRIPTOR. @retval EFI_SUCCESS The memory map was returned in the MemoryMap buffer. @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current buffer size needed to hold the memory map is returned in MemoryMapSize. @retval EFI_INVALID_PARAMETER 1) MemoryMapSize is NULL. 2) The MemoryMap buffer is not too small and MemoryMap is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_MEMORY_MAP)( IN OUT UINTN *MemoryMapSize, OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, OUT UINTN *MapKey, OUT UINTN *DescriptorSize, OUT UINT32 *DescriptorVersion ); /** Allocates pool memory. @param[in] PoolType The type of pool to allocate. MemoryType values in the range 0x70000000..0x7FFFFFFF are reserved for OEM use. MemoryType values in the range 0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders that are provided by operating system vendors. @param[in] Size The number of bytes to allocate from the pool. @param[out] Buffer A pointer to a pointer to the allocated buffer if the call succeeds; undefined otherwise. @retval EFI_SUCCESS The requested number of bytes was allocated. @retval EFI_OUT_OF_RESOURCES The pool requested could not be allocated. @retval EFI_INVALID_PARAMETER Buffer is NULL. PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF. PoolType is EfiPersistentMemory. **/ typedef EFI_STATUS (EFIAPI *EFI_ALLOCATE_POOL)( IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer ); /** Returns pool memory to the system. @param[in] Buffer The pointer to the buffer to free. @retval EFI_SUCCESS The memory was returned to the system. @retval EFI_INVALID_PARAMETER Buffer was invalid. **/ typedef EFI_STATUS (EFIAPI *EFI_FREE_POOL)( IN VOID *Buffer ); /** Changes the runtime addressing mode of EFI firmware from physical to virtual. @param[in] MemoryMapSize The size in bytes of VirtualMap. @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. @param[in] DescriptorVersion The version of the structure entries in VirtualMap. @param[in] VirtualMap An array of memory descriptors which contain new virtual address mapping information for all runtime ranges. @retval EFI_SUCCESS The virtual address map has been applied. @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in virtual address mapped mode. @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory map that requires a mapping. @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found in the memory map. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)( IN UINTN MemoryMapSize, IN UINTN DescriptorSize, IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap ); /** Connects one or more drivers to a controller. @param[in] ControllerHandle The handle of the controller to which driver(s) are to be connected. @param[in] DriverImageHandle A pointer to an ordered list handles that support the EFI_DRIVER_BINDING_PROTOCOL. @param[in] RemainingDevicePath A pointer to the device path that specifies a child of the controller specified by ControllerHandle. @param[in] Recursive If TRUE, then ConnectController() is called recursively until the entire tree of controllers below the controller specified by ControllerHandle have been created. If FALSE, then the tree of controllers is only expanded one level. @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. 2) No drivers were connected to ControllerHandle, but RemainingDevicePath is not NULL, and it is an End Device Path Node. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances present in the system. 2) No drivers were connected to ControllerHandle. @retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device drivers on the device path associated with the ControllerHandle or specified by the RemainingDevicePath. **/ typedef EFI_STATUS (EFIAPI *EFI_CONNECT_CONTROLLER)( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN BOOLEAN Recursive ); /** Disconnects one or more drivers from a controller. @param[in] ControllerHandle The handle of the controller from which driver(s) are to be disconnected. @param[in] DriverImageHandle The driver to disconnect from ControllerHandle. If DriverImageHandle is NULL, then all the drivers currently managing ControllerHandle are disconnected from ControllerHandle. @param[in] ChildHandle The handle of the child to destroy. If ChildHandle is NULL, then all the children of ControllerHandle are destroyed before the drivers are disconnected from ControllerHandle. @retval EFI_SUCCESS 1) One or more drivers were disconnected from the controller. 2) On entry, no drivers are managing ControllerHandle. 3) DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle. @retval EFI_INVALID_PARAMETER 1) ControllerHandle is NULL. 2) DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE. 3) ChildHandle is not NULL, and it is not a valid EFI_HANDLE. 4) DriverImageHandle does not support the EFI_DRIVER_BINDING_PROTOCOL. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to disconnect any drivers from ControllerHandle. @retval EFI_DEVICE_ERROR The controller could not be disconnected because of a device error. **/ typedef EFI_STATUS (EFIAPI *EFI_DISCONNECT_CONTROLLER)( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle OPTIONAL, IN EFI_HANDLE ChildHandle OPTIONAL ); // // ConvertPointer DebugDisposition type. // #define EFI_OPTIONAL_PTR 0x00000001 /** Determines the new virtual address that is to be used on subsequent memory accesses. @param[in] DebugDisposition Supplies type information for the pointer being converted. @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed for the new virtual address mappings being applied. @retval EFI_SUCCESS The pointer pointed to by Address was modified. @retval EFI_INVALID_PARAMETER 1) Address is NULL. 2) *Address is NULL and DebugDisposition does not have the EFI_OPTIONAL_PTR bit set. @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part of the current memory map. This is normally fatal. **/ typedef EFI_STATUS (EFIAPI *EFI_CONVERT_POINTER)( IN UINTN DebugDisposition, IN OUT VOID **Address ); // // These types can be ORed together as needed - for example, // EVT_TIMER might be Ored with EVT_NOTIFY_WAIT or // EVT_NOTIFY_SIGNAL. // #define EVT_TIMER 0x80000000 #define EVT_RUNTIME 0x40000000 #define EVT_NOTIFY_WAIT 0x00000100 #define EVT_NOTIFY_SIGNAL 0x00000200 #define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 #define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 // // The event's NotifyContext pointer points to a runtime memory // address. // The event is deprecated in UEFI2.0 and later specifications. // #define EVT_RUNTIME_CONTEXT 0x20000000 /** Invoke a notification event @param[in] Event Event whose notification function is being invoked. @param[in] Context The pointer to the notification function's context, which is implementation-dependent. **/ typedef VOID (EFIAPI *EFI_EVENT_NOTIFY)( IN EFI_EVENT Event, IN VOID *Context ); /** Creates an event. @param[in] Type The type of event to create and its mode and attributes. @param[in] NotifyTpl The task priority level of event notifications, if needed. @param[in] NotifyFunction The pointer to the event's notification function, if any. @param[in] NotifyContext The pointer to the notification function's context; corresponds to parameter Context in the notification function. @param[out] Event The pointer to the newly created event if the call succeeds; undefined otherwise. @retval EFI_SUCCESS The event structure was created. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The event could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_CREATE_EVENT)( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext, OUT EFI_EVENT *Event ); /** Creates an event in a group. @param[in] Type The type of event to create and its mode and attributes. @param[in] NotifyTpl The task priority level of event notifications,if needed. @param[in] NotifyFunction The pointer to the event's notification function, if any. @param[in] NotifyContext The pointer to the notification function's context; corresponds to parameter Context in the notification function. @param[in] EventGroup The pointer to the unique identifier of the group to which this event belongs. If this is NULL, then the function behaves as if the parameters were passed to CreateEvent. @param[out] Event The pointer to the newly created event if the call succeeds; undefined otherwise. @retval EFI_SUCCESS The event structure was created. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The event could not be allocated. **/ typedef EFI_STATUS (EFIAPI *EFI_CREATE_EVENT_EX)( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN CONST VOID *NotifyContext OPTIONAL, IN CONST EFI_GUID *EventGroup OPTIONAL, OUT EFI_EVENT *Event ); /// /// Timer delay types /// typedef enum { /// /// An event's timer settings is to be cancelled and not trigger time is to be set/ /// TimerCancel, /// /// An event is to be signaled periodically at a specified interval from the current time. /// TimerPeriodic, /// /// An event is to be signaled once at a specified interval from the current time. /// TimerRelative } EFI_TIMER_DELAY; /** Sets the type of timer and the trigger time for a timer event. @param[in] Event The timer event that is to be signaled at the specified time. @param[in] Type The type of time that is specified in TriggerTime. @param[in] TriggerTime The number of 100ns units until the timer expires. A TriggerTime of 0 is legal. If Type is TimerRelative and TriggerTime is 0, then the timer event will be signaled on the next timer tick. If Type is TimerPeriodic and TriggerTime is 0, then the timer event will be signaled on every timer tick. @retval EFI_SUCCESS The event has been set to be signaled at the requested time. @retval EFI_INVALID_PARAMETER Event or Type is not valid. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_TIMER)( IN EFI_EVENT Event, IN EFI_TIMER_DELAY Type, IN UINT64 TriggerTime ); /** Signals an event. @param[in] Event The event to signal. @retval EFI_SUCCESS The event has been signaled. **/ typedef EFI_STATUS (EFIAPI *EFI_SIGNAL_EVENT)( IN EFI_EVENT Event ); /** Stops execution until an event is signaled. @param[in] NumberOfEvents The number of events in the Event array. @param[in] Event An array of EFI_EVENT. @param[out] Index The pointer to the index of the event which satisfied the wait condition. @retval EFI_SUCCESS The event indicated by Index was signaled. @retval EFI_INVALID_PARAMETER 1) NumberOfEvents is 0. 2) The event indicated by Index is of type EVT_NOTIFY_SIGNAL. @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION. **/ typedef EFI_STATUS (EFIAPI *EFI_WAIT_FOR_EVENT)( IN UINTN NumberOfEvents, IN EFI_EVENT *Event, OUT UINTN *Index ); /** Closes an event. @param[in] Event The event to close. @retval EFI_SUCCESS The event has been closed. **/ typedef EFI_STATUS (EFIAPI *EFI_CLOSE_EVENT)( IN EFI_EVENT Event ); /** Checks whether an event is in the signaled state. @param[in] Event The event to check. @retval EFI_SUCCESS The event is in the signaled state. @retval EFI_NOT_READY The event is not in the signaled state. @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL. **/ typedef EFI_STATUS (EFIAPI *EFI_CHECK_EVENT)( IN EFI_EVENT Event ); // // Task priority level // #define TPL_APPLICATION 4 #define TPL_CALLBACK 8 #define TPL_NOTIFY 16 #define TPL_HIGH_LEVEL 31 /** Raises a task's priority level and returns its previous level. @param[in] NewTpl The new task priority level. @return Previous task priority level **/ typedef EFI_TPL (EFIAPI *EFI_RAISE_TPL)( IN EFI_TPL NewTpl ); /** Restores a task's priority level to its previous value. @param[in] OldTpl The previous task priority level to restore. **/ typedef VOID (EFIAPI *EFI_RESTORE_TPL)( IN EFI_TPL OldTpl ); /** Returns the value of a variable. @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. @param[in] VendorGuid A unique identifier for the vendor. @param[out] Attributes If not NULL, a pointer to the memory location to return the attributes bitmask for the variable. @param[in, out] DataSize On input, the size in bytes of the return Data buffer. On output the size of data returned in Data. @param[out] Data The buffer to return the contents of the variable. May be NULL with a zero DataSize in order to determine the size buffer needed. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND The variable was not found. @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. @retval EFI_INVALID_PARAMETER VariableName is NULL. @retval EFI_INVALID_PARAMETER VendorGuid is NULL. @retval EFI_INVALID_PARAMETER DataSize is NULL. @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_VARIABLE)( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, IN OUT UINTN *DataSize, OUT VOID *Data OPTIONAL ); /** Enumerates the current variable names. @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input string supplied in VariableName buffer. @param[in, out] VariableName On input, supplies the last VariableName that was returned by GetNextVariableName(). On output, returns the Nullterminated string of the current variable. @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName(). On output, returns the VendorGuid of the current variable. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND The next variable was not found. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. VariableNameSize has been updated with the size needed to complete the request. @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. @retval EFI_INVALID_PARAMETER VariableName is NULL. @retval EFI_INVALID_PARAMETER VendorGuid is NULL. @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and GUID of an existing variable. @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)( IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid ); /** Sets the value of a variable. @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. Each VariableName is unique for each VendorGuid. VariableName must contain 1 or more characters. If VariableName is an empty string, then EFI_INVALID_PARAMETER is returned. @param[in] VendorGuid A unique identifier for the vendor. @param[in] Attributes Attributes bitmask to set for the variable. @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is set, then a SetVariable() call with a DataSize of zero will not cause any change to the variable value (the timestamp associated with the variable may be updated however even if no new data value is provided,see the description of the EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). @param[in] Data The contents for the variable. @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as defined by the Attributes. @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the DataSize exceeds the maximum allowed. @retval EFI_INVALID_PARAMETER VariableName is an empty string. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_WRITE_PROTECTED The variable in question is read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo does NOT pass the validation check carried out by the firmware. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_VARIABLE)( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data ); /// /// This provides the capabilities of the /// real time clock device as exposed through the EFI interfaces. /// typedef struct { /// /// Provides the reporting resolution of the real-time clock device in /// counts per second. For a normal PC-AT CMOS RTC device, this /// value would be 1 Hz, or 1, to indicate that the device only reports /// the time to the resolution of 1 second. /// UINT32 Resolution; /// /// Provides the timekeeping accuracy of the real-time clock in an /// error rate of 1E-6 parts per million. For a clock with an accuracy /// of 50 parts per million, the value in this field would be /// 50,000,000. /// UINT32 Accuracy; /// /// A TRUE indicates that a time set operation clears the device's /// time below the Resolution reporting level. A FALSE /// indicates that the state below the Resolution level of the /// device is not cleared when the time is set. Normal PC-AT CMOS /// RTC devices set this value to FALSE. /// BOOLEAN SetsToZero; } EFI_TIME_CAPABILITIES; /** Returns the current time and date information, and the time-keeping capabilities of the hardware platform. @param[out] Time A pointer to storage to receive a snapshot of the current time. @param[out] Capabilities An optional pointer to a buffer to receive the real time clock device's capabilities. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER Time is NULL. @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_TIME)( OUT EFI_TIME *Time, OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ); /** Sets the current local time and date information. @param[in] Time A pointer to the current time. @retval EFI_SUCCESS The operation completed successfully. @retval EFI_INVALID_PARAMETER A time field is out of range. @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_TIME)( IN EFI_TIME *Time ); /** Returns the current wakeup alarm clock setting. @param[out] Enabled Indicates if the alarm is currently enabled or disabled. @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. @param[out] Time The current alarm setting. @retval EFI_SUCCESS The alarm settings were returned. @retval EFI_INVALID_PARAMETER Enabled is NULL. @retval EFI_INVALID_PARAMETER Pending is NULL. @retval EFI_INVALID_PARAMETER Time is NULL. @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_WAKEUP_TIME)( OUT BOOLEAN *Enabled, OUT BOOLEAN *Pending, OUT EFI_TIME *Time ); /** Sets the system wakeup alarm clock time. @param[in] Enable Enable or disable the wakeup alarm. @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. If Enable is FALSE, then this parameter is optional, and may be NULL. @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If Enable is FALSE, then the wakeup alarm was disabled. @retval EFI_INVALID_PARAMETER A time field is out of range. @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_WAKEUP_TIME)( IN BOOLEAN Enable, IN EFI_TIME *Time OPTIONAL ); /** Loads an EFI image into memory. @param[in] BootPolicy If TRUE, indicates that the request originates from the boot manager, and that the boot manager is attempting to load FilePath as a boot selection. Ignored if SourceBuffer is not NULL. @param[in] ParentImageHandle The caller's image handle. @param[in] DevicePath The DeviceHandle specific file path from which the image is loaded. @param[in] SourceBuffer If not NULL, a pointer to the memory location containing a copy of the image to be loaded. @param[in] SourceSize The size in bytes of SourceBuffer. Ignored if SourceBuffer is NULL. @param[out] ImageHandle The pointer to the returned image handle that is created when the image is successfully loaded. @retval EFI_SUCCESS Image was loaded into memory correctly. @retval EFI_NOT_FOUND Both SourceBuffer and DevicePath are NULL. @retval EFI_INVALID_PARAMETER One or more parametes are invalid. @retval EFI_UNSUPPORTED The image type is not supported. @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient resources. @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not understood. @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the image from being loaded. NULL is returned in *ImageHandle. @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a valid EFI_LOADED_IMAGE_PROTOCOL. However, the current platform policy specifies that the image should not be started. **/ typedef EFI_STATUS (EFIAPI *EFI_IMAGE_LOAD)( IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN VOID *SourceBuffer OPTIONAL, IN UINTN SourceSize, OUT EFI_HANDLE *ImageHandle ); /** Transfers control to a loaded image's entry point. @param[in] ImageHandle Handle of image to be started. @param[out] ExitDataSize The pointer to the size, in bytes, of ExitData. @param[out] ExitData The pointer to a pointer to a data buffer that includes a Null-terminated string, optionally followed by additional binary data. @retval EFI_INVALID_PARAMETER ImageHandle is either an invalid image handle or the image has already been initialized with StartImage. @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. @return Exit code from image **/ typedef EFI_STATUS (EFIAPI *EFI_IMAGE_START)( IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, OUT CHAR16 **ExitData OPTIONAL ); /** Terminates a loaded EFI image and returns control to boot services. @param[in] ImageHandle Handle that identifies the image. This parameter is passed to the image on entry. @param[in] ExitStatus The image's exit code. @param[in] ExitDataSize The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS. @param[in] ExitData The pointer to a data buffer that includes a Null-terminated string, optionally followed by additional binary data. The string is a description that the caller may use to further indicate the reason for the image's exit. ExitData is only valid if ExitStatus is something other than EFI_SUCCESS. The ExitData buffer must be allocated by calling AllocatePool(). @retval EFI_SUCCESS The image specified by ImageHandle was unloaded. @retval EFI_INVALID_PARAMETER The image specified by ImageHandle has been loaded and started with LoadImage() and StartImage(), but the image is not the currently executing image. **/ typedef EFI_STATUS (EFIAPI *EFI_EXIT)( IN EFI_HANDLE ImageHandle, IN EFI_STATUS ExitStatus, IN UINTN ExitDataSize, IN CHAR16 *ExitData OPTIONAL ) __dead2; /** Unloads an image. @param[in] ImageHandle Handle that identifies the image to be unloaded. @retval EFI_SUCCESS The image has been unloaded. @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. **/ typedef EFI_STATUS (EFIAPI *EFI_IMAGE_UNLOAD)( IN EFI_HANDLE ImageHandle ); /** Terminates all boot services. @param[in] ImageHandle Handle that identifies the exiting image. @param[in] MapKey Key to the latest memory map. @retval EFI_SUCCESS Boot services have been terminated. @retval EFI_INVALID_PARAMETER MapKey is incorrect. **/ typedef EFI_STATUS (EFIAPI *EFI_EXIT_BOOT_SERVICES)( IN EFI_HANDLE ImageHandle, IN UINTN MapKey ); /** Induces a fine-grained stall. @param[in] Microseconds The number of microseconds to stall execution. @retval EFI_SUCCESS Execution was stalled at least the requested number of Microseconds. **/ typedef EFI_STATUS (EFIAPI *EFI_STALL)( IN UINTN Microseconds ); /** Sets the system's watchdog timer. @param[in] Timeout The number of seconds to set the watchdog timer to. @param[in] WatchdogCode The numeric code to log on a watchdog timer timeout event. @param[in] DataSize The size, in bytes, of WatchdogData. @param[in] WatchdogData A data buffer that includes a Null-terminated string, optionally followed by additional binary data. @retval EFI_SUCCESS The timeout has been set. @retval EFI_INVALID_PARAMETER The supplied WatchdogCode is invalid. @retval EFI_UNSUPPORTED The system does not have a watchdog timer. @retval EFI_DEVICE_ERROR The watchdog timer could not be programmed due to a hardware error. **/ typedef EFI_STATUS (EFIAPI *EFI_SET_WATCHDOG_TIMER)( IN UINTN Timeout, IN UINT64 WatchdogCode, IN UINTN DataSize, IN CHAR16 *WatchdogData OPTIONAL ); /** Resets the entire platform. @param[in] ResetType The type of reset to perform. @param[in] ResetStatus The status code for the reset. @param[in] DataSize The size, in bytes, of ResetData. @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown the data buffer starts with a Null-terminated string, optionally followed by additional binary data. The string is a description that the caller may use to further indicate the reason for the system reset. For a ResetType of EfiResetPlatformSpecific the data buffer also starts with a Null-terminated string that is followed by an EFI_GUID that describes the specific type of reset to perform. **/ typedef VOID (EFIAPI *EFI_RESET_SYSTEM)( IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, IN VOID *ResetData OPTIONAL ) __dead2; /** Returns a monotonically increasing count for the platform. @param[out] Count The pointer to returned value. @retval EFI_SUCCESS The next monotonic count was returned. @retval EFI_INVALID_PARAMETER Count is NULL. @retval EFI_DEVICE_ERROR The device is not functioning properly. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)( OUT UINT64 *Count ); /** Returns the next high 32 bits of the platform's monotonic counter. @param[out] HighCount The pointer to returned value. @retval EFI_SUCCESS The next high monotonic count was returned. @retval EFI_INVALID_PARAMETER HighCount is NULL. @retval EFI_DEVICE_ERROR The device is not functioning properly. **/ typedef EFI_STATUS (EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)( OUT UINT32 *HighCount ); /** Computes and returns a 32-bit CRC for a data buffer. @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. @param[in] DataSize The number of bytes in the buffer Data. @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data and DataSize. @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in Crc32. @retval EFI_INVALID_PARAMETER Data is NULL. @retval EFI_INVALID_PARAMETER Crc32 is NULL. @retval EFI_INVALID_PARAMETER DataSize is 0. **/ typedef EFI_STATUS (EFIAPI *EFI_CALCULATE_CRC32)( IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32 ); /** Copies the contents of one buffer to another buffer. @param[in] Destination The pointer to the destination buffer of the memory copy. @param[in] Source The pointer to the source buffer of the memory copy. @param[in] Length Number of bytes to copy from Source to Destination. **/ typedef VOID (EFIAPI *EFI_COPY_MEM)( IN VOID *Destination, IN VOID *Source, IN UINTN Length ); /** The SetMem() function fills a buffer with a specified value. @param[in] Buffer The pointer to the buffer to fill. @param[in] Size Number of bytes in Buffer to fill. @param[in] Value Value to fill Buffer with. **/ typedef VOID (EFIAPI *EFI_SET_MEM)( IN VOID *Buffer, IN UINTN Size, IN UINT8 Value ); /// /// Enumeration of EFI Interface Types /// typedef enum { /// /// Indicates that the supplied protocol interface is supplied in native form. /// EFI_NATIVE_INTERFACE } EFI_INTERFACE_TYPE; /** Installs a protocol interface on a device handle. If the handle does not exist, it is created and added to the list of handles in the system. InstallMultipleProtocolInterfaces() performs more error checking than InstallProtocolInterface(), so it is recommended that InstallMultipleProtocolInterfaces() be used in place of InstallProtocolInterface() @param[in, out] Handle A pointer to the EFI_HANDLE on which the interface is to be installed. @param[in] Protocol The numeric ID of the protocol interface. @param[in] InterfaceType Indicates whether Interface is supplied in native form. @param[in] Interface A pointer to the protocol interface. @retval EFI_SUCCESS The protocol interface was installed. @retval EFI_OUT_OF_RESOURCES Space for a new handle could not be allocated. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Protocol is NULL. @retval EFI_INVALID_PARAMETER InterfaceType is not EFI_NATIVE_INTERFACE. @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. **/ typedef EFI_STATUS (EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)( IN OUT EFI_HANDLE *Handle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface ); /** Installs one or more protocol interfaces into the boot services environment. @param[in, out] Handle The pointer to a handle to install the new protocol interfaces on, or a pointer to NULL if a new handle is to be allocated. @param ... A variable argument list containing pairs of protocol GUIDs and protocol interfaces. @retval EFI_SUCCESS All the protocol interface was installed. @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in the handle database. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. **/ typedef EFI_STATUS (EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)( IN OUT EFI_HANDLE *Handle, ... ); /** Reinstalls a protocol interface on a device handle. @param[in] Handle Handle on which the interface is to be reinstalled. @param[in] Protocol The numeric ID of the interface. @param[in] OldInterface A pointer to the old interface. NULL can be used if a structure is not associated with Protocol. @param[in] NewInterface A pointer to the new interface. @retval EFI_SUCCESS The protocol interface was reinstalled. @retval EFI_NOT_FOUND The OldInterface on the handle was not found. @retval EFI_ACCESS_DENIED The protocol interface could not be reinstalled, because OldInterface is still being used by a driver that will not release it. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Protocol is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, IN VOID *OldInterface, IN VOID *NewInterface ); /** Removes a protocol interface from a device handle. It is recommended that UninstallMultipleProtocolInterfaces() be used in place of UninstallProtocolInterface(). @param[in] Handle The handle on which the interface was installed. @param[in] Protocol The numeric ID of the interface. @param[in] Interface A pointer to the interface. @retval EFI_SUCCESS The interface was removed. @retval EFI_NOT_FOUND The interface was not found. @retval EFI_ACCESS_DENIED The interface was not removed because the interface is still being used by a driver. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Protocol is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, IN VOID *Interface ); /** Removes one or more protocol interfaces into the boot services environment. @param[in] Handle The handle to remove the protocol interfaces from. @param ... A variable argument list containing pairs of protocol GUIDs and protocol interfaces. @retval EFI_SUCCESS All the protocol interfaces were removed. @retval EFI_INVALID_PARAMETER One of the protocol interfaces was not previously installed on Handle. **/ typedef EFI_STATUS (EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)( IN EFI_HANDLE Handle, ... ); /** Queries a handle to determine if it supports a specified protocol. @param[in] Handle The handle being queried. @param[in] Protocol The published unique identifier of the protocol. @param[out] Interface Supplies the address where a pointer to the corresponding Protocol Interface is returned. @retval EFI_SUCCESS The interface information for the specified protocol was returned. @retval EFI_UNSUPPORTED The device does not support the specified protocol. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Protocol is NULL. @retval EFI_INVALID_PARAMETER Interface is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_HANDLE_PROTOCOL)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface ); #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 #define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 #define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 #define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 #define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 #define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 /** Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the handle, it opens the protocol on behalf of the calling agent. @param[in] Handle The handle for the protocol interface that is being opened. @param[in] Protocol The published unique identifier of the protocol. @param[out] Interface Supplies the address where a pointer to the corresponding Protocol Interface is returned. @param[in] AgentHandle The handle of the agent that is opening the protocol interface specified by Protocol and Interface. @param[in] ControllerHandle If the agent that is opening a protocol is a driver that follows the UEFI Driver Model, then this parameter is the controller handle that requires the protocol interface. If the agent does not follow the UEFI Driver Model, then this parameter is optional and may be NULL. @param[in] Attributes The open mode of the protocol interface specified by Handle and Protocol. @retval EFI_SUCCESS An item was added to the open list for the protocol interface, and the protocol interface was returned in Interface. @retval EFI_UNSUPPORTED Handle does not support Protocol. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_ACCESS_DENIED Required attributes can't be supported in current environment. @retval EFI_ALREADY_STARTED Item on the open list already has requierd attributes whose agent handle is the same as AgentHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_OPEN_PROTOCOL)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface OPTIONAL, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle, IN UINT32 Attributes ); /** Closes a protocol on a handle that was opened using OpenProtocol(). @param[in] Handle The handle for the protocol interface that was previously opened with OpenProtocol(), and is now being closed. @param[in] Protocol The published unique identifier of the protocol. @param[in] AgentHandle The handle of the agent that is closing the protocol interface. @param[in] ControllerHandle If the agent that opened a protocol is a driver that follows the UEFI Driver Model, then this parameter is the controller handle that required the protocol interface. @retval EFI_SUCCESS The protocol instance was closed. @retval EFI_INVALID_PARAMETER 1) Handle is NULL. 2) AgentHandle is NULL. 3) ControllerHandle is not NULL and ControllerHandle is not a valid EFI_HANDLE. 4) Protocol is NULL. @retval EFI_NOT_FOUND 1) Handle does not support the protocol specified by Protocol. 2) The protocol interface specified by Handle and Protocol is not currently open by AgentHandle and ControllerHandle. **/ typedef EFI_STATUS (EFIAPI *EFI_CLOSE_PROTOCOL)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle ); /// /// EFI Oprn Protocol Information Entry /// typedef struct { EFI_HANDLE AgentHandle; EFI_HANDLE ControllerHandle; UINT32 Attributes; UINT32 OpenCount; } EFI_OPEN_PROTOCOL_INFORMATION_ENTRY; /** Retrieves the list of agents that currently have a protocol interface opened. @param[in] Handle The handle for the protocol interface that is being queried. @param[in] Protocol The published unique identifier of the protocol. @param[out] EntryBuffer A pointer to a buffer of open protocol information in the form of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. @param[out] EntryCount A pointer to the number of entries in EntryBuffer. @retval EFI_SUCCESS The open protocol information was returned in EntryBuffer, and the number of entries was returned EntryCount. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate EntryBuffer. @retval EFI_NOT_FOUND Handle does not support the protocol specified by Protocol. **/ typedef EFI_STATUS (EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, OUT UINTN *EntryCount ); /** Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool. @param[in] Handle The handle from which to retrieve the list of protocol interface GUIDs. @param[out] ProtocolBuffer A pointer to the list of protocol interface GUID pointers that are installed on Handle. @param[out] ProtocolBufferCount A pointer to the number of GUID pointers present in ProtocolBuffer. @retval EFI_SUCCESS The list of protocol interface GUIDs installed on Handle was returned in ProtocolBuffer. The number of protocol interface GUIDs was returned in ProtocolBufferCount. @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the results. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_PROTOCOLS_PER_HANDLE)( IN EFI_HANDLE Handle, OUT EFI_GUID ***ProtocolBuffer, OUT UINTN *ProtocolBufferCount ); /** Creates an event that is to be signaled whenever an interface is installed for a specified protocol. @param[in] Protocol The numeric ID of the protocol for which the event is to be registered. @param[in] Event Event that is to be signaled whenever a protocol interface is registered for Protocol. @param[out] Registration A pointer to a memory location to receive the registration value. @retval EFI_SUCCESS The notification event has been registered. @retval EFI_OUT_OF_RESOURCES Space for the notification event could not be allocated. @retval EFI_INVALID_PARAMETER Protocol is NULL. @retval EFI_INVALID_PARAMETER Event is NULL. @retval EFI_INVALID_PARAMETER Registration is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)( IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration ); /// /// Enumeration of EFI Locate Search Types /// typedef enum { /// /// Retrieve all the handles in the handle database. /// AllHandles, /// /// Retrieve the next handle fron a RegisterProtocolNotify() event. /// ByRegisterNotify, /// /// Retrieve the set of handles from the handle database that support a /// specified protocol. /// ByProtocol } EFI_LOCATE_SEARCH_TYPE; /** Returns an array of handles that support a specified protocol. @param[in] SearchType Specifies which handle(s) are to be returned. @param[in] Protocol Specifies the protocol to search by. @param[in] SearchKey Specifies the search key. @param[in, out] BufferSize On input, the size in bytes of Buffer. On output, the size in bytes of the array returned in Buffer (if the buffer was large enough) or the size, in bytes, of the buffer needed to obtain the array (if the buffer was not large enough). @param[out] Buffer The buffer in which the array is returned. @retval EFI_SUCCESS The array of handles was returned. @retval EFI_NOT_FOUND No handles match the search. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. @retval EFI_INVALID_PARAMETER SearchType is not a member of EFI_LOCATE_SEARCH_TYPE. @retval EFI_INVALID_PARAMETER SearchType is ByRegisterNotify and SearchKey is NULL. @retval EFI_INVALID_PARAMETER SearchType is ByProtocol and Protocol is NULL. @retval EFI_INVALID_PARAMETER One or more matches are found and BufferSize is NULL. @retval EFI_INVALID_PARAMETER BufferSize is large enough for the result and Buffer is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_LOCATE_HANDLE)( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *BufferSize, OUT EFI_HANDLE *Buffer ); /** Locates the handle to a device on the device path that supports the specified protocol. @param[in] Protocol Specifies the protocol to search for. @param[in, out] DevicePath On input, a pointer to a pointer to the device path. On output, the device path pointer is modified to point to the remaining part of the device path. @param[out] Device A pointer to the returned device handle. @retval EFI_SUCCESS The resulting handle was returned. @retval EFI_NOT_FOUND No handles match the search. @retval EFI_INVALID_PARAMETER Protocol is NULL. @retval EFI_INVALID_PARAMETER DevicePath is NULL. @retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_LOCATE_DEVICE_PATH)( IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT EFI_HANDLE *Device ); /** Adds, updates, or removes a configuration table entry from the EFI System Table. @param[in] Guid A pointer to the GUID for the entry to add, update, or remove. @param[in] Table A pointer to the configuration table for the entry to add, update, or remove. May be NULL. @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed. @retval EFI_NOT_FOUND An attempt was made to delete a nonexistent entry. @retval EFI_INVALID_PARAMETER Guid is NULL. @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation. **/ typedef EFI_STATUS (EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)( IN EFI_GUID *Guid, IN VOID *Table ); /** Returns an array of handles that support the requested protocol in a buffer allocated from pool. @param[in] SearchType Specifies which handle(s) are to be returned. @param[in] Protocol Provides the protocol to search by. This parameter is only valid for a SearchType of ByProtocol. @param[in] SearchKey Supplies the search key depending on the SearchType. @param[out] NoHandles The number of handles returned in Buffer. @param[out] Buffer A pointer to the buffer to return the requested array of handles that support Protocol. @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of handles in Buffer was returned in NoHandles. @retval EFI_NOT_FOUND No handles match the search. @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results. @retval EFI_INVALID_PARAMETER NoHandles is NULL. @retval EFI_INVALID_PARAMETER Buffer is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_LOCATE_HANDLE_BUFFER)( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, OUT UINTN *NoHandles, OUT EFI_HANDLE **Buffer ); /** Returns the first protocol instance that matches the given protocol. @param[in] Protocol Provides the protocol to search for. @param[in] Registration Optional registration key returned from RegisterProtocolNotify(). @param[out] Interface On return, a pointer to the first interface that matches Protocol and Registration. @retval EFI_SUCCESS A protocol instance matching Protocol was found and returned in Interface. @retval EFI_NOT_FOUND No protocol instances were found that match Protocol and Registration. @retval EFI_INVALID_PARAMETER Interface is NULL. Protocol is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_LOCATE_PROTOCOL)( IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface ); /// /// EFI Capsule Block Descriptor /// typedef struct { /// /// Length in bytes of the data pointed to by DataBlock/ContinuationPointer. /// UINT64 Length; union { /// /// Physical address of the data block. This member of the union is /// used if Length is not equal to zero. /// EFI_PHYSICAL_ADDRESS DataBlock; /// /// Physical address of another block of /// EFI_CAPSULE_BLOCK_DESCRIPTOR structures. This /// member of the union is used if Length is equal to zero. If /// ContinuationPointer is zero this entry represents the end of the list. /// EFI_PHYSICAL_ADDRESS ContinuationPointer; } Union; } EFI_CAPSULE_BLOCK_DESCRIPTOR; /// /// EFI Capsule Header. /// typedef struct { /// /// A GUID that defines the contents of a capsule. /// EFI_GUID CapsuleGuid; /// /// The size of the capsule header. This may be larger than the size of /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply /// extended header entries /// UINT32 HeaderSize; /// /// Bit-mapped list describing the capsule attributes. The Flag values /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values /// of 0x10000 - 0xFFFFFFFF are defined by this specification /// UINT32 Flags; /// /// Size in bytes of the capsule. /// UINT32 CapsuleImageSize; } EFI_CAPSULE_HEADER; /// /// The EFI System Table entry must point to an array of capsules /// that contain the same CapsuleGuid value. The array must be /// prefixed by a UINT32 that represents the size of the array of capsules. /// typedef struct { /// /// the size of the array of capsules. /// UINT32 CapsuleArrayNumber; /// /// Point to an array of capsules that contain the same CapsuleGuid value. /// VOID *CapsulePtr[1]; } EFI_CAPSULE_TABLE; #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 /** Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended consumption, the firmware may process the capsule immediately. If the payload should persist across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must be passed into ResetSystem() and will cause the capsule to be processed by the firmware as part of the reset process. @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules being passed into update capsule. @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in CaspuleHeaderArray. @param[in] ScatterGatherList Physical pointer to a set of EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the location in physical memory of a set of capsules. @retval EFI_SUCCESS Valid capsule was passed. If CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the capsule has been successfully processed by the firmware. @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were set in the capsule header. @retval EFI_INVALID_PARAMETER CapsuleCount is 0. @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule is compatible with this platform but is not capable of being submitted or processed in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. **/ typedef EFI_STATUS (EFIAPI *EFI_UPDATE_CAPSULE)( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ); /** Returns if the capsule can be supported via UpdateCapsule(). @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules being passed into update capsule. @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in CaspuleHeaderArray. @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can support as an argument to UpdateCapsule() via CapsuleHeaderArray and ScatterGatherList. @param[out] ResetType Returns the type of reset required for the capsule update. @retval EFI_SUCCESS Valid answer returned. @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and MaximumCapsuleSize and ResetType are undefined. @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule is compatible with this platform but is not capable of being submitted or processed in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. **/ typedef EFI_STATUS (EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, OUT UINT64 *MaximumCapsuleSize, OUT EFI_RESET_TYPE *ResetType ); /** Returns information about the EFI variables. @param[in] Attributes Attributes bitmask to specify the type of variables on which to return information. @param[out] MaximumVariableStorageSize On output the maximum size of the storage space available for the EFI variables associated with the attributes specified. @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space available for the EFI variables associated with the attributes specified. @param[out] MaximumVariableSize Returns the maximum size of the individual EFI variables associated with the attributes specified. @retval EFI_SUCCESS Valid answer returned. @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the MaximumVariableStorageSize, RemainingVariableStorageSize, MaximumVariableSize are undefined. **/ typedef EFI_STATUS (EFIAPI *EFI_QUERY_VARIABLE_INFO)( IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize, OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize ); // // Firmware should stop at a firmware user interface on next boot // #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001 #define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION 0x0000000000000002 #define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 0x0000000000000004 #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED 0x0000000000000008 #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED 0x0000000000000010 #define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY 0x0000000000000040 #define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH 0x0000000000000080 // // EFI Runtime Services Table // #define EFI_SYSTEM_TABLE_SIGNATURE SIGNATURE_64 ('I','B','I',' ','S','Y','S','T') #define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80)) #define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70)) #define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60)) #define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50)) #define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40)) #define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31)) #define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) #define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20)) #define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10)) #define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00)) #define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10)) #define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02)) #define EFI_SYSTEM_TABLE_REVISION EFI_2_70_SYSTEM_TABLE_REVISION #define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION #define EFI_RUNTIME_SERVICES_SIGNATURE SIGNATURE_64 ('R','U','N','T','S','E','R','V') #define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION /// /// EFI Runtime Services Table. /// typedef struct { /// /// The table header for the EFI Runtime Services Table. /// EFI_TABLE_HEADER Hdr; // // Time Services // EFI_GET_TIME GetTime; EFI_SET_TIME SetTime; EFI_GET_WAKEUP_TIME GetWakeupTime; EFI_SET_WAKEUP_TIME SetWakeupTime; // // Virtual Memory Services // EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; EFI_CONVERT_POINTER ConvertPointer; // // Variable Services // EFI_GET_VARIABLE GetVariable; EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; EFI_SET_VARIABLE SetVariable; // // Miscellaneous Services // EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; EFI_RESET_SYSTEM ResetSystem; // // UEFI 2.0 Capsule Services // EFI_UPDATE_CAPSULE UpdateCapsule; EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities; // // Miscellaneous UEFI 2.0 Service // EFI_QUERY_VARIABLE_INFO QueryVariableInfo; } EFI_RUNTIME_SERVICES; #define EFI_BOOT_SERVICES_SIGNATURE SIGNATURE_64 ('B','O','O','T','S','E','R','V') #define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION /// /// EFI Boot Services Table. /// typedef struct { /// /// The table header for the EFI Boot Services Table. /// EFI_TABLE_HEADER Hdr; // // Task Priority Services // EFI_RAISE_TPL RaiseTPL; EFI_RESTORE_TPL RestoreTPL; // // Memory Services // EFI_ALLOCATE_PAGES AllocatePages; EFI_FREE_PAGES FreePages; EFI_GET_MEMORY_MAP GetMemoryMap; EFI_ALLOCATE_POOL AllocatePool; EFI_FREE_POOL FreePool; // // Event & Timer Services // EFI_CREATE_EVENT CreateEvent; EFI_SET_TIMER SetTimer; EFI_WAIT_FOR_EVENT WaitForEvent; EFI_SIGNAL_EVENT SignalEvent; EFI_CLOSE_EVENT CloseEvent; EFI_CHECK_EVENT CheckEvent; // // Protocol Handler Services // EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; EFI_HANDLE_PROTOCOL HandleProtocol; VOID *Reserved; EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; EFI_LOCATE_HANDLE LocateHandle; EFI_LOCATE_DEVICE_PATH LocateDevicePath; EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; // // Image Services // EFI_IMAGE_LOAD LoadImage; EFI_IMAGE_START StartImage; EFI_EXIT Exit; EFI_IMAGE_UNLOAD UnloadImage; EFI_EXIT_BOOT_SERVICES ExitBootServices; // // Miscellaneous Services // EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; EFI_STALL Stall; EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; // // DriverSupport Services // EFI_CONNECT_CONTROLLER ConnectController; EFI_DISCONNECT_CONTROLLER DisconnectController; // // Open and Close Protocol Services // EFI_OPEN_PROTOCOL OpenProtocol; EFI_CLOSE_PROTOCOL CloseProtocol; EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; // // Library Services // EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; EFI_LOCATE_PROTOCOL LocateProtocol; EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces; EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces; // // 32-bit CRC Services // EFI_CALCULATE_CRC32 CalculateCrc32; // // Miscellaneous Services // EFI_COPY_MEM CopyMem; EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; } EFI_BOOT_SERVICES; /// /// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the /// EFI System Table. /// typedef struct { /// /// The 128-bit GUID value that uniquely identifies the system configuration table. /// EFI_GUID VendorGuid; /// /// A pointer to the table associated with VendorGuid. /// VOID *VendorTable; } EFI_CONFIGURATION_TABLE; /// /// EFI System Table /// typedef struct { /// /// The table header for the EFI System Table. /// EFI_TABLE_HEADER Hdr; /// /// A pointer to a null terminated string that identifies the vendor /// that produces the system firmware for the platform. /// CHAR16 *FirmwareVendor; /// /// A firmware vendor specific value that identifies the revision /// of the system firmware for the platform. /// UINT32 FirmwareRevision; /// /// The handle for the active console input device. This handle must support /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. /// EFI_HANDLE ConsoleInHandle; /// /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is /// associated with ConsoleInHandle. /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; /// /// The handle for the active console output device. /// EFI_HANDLE ConsoleOutHandle; /// /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface /// that is associated with ConsoleOutHandle. /// EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; /// /// The handle for the active standard error console device. /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. /// EFI_HANDLE StandardErrorHandle; /// /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface /// that is associated with StandardErrorHandle. /// EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; /// /// A pointer to the EFI Runtime Services Table. /// EFI_RUNTIME_SERVICES *RuntimeServices; /// /// A pointer to the EFI Boot Services Table. /// EFI_BOOT_SERVICES *BootServices; /// /// The number of system configuration tables in the buffer ConfigurationTable. /// UINTN NumberOfTableEntries; /// /// A pointer to the system configuration tables. /// The number of entries in the table is NumberOfTableEntries. /// EFI_CONFIGURATION_TABLE *ConfigurationTable; } EFI_SYSTEM_TABLE; /** This is the declaration of an EFI image entry point. This entry point is the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including both device drivers and bus drivers. @param[in] ImageHandle The firmware allocated handle for the UEFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ typedef EFI_STATUS (EFIAPI *EFI_IMAGE_ENTRY_POINT)( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ); // // EFI Load Option. This data structure describes format of UEFI boot option variables. // // NOTE: EFI Load Option is a byte packed buffer of variable length fields. // The first two fields have fixed length. They are declared as members of the // EFI_LOAD_OPTION structure. All the other fields are variable length fields. // They are listed in the comment block below for reference purposes. // #pragma pack(1) typedef struct _EFI_LOAD_OPTION { /// /// The attributes for this load option entry. All unused bits must be zero /// and are reserved by the UEFI specification for future growth. /// UINT32 Attributes; /// /// Length in bytes of the FilePathList. OptionalData starts at offset /// sizeof(UINT32) + sizeof(UINT16) + StrSize(Description) + FilePathListLength /// of the EFI_LOAD_OPTION descriptor. /// UINT16 FilePathListLength; /// /// The user readable description for the load option. /// This field ends with a Null character. /// // CHAR16 Description[]; /// /// A packed array of UEFI device paths. The first element of the array is a /// device path that describes the device and location of the Image for this /// load option. The FilePathList[0] is specific to the device type. Other /// device paths may optionally exist in the FilePathList, but their usage is /// OSV specific. Each element in the array is variable length, and ends at /// the device path end structure. Because the size of Description is /// arbitrary, this data structure is not guaranteed to be aligned on a /// natural boundary. This data structure may have to be copied to an aligned /// natural boundary before it is used. /// // EFI_DEVICE_PATH_PROTOCOL FilePathList[]; /// /// The remaining bytes in the load option descriptor are a binary data buffer /// that is passed to the loaded image. If the field is zero bytes long, a /// NULL pointer is passed to the loaded image. The number of bytes in /// OptionalData can be computed by subtracting the starting offset of /// OptionalData from total size in bytes of the EFI_LOAD_OPTION. /// // UINT8 OptionalData[]; } EFI_LOAD_OPTION; #pragma pack() // // EFI Load Options Attributes // #define LOAD_OPTION_ACTIVE 0x00000001 #define LOAD_OPTION_FORCE_RECONNECT 0x00000002 #define LOAD_OPTION_HIDDEN 0x00000008 #define LOAD_OPTION_CATEGORY 0x00001F00 #define LOAD_OPTION_CATEGORY_BOOT 0x00000000 #define LOAD_OPTION_CATEGORY_APP 0x00000100 #define EFI_BOOT_OPTION_SUPPORT_KEY 0x00000001 #define EFI_BOOT_OPTION_SUPPORT_APP 0x00000002 #define EFI_BOOT_OPTION_SUPPORT_SYSPREP 0x00000010 #define EFI_BOOT_OPTION_SUPPORT_COUNT 0x00000300 /// /// EFI Boot Key Data /// typedef union { struct { /// /// Indicates the revision of the EFI_KEY_OPTION structure. This revision level should be 0. /// UINT32 Revision : 8; /// /// Either the left or right Shift keys must be pressed (1) or must not be pressed (0). /// UINT32 ShiftPressed : 1; /// /// Either the left or right Control keys must be pressed (1) or must not be pressed (0). /// UINT32 ControlPressed : 1; /// /// Either the left or right Alt keys must be pressed (1) or must not be pressed (0). /// UINT32 AltPressed : 1; /// /// Either the left or right Logo keys must be pressed (1) or must not be pressed (0). /// UINT32 LogoPressed : 1; /// /// The Menu key must be pressed (1) or must not be pressed (0). /// UINT32 MenuPressed : 1; /// /// The SysReq key must be pressed (1) or must not be pressed (0). /// UINT32 SysReqPressed : 1; UINT32 Reserved : 16; /// /// Specifies the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3. If /// zero, then only the shift state is considered. If more than one, then the boot option will /// only be launched if all of the specified keys are pressed with the same shift state. /// UINT32 InputKeyCount : 2; } Options; UINT32 PackedValue; } EFI_BOOT_KEY_DATA; /// /// EFI Key Option. /// #pragma pack(1) typedef struct { /// /// Specifies options about how the key will be processed. /// EFI_BOOT_KEY_DATA KeyData; /// /// The CRC-32 which should match the CRC-32 of the entire EFI_LOAD_OPTION to /// which BootOption refers. If the CRC-32s do not match this value, then this key /// option is ignored. /// UINT32 BootOptionCrc; /// /// The Boot#### option which will be invoked if this key is pressed and the boot option /// is active (LOAD_OPTION_ACTIVE is set). /// UINT16 BootOption; /// /// The key codes to compare against those returned by the /// EFI_SIMPLE_TEXT_INPUT and EFI_SIMPLE_TEXT_INPUT_EX protocols. /// The number of key codes (0-3) is specified by the EFI_KEY_CODE_COUNT field in KeyOptions. /// // EFI_INPUT_KEY Keys[]; } EFI_KEY_OPTION; #pragma pack() // // EFI File location to boot from on removable media devices // #define EFI_REMOVABLE_MEDIA_FILE_NAME_IA32 L"\\EFI\\BOOT\\BOOTIA32.EFI" #define EFI_REMOVABLE_MEDIA_FILE_NAME_IA64 L"\\EFI\\BOOT\\BOOTIA64.EFI" #define EFI_REMOVABLE_MEDIA_FILE_NAME_X64 L"\\EFI\\BOOT\\BOOTX64.EFI" #define EFI_REMOVABLE_MEDIA_FILE_NAME_ARM L"\\EFI\\BOOT\\BOOTARM.EFI" #define EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64 L"\\EFI\\BOOT\\BOOTAA64.EFI" #define EFI_REMOVABLE_MEDIA_FILE_NAME_RISCV64 L"\\EFI\\BOOT\\BOOTRISCV64.EFI" #if !defined (EFI_REMOVABLE_MEDIA_FILE_NAME) #if defined (MDE_CPU_IA32) #define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_IA32 #elif defined (MDE_CPU_X64) #define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_X64 #elif defined (MDE_CPU_EBC) #elif defined (MDE_CPU_ARM) #define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_ARM #elif defined (MDE_CPU_AARCH64) #define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64 #elif defined (MDE_CPU_RISCV64) #define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_RISCV64 #else #error Unknown Processor Type #endif #endif // // The directory within the active EFI System Partition defined for delivery of capsule to firmware // #define EFI_CAPSULE_FILE_DIRECTORY L"\\EFI\\UpdateCapsule\\" #include #include #include #endif /** @file Processor or Compiler specific defines and types x64 (Intel 64, AMD64). Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PROCESSOR_BIND_H__ #define __PROCESSOR_BIND_H__ #define EFIAPI __attribute__((ms_abi)) /// /// Define the processor type so other code can make processor based choices /// #define MDE_CPU_X64 // // Make sure we are using the correct packing rules per EFI specification // #if !defined (__GNUC__) #pragma pack() #endif #if defined (__GNUC__) && defined (__pic__) && !defined (USING_LTO) && !defined (__APPLE__) // // Mark all symbol declarations and references as hidden, meaning they will // not be subject to symbol preemption. This allows the compiler to refer to // symbols directly using relative references rather than via the GOT, which // contains absolute symbol addresses that are subject to runtime relocation. // // The LTO linker will not emit GOT based relocations when all symbol // references can be resolved locally, and so there is no need to set the // pragma in that case (and doing so will cause other issues). // #pragma GCC visibility push (hidden) #endif #if defined (__INTEL_COMPILER) // // Disable ICC's remark #869: "Parameter" was never referenced warning. // This is legal ANSI C code so we disable the remark that is turned on with -Wall // #pragma warning ( disable : 869 ) // // Disable ICC's remark #1418: external function definition with no prior declaration. // This is legal ANSI C code so we disable the remark that is turned on with /W4 // #pragma warning ( disable : 1418 ) // // Disable ICC's remark #1419: external declaration in primary source file // This is legal ANSI C code so we disable the remark that is turned on with /W4 // #pragma warning ( disable : 1419 ) // // Disable ICC's remark #593: "Variable" was set but never used. // This is legal ANSI C code so we disable the remark that is turned on with /W4 // #pragma warning ( disable : 593 ) #endif #if defined (_MSC_EXTENSIONS) // // Disable warning that make it impossible to compile at /W4 // This only works for Microsoft* tools // // // Disabling bitfield type checking warnings. // #pragma warning ( disable : 4214 ) // // Disabling the unreferenced formal parameter warnings. // #pragma warning ( disable : 4100 ) // // Disable slightly different base types warning as CHAR8 * can not be set // to a constant string. // #pragma warning ( disable : 4057 ) // // ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning // #pragma warning ( disable : 4127 ) // // This warning is caused by functions defined but not used. For precompiled header only. // #pragma warning ( disable : 4505 ) // // This warning is caused by empty (after preprocessing) source file. For precompiled header only. // #pragma warning ( disable : 4206 ) #if defined (_MSC_VER) && _MSC_VER >= 1800 // // Disable these warnings for VS2013. // // // This warning is for potentially uninitialized local variable, and it may cause false // positive issues in VS2013 and VS2015 build // #pragma warning ( disable : 4701 ) // // This warning is for potentially uninitialized local pointer variable, and it may cause // false positive issues in VS2013 and VS2015 build // #pragma warning ( disable : 4703 ) #endif #endif #if defined (_MSC_EXTENSIONS) // // use Microsoft C compiler dependent integer width types // /// /// 8-byte unsigned value /// typedef unsigned __int64 UINT64; /// /// 8-byte signed value /// typedef __int64 INT64; /// /// 4-byte unsigned value /// typedef unsigned __int32 UINT32; /// /// 4-byte signed value /// typedef __int32 INT32; /// /// 2-byte unsigned value /// typedef unsigned short UINT16; /// /// 2-byte Character. Unless otherwise specified all strings are stored in the /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards. /// typedef unsigned short CHAR16; /// /// 2-byte signed value /// typedef short INT16; /// /// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other /// values are undefined. /// typedef unsigned char BOOLEAN; /// /// 1-byte unsigned value /// typedef unsigned char UINT8; /// /// 1-byte Character /// typedef char CHAR8; /// /// 1-byte signed value /// typedef signed char INT8; #else /// /// 8-byte unsigned value /// #ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ #define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ typedef unsigned long UINT64; /// /// 8-byte signed value /// typedef long long INT64; #endif /// /// 4-byte unsigned value /// typedef unsigned int UINT32; /// /// 4-byte signed value /// typedef int INT32; /// /// 2-byte unsigned value /// typedef unsigned short UINT16; /// /// 2-byte Character. Unless otherwise specified all strings are stored in the /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards. /// typedef unsigned short CHAR16; /// /// 2-byte signed value /// typedef short INT16; /// /// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other /// values are undefined. /// typedef unsigned char BOOLEAN; /// /// 1-byte unsigned value /// typedef unsigned char UINT8; /// /// 1-byte Character /// typedef char CHAR8; /// /// 1-byte signed value /// typedef signed char INT8; #endif /// /// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions, /// 8 bytes on supported 64-bit processor instructions) /// typedef UINT64 UINTN; /// /// Signed value of native width. (4 bytes on supported 32-bit processor instructions, /// 8 bytes on supported 64-bit processor instructions) /// typedef INT64 INTN; // // Processor specific defines // /// /// A value of native width with the highest bit set. /// #define MAX_BIT 0x8000000000000000ULL /// /// A value of native width with the two highest bits set. /// #define MAX_2_BITS 0xC000000000000000ULL /// /// Maximum legal x64 address /// #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL /// /// Maximum usable address at boot time /// #define MAX_ALLOC_ADDRESS MAX_ADDRESS /// /// Maximum legal x64 INTN and UINTN values. /// #define MAX_INTN ((INTN)0x7FFFFFFFFFFFFFFFULL) #define MAX_UINTN ((UINTN)0xFFFFFFFFFFFFFFFFULL) /// /// Minimum legal x64 INTN value. /// #define MIN_INTN (((INTN)-9223372036854775807LL) - 1) /// /// The stack alignment required for x64 /// #define CPU_STACK_ALIGNMENT 16 /// /// Page allocation granularity for x64 /// #define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000) #define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x1000) // // Modifier to ensure that all protocol member functions and EFI intrinsics // use the correct C calling convention. All protocol member functions and // EFI intrinsics are required to modify their member functions with EFIAPI. // #ifdef EFIAPI /// /// If EFIAPI is already defined, then we use that definition. /// #elif defined (_MSC_EXTENSIONS) /// /// Microsoft* compiler specific method for EFIAPI calling convention. /// #define EFIAPI __cdecl #elif defined (__GNUC__) /// /// Define the standard calling convention regardless of optimization level. /// The GCC support assumes a GCC compiler that supports the EFI ABI. The EFI /// ABI is much closer to the x64 Microsoft* ABI than standard x64 (x86-64) /// GCC ABI. Thus a standard x64 (x86-64) GCC compiler can not be used for /// x64. Warning the assembly code in the MDE x64 does not follow the correct /// ABI for the standard x64 (x86-64) GCC. /// #define EFIAPI #else /// /// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI /// is the standard. /// #define EFIAPI #endif #if defined (__GNUC__) || defined (__clang__) /// /// For GNU assembly code, .global or .globl can declare global symbols. /// Define this macro to unify the usage. /// #define ASM_GLOBAL .globl #endif /** Return the pointer to the first instruction of a function given a function pointer. On x64 CPU architectures, these two pointer values are the same, so the implementation of this macro is very simple. @param FunctionPointer A pointer to a function. @return The pointer to the first instruction of a function given a function pointer. **/ #define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer) #ifndef __USER_LABEL_PREFIX__ #define __USER_LABEL_PREFIX__ #endif #endif /** @file Processor or Compiler specific defines and types for AArch64. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __PROCESSOR_BIND_H__ #define __PROCESSOR_BIND_H__ /// /// Define the processor type so other code can make processor based choices /// #define MDE_CPU_AARCH64 // // Make sure we are using the correct packing rules per EFI specification // #if !defined (__GNUC__) && !defined (__ASSEMBLER__) #pragma pack() #endif #if defined (_MSC_EXTENSIONS) // // Disable some level 4 compilation warnings (same as IA32 and X64) // // // Disabling bitfield type checking warnings. // #pragma warning ( disable : 4214 ) // // Disabling the unreferenced formal parameter warnings. // #pragma warning ( disable : 4100 ) // // Disable slightly different base types warning as CHAR8 * can not be set // to a constant string. // #pragma warning ( disable : 4057 ) // // ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning // #pragma warning ( disable : 4127 ) // // This warning is caused by functions defined but not used. For precompiled header only. // #pragma warning ( disable : 4505 ) // // This warning is caused by empty (after preprocessing) source file. For precompiled header only. // #pragma warning ( disable : 4206 ) // // Disable 'potentially uninitialized local variable X used' warnings // #pragma warning ( disable : 4701 ) // // Disable 'potentially uninitialized local pointer variable X used' warnings // #pragma warning ( disable : 4703 ) // // use Microsoft* C compiler dependent integer width types // typedef unsigned __int64 UINT64; typedef __int64 INT64; typedef unsigned __int32 UINT32; typedef __int32 INT32; typedef unsigned short UINT16; typedef unsigned short CHAR16; typedef short INT16; typedef unsigned char BOOLEAN; typedef unsigned char UINT8; typedef char CHAR8; typedef signed char INT8; #else // // Assume standard AARCH64 alignment. // typedef unsigned long long UINT64; typedef long long INT64; typedef unsigned int UINT32; typedef int INT32; typedef unsigned short UINT16; typedef unsigned short CHAR16; typedef short INT16; typedef unsigned char BOOLEAN; typedef unsigned char UINT8; typedef char CHAR8; typedef signed char INT8; #endif /// /// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions, /// 8 bytes on supported 64-bit processor instructions) /// typedef UINT64 UINTN; /// /// Signed value of native width. (4 bytes on supported 32-bit processor instructions, /// 8 bytes on supported 64-bit processor instructions) /// typedef INT64 INTN; // // Processor specific defines // /// /// A value of native width with the highest bit set. /// #define MAX_BIT 0x8000000000000000ULL /// /// A value of native width with the two highest bits set. /// #define MAX_2_BITS 0xC000000000000000ULL /// /// Maximum legal AARCH64 address /// #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL /// /// Maximum usable address at boot time (48 bits using 4 KB pages) /// #define MAX_ALLOC_ADDRESS 0xFFFFFFFFFFFFULL /// /// Maximum legal AArch64 INTN and UINTN values. /// #define MAX_INTN ((INTN)0x7FFFFFFFFFFFFFFFULL) #define MAX_UINTN ((UINTN)0xFFFFFFFFFFFFFFFFULL) /// /// Minimum legal AArch64 INTN value. /// #define MIN_INTN (((INTN)-9223372036854775807LL) - 1) /// /// The stack alignment required for AARCH64 /// #define CPU_STACK_ALIGNMENT 16 /// /// Page allocation granularity for AARCH64 /// #define DEFAULT_PAGE_ALLOCATION_GRANULARITY (0x1000) #define RUNTIME_PAGE_ALLOCATION_GRANULARITY (0x10000) // // Modifier to ensure that all protocol member functions and EFI intrinsics // use the correct C calling convention. All protocol member functions and // EFI intrinsics are required to modify their member functions with EFIAPI. // #define EFIAPI // When compiling with Clang, we still use GNU as for the assembler, so we still // need to define the GCC_ASM* macros. #if defined (__GNUC__) || defined (__clang__) /// /// For GNU assembly code, .global or .globl can declare global symbols. /// Define this macro to unify the usage. /// #define ASM_GLOBAL .globl #define GCC_ASM_EXPORT(func__) \ .global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\ .type ASM_PFX(func__), %function #define GCC_ASM_IMPORT(func__) \ .extern _CONCATENATE (__USER_LABEL_PREFIX__, func__) #endif /** Return the pointer to the first instruction of a function given a function pointer. On ARM CPU architectures, these two pointer values are the same, so the implementation of this macro is very simple. @param FunctionPointer A pointer to a function. @return The pointer to the first instruction of a function given a function pointer. **/ #define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer) #ifndef __USER_LABEL_PREFIX__ #define __USER_LABEL_PREFIX__ #endif #endif /* * * Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved * This software and associated documentation (if any) is furnished * under a license and may only be used or copied in accordance * with the terms of the license. Except as permitted by such * license, no part of this software or documentation may be * reproduced, stored in a retrieval system, or transmitted in any * form or by any means without the express written consent of * Intel Corporation. * * Module Name: * * efi.h * * Abstract: * Public EFI header files * * Revision History */ // // Build flags on input // EFI32 // EFI_DEBUG - Enable debugging code // EFI_NT_EMULATOR - Building for running under NT // #ifndef _EFI_INCLUDE_ #define _EFI_INCLUDE_ #include /* Need __dead2. */ #include #define NextMemoryDescriptor(Ptr, Size) \ ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) /* See also ENCODE_ERROR(). */ #define DECODE_ERROR(StatusCode) \ (unsigned long)(StatusCode & ~MAX_BIT) #include /* * Global variables */ extern bool has_boot_services; /* * illumos UUID */ #define ILLUMOS_BOOT_VAR_GUID \ { 0x8B54B311, 0x7163, 0x40d3, \ {0xA6, 0x7B, 0xE7, 0xB2, 0x95, 0x1B, 0x3D, 0x56} \ } extern EFI_GUID gillumosBootVarGuid; #define LZMA_COMPRESS_GUID \ { 0xee4e5898, 0x3914, 0x4259, \ {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf} \ } #endif /* _EFI_INCLUDE_ */ /* * Copyright (c) 2017 Eric McCorkle * All rights reserved. * * 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. * * 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 _EFI_DRIVER_UTILS_H_ #define _EFI_DRIVER_UTILS_H_ #include #include extern EFI_STATUS install_driver(EFI_DRIVER_BINDING_PROTOCOL *driver); extern EFI_STATUS connect_controllers(EFI_GUID *filter); #endif /* _EFI_DRIVER_UTILS_H_ */ /* * Copyright (c) 2016 Eric McCorkle * All rights reserved. * * 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. * * 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 _EFI_DRIVERS_H_ #define _EFI_DRIVERS_H_ #include typedef struct efi_driver_t { const char *name; void (*init)(void); } efi_driver_t; extern struct devsw efipart_dev; extern int efipart_getdesc(struct devdesc *dev, char **out); /* EFI drivers. */ extern const efi_driver_t fs_driver; #endif /* * Copyright (c) 2010 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include #ifndef _BOOT_EFI_EFICHAR_H_ #define _BOOT_EFI_EFICHAR_H_ int ucs2_to_utf8(const CHAR16 *, char **); int utf8_to_ucs2(const char *, CHAR16 **, size_t *); int ucs2len(const CHAR16 *); #endif /* _BOOT_EFI_EFICHAR_H_ */ /*- * Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /* * Original Module Name: ConsoleControl.h * Abstract: Abstraction of a Text mode or GOP/UGA screen */ /* $FreeBSD$ */ #ifndef _EFI_CONS_CTL_H #define _EFI_CONS_CTL_H #define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} } typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL; typedef enum { EfiConsoleControlScreenText, EfiConsoleControlScreenGraphics, EfiConsoleControlScreenMaxValue } EFI_CONSOLE_CONTROL_SCREEN_MODE; typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) ( IN EFI_CONSOLE_CONTROL_PROTOCOL *This, OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, OUT BOOLEAN *GopUgaExists, OPTIONAL OUT BOOLEAN *StdInLocked OPTIONAL ) /*++ Routine Description: Return the current video mode information. Also returns info about existence of Graphics Output devices or UGA Draw devices in system, and if the Std In device is locked. All the arguments are optional and only returned if a non NULL pointer is passed in. Arguments: This - Protocol instance pointer. Mode - Are we in text of grahics mode. GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device StdInLocked - TRUE if StdIn device is keyboard locked Returns: EFI_SUCCESS - Mode information returned. --*/ ; typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) ( IN EFI_CONSOLE_CONTROL_PROTOCOL *This, IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode ) /*++ Routine Description: Set the current mode to either text or graphics. Graphics is for Quiet Boot. Arguments: This - Protocol instance pointer. Mode - Mode to set the Returns: EFI_SUCCESS - Mode information returned. --*/ ; typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) ( IN EFI_CONSOLE_CONTROL_PROTOCOL *This, IN CHAR16 *Password ) /*++ Routine Description: Lock Std In devices until Password is typed. Arguments: This - Protocol instance pointer. Password - Password needed to unlock screen. NULL means unlock keyboard Returns: EFI_SUCCESS - Mode information returned. EFI_DEVICE_ERROR - Std In not locked --*/ ; struct _EFI_CONSOLE_CONTROL_PROTOCOL { EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode; EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode; EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; }; extern EFI_GUID gEfiConsoleControlProtocolGuid; #endif /* * Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved * This software and associated documentation (if any) is furnished * under a license and may only be used or copied in accordance * with the terms of the license. Except as permitted by such * license, no part of this software or documentation may be * reproduced, stored in a retrieval system, or transmitted in any * form or by any means without the express written consent of * Intel Corporation. * * Module Name: * * devpath.h * * Abstract: * * Defines for parsing the EFI Device Path structures * * Revision History */ #ifndef _DEVPATH_H #define _DEVPATH_H #include #define EFI_DP_TYPE_MASK 0x7F #define EFI_DP_TYPE_UNPACKED 0x80 #define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH)) #define DP_IS_END_TYPE(a) #define DP_IS_END_SUBTYPE(a) \ (((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE) #define DevicePathType(a) (((a)->Type) & EFI_DP_TYPE_MASK) #define DevicePathSubType(a) ((a)->SubType) #define DevicePathNodeLength(a) \ ((size_t)(((a)->Length[0]) |((a)->Length[1] << 8))) #define NextDevicePathNode(a) \ ((EFI_DEVICE_PATH *)(((UINT8 *)(a)) + DevicePathNodeLength(a))) #define IsDevicePathType(a, t) (DevicePathType(a) == t) #define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE) #define IsDevicePathEndSubType(a) \ ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE) #define IsDevicePathEnd(a) \ (IsDevicePathEndType(a) && IsDevicePathEndSubType(a)) #define IsDevicePathUnpacked(a) ((a)->Type & EFI_DP_TYPE_UNPACKED) #define SetDevicePathNodeLength(a, l) { \ (a)->Length[0] = (UINT8)(l); \ (a)->Length[1] = (UINT8)((l) >> 8); \ } #define SetDevicePathEndNode(a) { \ (a)->Type = END_DEVICE_PATH_TYPE; \ (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ (a)->Length[0] = sizeof (EFI_DEVICE_PATH); \ (a)->Length[1] = 0; \ } #endif /* _DEVPATH_H */ /* $FreeBSD$ */ #ifndef _EFI_FPSWA_H #define _EFI_FPSWA_H /* * EFI FP SWA Driver (Floating Point Software Assist) */ #define EFI_INTEL_FPSWA \ { 0xc41b6531, 0x97b9, 0x11d3, {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } INTERFACE_DECL(_FPSWA_INTERFACE); typedef struct _FPSWA_RET { UINT64 status; UINT64 err1; UINT64 err2; UINT64 err3; } FPSWA_RET; typedef FPSWA_RET (EFIAPI *EFI_FPSWA) ( IN UINTN TrapType, IN OUT VOID *Bundle, IN OUT UINT64 *pipsr, IN OUT UINT64 *pfsr, IN OUT UINT64 *pisr, IN OUT UINT64 *ppreds, IN OUT UINT64 *pifs, IN OUT VOID *fp_state ); typedef struct _FPSWA_INTERFACE { UINT32 Revision; UINT32 Reserved; EFI_FPSWA Fpswa; } FPSWA_INTERFACE; #endif /* * Copyright (c) 2000 Doug Rabson * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * 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 _LOADER_EFILIB_H #define _LOADER_EFILIB_H #include #include #include #include #include #include extern EFI_HANDLE IH; extern EFI_SYSTEM_TABLE *ST; extern EFI_BOOT_SERVICES *BS; extern EFI_RUNTIME_SERVICES *RS; extern struct devsw efipart_fddev; extern struct devsw efipart_cddev; extern struct devsw efipart_hddev; extern struct devsw efinet_dev; extern struct netif_driver efinetif; /* * Serial port descriptor. */ typedef STAILQ_HEAD(serial_list, serial) serial_list_t; struct serial { STAILQ_ENTRY(serial) next; uint64_t baudrate; uint32_t timeout; uint32_t receivefifodepth; uint32_t databits; EFI_PARITY_TYPE parity; EFI_STOP_BITS_TYPE stopbits; bool ignore_cd; bool rtsdtr_off; bool is_efi_console; /* EFI Console device */ EFI_HANDLE currdev; /* current serial device */ EFI_HANDLE iodev; /* handle to IO layer */ EFI_GUID *guid; /* Driver protocol guid */ union { EFI_SERIAL_IO_PROTOCOL *sio; EFI_ISA_IO_PROTOCOL *isa; } io; uint32_t ioaddr; char name; /* 'a'-'d' or '0'-'9' */ }; extern serial_list_t serials; /* In efiserialio.c */ /* EFI block device data, included here to help efi_zfs_probe() */ typedef STAILQ_HEAD(pdinfo_list, pdinfo) pdinfo_list_t; typedef struct pdinfo { STAILQ_ENTRY(pdinfo) pd_link; /* link in device list */ pdinfo_list_t pd_part; /* list of partitions */ EFI_HANDLE pd_handle; EFI_HANDLE pd_alias; EFI_DEVICE_PATH *pd_devpath; EFI_BLOCK_IO *pd_blkio; uint32_t pd_unit; /* unit number */ uint32_t pd_open; /* reference counter */ void *pd_bcache; /* buffer cache data */ struct pdinfo *pd_parent; /* Linked items (eg partitions) */ struct devsw *pd_devsw; /* Back pointer to devsw */ } pdinfo_t; pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h); void *efi_get_table(EFI_GUID *tbl); EFI_STATUS OpenProtocolByHandle(EFI_HANDLE, EFI_GUID *, void **); EFI_STATUS efi_get_protocol_handles(EFI_GUID *, uint_t *, EFI_HANDLE **); int efi_getdev(void **, const char *, const char **); char *efi_fmtdev(void *); int efi_setcurrdev(struct env_var *, int, const void *); int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); EFI_HANDLE efi_find_handle(struct devsw *, int); int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *); int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t); EFI_DEVICE_PATH *efi_lookup_image_devpath(EFI_HANDLE); EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE); void efi_close_devpath(EFI_HANDLE); EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); EFI_DEVICE_PATH *efi_devpath_next_instance(EFI_DEVICE_PATH *); bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); void efi_free_devpath_name(CHAR16 *); int efi_status_to_errno(EFI_STATUS); EFI_STATUS errno_to_efi_status(int errno); void efi_time_init(void); void efi_time_fini(void); void efi_serial_ini(void); void efi_isa_ini(void); EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); EFI_STATUS main(int argc, CHAR16 *argv[]); void efi_exit(EFI_STATUS status) __dead2; void delay(int usecs); /* EFI environment initialization. */ void efi_init_environment(void); /* EFI Memory type strings. */ const char *efi_memory_type(EFI_MEMORY_TYPE); /* CHAR16 utility functions. */ int wcscmp(CHAR16 *, CHAR16 *); void cpy8to16(const char *, CHAR16 *, size_t); void cpy16to8(const CHAR16 *, char *, size_t); /* * Routines for interacting with EFI's env vars in a more unix-like * way than the standard APIs. In addition, convenience routines for * the loader setting / getting illumos specific variables. */ EFI_STATUS efi_illumos_getenv(const char *v, void *data, size_t *len); EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len); EFI_STATUS efi_setenv(EFI_GUID *g, uint32_t, const char *, void *, size_t); EFI_STATUS efi_global_getenv(const char *v, void *data, size_t *len); EFI_STATUS efi_global_setenv(const char *v, void *data, size_t len); EFI_STATUS efi_setenv_illumos_wcs(const char *varname, CHAR16 *valstr); /* guids and names */ bool efi_guid_to_str(const EFI_GUID *, char **); bool efi_str_to_guid(const char *, EFI_GUID *); bool efi_name_to_guid(const char *, EFI_GUID *); bool efi_guid_to_name(EFI_GUID *, char **); /* efipart.c */ int efipart_inithandles(void); #endif /* _LOADER_EFILIB_H */ /* * Copyright (c) 2016 Eric McCorkle * All rights reserved. * * 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. * * 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. */ #include #ifndef _EFIZFS_H_ #define _EFIZFS_H_ typedef STAILQ_HEAD(zfsinfo_list, zfsinfo) zfsinfo_list_t; typedef struct zfsinfo { STAILQ_ENTRY(zfsinfo) zi_link; EFI_HANDLE zi_handle; uint64_t zi_pool_guid; } zfsinfo_t; extern uint64_t pool_guid; extern void efi_zfs_probe(void); extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void); extern bool efi_zfs_is_preferred(EFI_HANDLE *h); extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t); extern bool efizfs_get_guid_by_handle(EFI_HANDLE, uint64_t *); #endif # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # .KEEP_STATE: include $(SRC)/Makefile.master SUBDIRS = $(MACH64) all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber install : TARGET = install all clean clobber: $(SUBDIRS) install: all .PARALLEL: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # include $(SRC)/Makefile.master include $(SRC)/boot/Makefile.inc install: OBJS += delay.o \ devicename.o \ devpath.o \ efi_console.o \ efi_driver_utils.o \ efichar.o \ efienv.o \ efinet.o \ efipart.o \ efiserialio.o \ efiisaio.o \ efizfs.o \ env.o \ errno.o \ gfx_fb.o \ handles.o \ libefi.o \ pnglite.o \ wchar.o CPPFLAGS += -DEFI CPPFLAGS += -I. -I../../../include -I../../../sys CPPFLAGS += -I$(SRC)/common/ficl -I../../../libficl CPPFLAGS += -I../../include CPPFLAGS += -I../../include/$(MACHINE) CPPFLAGS += -I../../../libsa CPPFLAGS += -I$(ZFSSRC) CPPFLAGS += -I../../../sys/cddl/boot/zfs gfx_fb.o : CPPFLAGS += $(DEFAULT_CONSOLE_COLOR) -I$(LZ4) pnglite.o : CPPFLAGS += -I$(ZLIB) gfx_fb.o pnglite.o efi_console.o : CPPFLAGS += -I$(PNGLITE) # Pick up the bootstrap header for some interface items CPPFLAGS += -I../../../common include ../../Makefile.inc # For multiboot2.h, must be last, to avoid conflicts CPPFLAGS += -I$(SRC)/uts/common libefi.a: $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) clean: clobber clobber: $(RM) $(CLEANFILES) $(OBJS) libefi.a machine: $(RM) machine $(SYMLINK) ../../../sys/$(MACHINE)/include machine x86: $(RM) x86 $(SYMLINK) ../../../sys/x86/include x86 %.o: ../%.c $(COMPILE.c) $< %.o: ../../../common/%.c $(COMPILE.c) $< %.o: $(PNGLITE)/%.c $(COMPILE.c) $< # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2016 RackTop Systems. # MACHINE= $(MACH64) all: libefi.a OBJS= time.o include ../Makefile.com CFLAGS += -m64 $(CFLAGS64) CLEANFILES += machine x86 $(OBJS): machine x86 /* * Copyright (c) 2001 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include #include #include void delay(int); void delay(int usecs) { if (has_boot_services) BS->Stall(usecs); } /* * Copyright (c) 1998 Michael Smith * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include static int efi_parsedev(struct devdesc **, const char *, const char **); /* * Point (dev) at an allocated device specifier for the device matching the * path in (devspec). If it contains an explicit device specification, * use that. If not, use the default device. */ int efi_getdev(void **vdev, const char *devspec, const char **path) { struct devdesc **dev = (struct devdesc **)vdev; int rv; /* * If it looks like this is just a path and no device, then * use the current device instead. */ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) { rv = efi_parsedev(dev, getenv("currdev"), NULL); if (rv == 0 && path != NULL) *path = devspec; return (rv); } /* Parse the device name off the beginning of the devspec. */ return (efi_parsedev(dev, devspec, path)); } /* * Point (dev) at an allocated device specifier matching the string version * at the beginning of (devspec). Return a pointer to the remaining * text in (path). * * In all cases, the beginning of (devspec) is compared to the names * of known devices in the device switch, and then any following text * is parsed according to the rules applied to the device type. * * For disk-type devices, the syntax is: * * fs: */ static int efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) { struct devdesc *idev; struct devsw *dv; int i, unit, err; char *cp; const char *np; /* minimum length check */ if (strlen(devspec) < 2) return (EINVAL); /* look for a device that matches */ for (i = 0; devsw[i] != NULL; i++) { dv = devsw[i]; if (strncmp(devspec, dv->dv_name, strlen(dv->dv_name)) == 0) break; } if (devsw[i] == NULL) return (ENOENT); np = devspec + strlen(dv->dv_name); idev = NULL; err = 0; switch (dv->dv_type) { case DEVT_NONE: break; case DEVT_DISK: idev = malloc(sizeof (struct disk_devdesc)); if (idev == NULL) return (ENOMEM); err = disk_parsedev((struct disk_devdesc *)idev, np, path); if (err != 0) goto fail; break; case DEVT_ZFS: idev = malloc(sizeof (struct zfs_devdesc)); if (idev == NULL) return (ENOMEM); err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); if (err != 0) goto fail; break; default: idev = malloc(sizeof (struct devdesc)); if (idev == NULL) return (ENOMEM); unit = 0; cp = (char *)np; if (*np != '\0' && *np != ':') { /* get unit number if present */ errno = 0; unit = strtol(np, &cp, 0); if (errno != 0 || cp == np) { err = EUNIT; goto fail; } } if (*cp != '\0' && *cp != ':') { err = EINVAL; goto fail; } idev->d_unit = unit; if (path != NULL) *path = (*cp == '\0') ? cp : cp + 1; break; } idev->d_dev = dv; if (dev != NULL) *dev = idev; else free(idev); return (0); fail: free(idev); return (err); } char * efi_fmtdev(void *vdev) { struct devdesc *dev = (struct devdesc *)vdev; static char buf[SPECNAMELEN + 1]; switch (dev->d_dev->dv_type) { case DEVT_NONE: strlcpy(buf, "(no device)", sizeof (buf)); break; case DEVT_DISK: return (disk_fmtdev(vdev)); case DEVT_ZFS: return (zfs_fmtdev(dev)); default: snprintf(buf, sizeof (buf), "%s%d:", dev->d_dev->dv_name, dev->d_unit); break; } return (buf); } /* * Set currdev to suit the value being supplied in (value) */ int efi_setcurrdev(struct env_var *ev, int flags, const void *value) { struct devdesc *ncurr; int rv; rv = efi_parsedev(&ncurr, value, NULL); if (rv != 0) return (rv); free(ncurr); env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (0); } /*- * Copyright (c) 2016 John Baldwin * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include EFI_GUID gEfiLoadedImageDevicePathProtocolGuid = EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID gEfiDevicePathProtocolGuid = DEVICE_PATH_PROTOCOL; EFI_GUID gEfiDevicePathToTextProtocolGuid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *textProtocol; EFI_DEVICE_PATH * efi_lookup_image_devpath(EFI_HANDLE handle) { EFI_DEVICE_PATH *devpath; EFI_STATUS status; status = OpenProtocolByHandle(handle, &gEfiLoadedImageDevicePathProtocolGuid, (void **)&devpath); if (EFI_ERROR(status)) devpath = NULL; return (devpath); } EFI_DEVICE_PATH * efi_lookup_devpath(EFI_HANDLE handle) { EFI_DEVICE_PATH *devpath; EFI_STATUS status; status = OpenProtocolByHandle(handle, &gEfiDevicePathProtocolGuid, (void **)&devpath); if (EFI_ERROR(status)) devpath = NULL; return (devpath); } void efi_close_devpath(EFI_HANDLE handle) { EFI_STATUS status; status = BS->CloseProtocol(handle, &gEfiDevicePathProtocolGuid, IH, NULL); if (EFI_ERROR(status)) printf("CloseProtocol error: %lu\n", DECODE_ERROR(status)); } CHAR16 * efi_devpath_name(EFI_DEVICE_PATH *devpath) { static bool once = true; EFI_STATUS status; if (devpath == NULL) return (NULL); if (once) { status = BS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (void **)&textProtocol); if (EFI_ERROR(status)) textProtocol = NULL; once = false; } if (textProtocol == NULL) return (NULL); return (textProtocol->ConvertDevicePathToText(devpath, TRUE, TRUE)); } void efi_free_devpath_name(CHAR16 *text) { BS->FreePool(text); } EFI_DEVICE_PATH * efi_devpath_last_node(EFI_DEVICE_PATH *devpath) { if (IsDevicePathEnd(devpath)) return (NULL); while (!IsDevicePathEnd(NextDevicePathNode(devpath))) devpath = NextDevicePathNode(devpath); return (devpath); } /* * Walk device path nodes, return next instance or end node. */ EFI_DEVICE_PATH * efi_devpath_next_instance(EFI_DEVICE_PATH *devpath) { while (!IsDevicePathEnd(devpath)) { devpath = NextDevicePathNode(devpath); if (IsDevicePathEndType(devpath) && devpath->SubType == END_INSTANCE_DEVICE_PATH_SUBTYPE) { devpath = NextDevicePathNode(devpath); break; } } return (devpath); } EFI_DEVICE_PATH * efi_devpath_trim(EFI_DEVICE_PATH *devpath) { EFI_DEVICE_PATH *node, *copy; size_t prefix, len; if ((node = efi_devpath_last_node(devpath)) == NULL) return (NULL); prefix = (UINT8 *)node - (UINT8 *)devpath; if (prefix == 0) return (NULL); len = prefix + DevicePathNodeLength(NextDevicePathNode(node)); copy = malloc(len); if (copy != NULL) { memcpy(copy, devpath, prefix); node = (EFI_DEVICE_PATH *)((UINT8 *)copy + prefix); SetDevicePathEndNode(node); } return (copy); } EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *devpath) { EFI_STATUS status; EFI_HANDLE h; /* * There isn't a standard way to locate a handle for a given * device path. However, querying the EFI_DEVICE_PATH protocol * for a given device path should give us a handle for the * closest node in the path to the end that is valid. */ status = BS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &devpath, &h); if (EFI_ERROR(status)) return (NULL); return (h); } bool efi_devpath_match(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { size_t len; if (devpath1 == NULL || devpath2 == NULL) return (false); while (true) { if (DevicePathType(devpath1) != DevicePathType(devpath2) || DevicePathSubType(devpath1) != DevicePathSubType(devpath2)) return (false); len = DevicePathNodeLength(devpath1); if (len != DevicePathNodeLength(devpath2)) return (false); if (memcmp(devpath1, devpath2, len) != 0) return (false); if (IsDevicePathEnd(devpath1)) break; devpath1 = NextDevicePathNode(devpath1); devpath2 = NextDevicePathNode(devpath2); } return (true); } bool efi_devpath_is_prefix(EFI_DEVICE_PATH *prefix, EFI_DEVICE_PATH *path) { size_t len; if (prefix == NULL || path == NULL) return (false); while (1) { if (IsDevicePathEnd(prefix)) break; if (DevicePathType(prefix) != DevicePathType(path) || DevicePathSubType(prefix) != DevicePathSubType(path)) return (false); len = DevicePathNodeLength(prefix); if (len != DevicePathNodeLength(path)) return (false); if (memcmp(prefix, path, len) != 0) return (false); prefix = NextDevicePathNode(prefix); path = NextDevicePathNode(path); } return (true); } /* * Copyright (c) 2000 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" struct efi_fb efifb; EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; EFI_UGA_DRAW_PROTOCOL *uga; EFI_GUID gEfiConsoleInDeviceGuid = EFI_CONSOLE_IN_DEVICE_GUID; EFI_GUID gEfiConsoleOutDeviceGuid = EFI_CONSOLE_OUT_DEVICE_GUID; EFI_GUID gEfiStandardErrorDeviceGuid = EFI_STANDARD_ERROR_DEVICE_GUID; EFI_GUID gEfiConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; EFI_GUID gEfiSimpleTextInProtocolGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID; EFI_GUID gEfiSimpleTextInputExProtocolGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; EFI_GUID gEfiSimpleTextOutProtocolGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID; extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL *shadow_fb; static size_t shadow_sz; /* units of pages */ static EFI_CONSOLE_CONTROL_PROTOCOL *console_control; static EFI_CONSOLE_CONTROL_SCREEN_MODE console_mode; static SIMPLE_TEXT_OUTPUT_INTERFACE *conout; /* mode change callback and argument from tem */ static vis_modechg_cb_t modechg_cb; static struct vis_modechg_arg *modechg_arg; static tem_vt_state_t tem; struct efi_console_data { struct visual_ops *ecd_visual_ops; SIMPLE_INPUT_INTERFACE *ecd_conin; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ecd_coninex; }; #define KEYBUFSZ 10 static unsigned keybuf[KEYBUFSZ]; /* keybuf for extended codes */ static int key_pending; static const unsigned char solaris_color_to_efi_color[16] = { EFI_WHITE, EFI_BLACK, EFI_BLUE, EFI_GREEN, EFI_CYAN, EFI_RED, EFI_MAGENTA, EFI_BROWN, EFI_LIGHTGRAY, EFI_DARKGRAY, EFI_LIGHTBLUE, EFI_LIGHTGREEN, EFI_LIGHTCYAN, EFI_LIGHTRED, EFI_LIGHTMAGENTA, EFI_YELLOW }; #define DEFAULT_FGCOLOR EFI_LIGHTGRAY #define DEFAULT_BGCOLOR EFI_BLACK extern int efi_find_framebuffer(struct efi_fb *efifb); static void efi_framebuffer_setup(void); static void efi_cons_probe(struct console *); static int efi_cons_init(struct console *, int); static void efi_cons_putchar(struct console *, int); static void efi_cons_efiputchar(int); static int efi_cons_getchar(struct console *); static int efi_cons_poll(struct console *); static int efi_cons_ioctl(struct console *cp, int cmd, void *data); static void efi_cons_devinfo(struct console *); static int efi_fb_devinit(struct vis_devinit *); static void efi_cons_cursor(struct vis_conscursor *); static int efi_text_devinit(struct vis_devinit *); static int efi_text_cons_clear(struct vis_consclear *); static void efi_text_cons_copy(struct vis_conscopy *); static void efi_text_cons_display(struct vis_consdisplay *); struct console efi_console = { .c_name = "text", .c_desc = "EFI console", .c_flags = C_WIDEOUT, .c_probe = efi_cons_probe, .c_init = efi_cons_init, .c_out = efi_cons_putchar, .c_in = efi_cons_getchar, .c_ready = efi_cons_poll, .c_ioctl = efi_cons_ioctl, .c_devinfo = efi_cons_devinfo, .c_private = NULL }; static struct vis_identifier fb_ident = { "efi_fb" }; static struct vis_identifier text_ident = { "efi_text" }; struct visual_ops fb_ops = { .ident = &fb_ident, .kdsetmode = NULL, .devinit = efi_fb_devinit, .cons_copy = gfx_fb_cons_copy, .cons_display = gfx_fb_cons_display, .cons_cursor = efi_cons_cursor, .cons_clear = gfx_fb_cons_clear, .cons_put_cmap = NULL }; struct visual_ops text_ops = { .ident = &text_ident, .kdsetmode = NULL, .devinit = efi_text_devinit, .cons_copy = efi_text_cons_copy, .cons_display = efi_text_cons_display, .cons_cursor = efi_cons_cursor, .cons_clear = efi_text_cons_clear, .cons_put_cmap = NULL }; /* * platform specific functions for tem */ int plat_stdout_is_framebuffer(void) { return (console_mode == EfiConsoleControlScreenGraphics); } void plat_tem_hide_prom_cursor(void) { if (has_boot_services) conout->EnableCursor(conout, FALSE); } static void plat_tem_display_prom_cursor(screen_pos_t row, screen_pos_t col) { if (has_boot_services) { conout->SetCursorPosition(conout, col, row); conout->EnableCursor(conout, TRUE); } } void plat_tem_get_prom_pos(uint32_t *row, uint32_t *col) { if (console_mode == EfiConsoleControlScreenText) { *col = (uint32_t)conout->Mode->CursorColumn; *row = (uint32_t)conout->Mode->CursorRow; } else { *col = 0; *row = 0; } } /* * plat_tem_get_prom_size() is supposed to return screen size * in chars. Return real data for text mode and TEM defaults for graphical * mode, so the tem can compute values based on default and font. */ void plat_tem_get_prom_size(size_t *height, size_t *width) { UINTN cols, rows; if (console_mode == EfiConsoleControlScreenText) { (void) conout->QueryMode(conout, conout->Mode->Mode, &cols, &rows); *height = (size_t)rows; *width = (size_t)cols; } else { *height = TEM_DEFAULT_ROWS; *width = TEM_DEFAULT_COLS; } } /* * Callback to notify about console mode change. * mode is value from enum EFI_CONSOLE_CONTROL_SCREEN_MODE. */ void plat_cons_update_mode(int mode) { UINTN cols, rows; struct vis_devinit devinit; struct efi_console_data *ecd = efi_console.c_private; /* Make sure we have usable console. */ if (efi_find_framebuffer(&efifb)) { console_mode = EfiConsoleControlScreenText; } else { efi_framebuffer_setup(); if (mode != -1 && console_mode != mode) console_mode = mode; } if (console_control != NULL) (void) console_control->SetMode(console_control, console_mode); /* some firmware enables the cursor when switching modes */ conout->EnableCursor(conout, FALSE); if (console_mode == EfiConsoleControlScreenText) { (void) conout->QueryMode(conout, conout->Mode->Mode, &cols, &rows); devinit.version = VIS_CONS_REV; devinit.width = cols; devinit.height = rows; devinit.depth = 4; devinit.linebytes = cols; devinit.color_map = NULL; devinit.mode = VIS_TEXT; ecd->ecd_visual_ops = &text_ops; } else { devinit.version = VIS_CONS_REV; devinit.width = gfx_fb.framebuffer_common.framebuffer_width; devinit.height = gfx_fb.framebuffer_common.framebuffer_height; devinit.depth = gfx_fb.framebuffer_common.framebuffer_bpp; devinit.linebytes = gfx_fb.framebuffer_common.framebuffer_pitch; devinit.color_map = gfx_fb_color_map; devinit.mode = VIS_PIXEL; ecd->ecd_visual_ops = &fb_ops; } modechg_cb(modechg_arg, &devinit); } static int efi_fb_devinit(struct vis_devinit *data) { if (console_mode != EfiConsoleControlScreenGraphics) return (1); data->version = VIS_CONS_REV; data->width = gfx_fb.framebuffer_common.framebuffer_width; data->height = gfx_fb.framebuffer_common.framebuffer_height; data->depth = gfx_fb.framebuffer_common.framebuffer_bpp; data->linebytes = gfx_fb.framebuffer_common.framebuffer_pitch; data->color_map = gfx_fb_color_map; data->mode = VIS_PIXEL; modechg_cb = data->modechg_cb; modechg_arg = data->modechg_arg; return (0); } static int efi_text_devinit(struct vis_devinit *data) { UINTN cols, rows; if (console_mode != EfiConsoleControlScreenText) return (1); (void) conout->QueryMode(conout, conout->Mode->Mode, &cols, &rows); data->version = VIS_CONS_REV; data->width = cols; data->height = rows; data->depth = 4; data->linebytes = cols; data->color_map = NULL; data->mode = VIS_TEXT; modechg_cb = data->modechg_cb; modechg_arg = data->modechg_arg; return (0); } static int efi_text_cons_clear(struct vis_consclear *ca) { EFI_STATUS st; UINTN attr = conout->Mode->Attribute & 0x0F; uint8_t bg; if (!has_boot_services) return (0); bg = solaris_color_to_efi_color[ca->bg_color.four & 0xF] & 0x7; attr = EFI_TEXT_ATTR(attr, bg); st = conout->SetAttribute(conout, attr); if (EFI_ERROR(st)) return (1); st = conout->ClearScreen(conout); if (EFI_ERROR(st)) return (1); return (0); } static void efi_text_cons_copy(struct vis_conscopy *ma) { UINTN col, row; if (!has_boot_services) return; col = 0; row = ma->e_row; conout->SetCursorPosition(conout, col, row); efi_cons_efiputchar('\n'); } static void efi_text_cons_display(struct vis_consdisplay *da) { EFI_STATUS st; UINTN attr; UINTN row, col; tem_char_t *data; uint8_t fg, bg; int i; if (!has_boot_services) return; (void) conout->QueryMode(conout, conout->Mode->Mode, &col, &row); /* reduce clear line on bottom row by one to prevent autoscroll */ if (row - 1 == da->row && da->col == 0 && da->width == col) da->width--; data = (tem_char_t *)da->data; fg = solaris_color_to_efi_color[da->fg_color.four & 0xf]; bg = solaris_color_to_efi_color[da->bg_color.four & 0xf] & 0x7; attr = EFI_TEXT_ATTR(fg, bg); st = conout->SetAttribute(conout, attr); if (EFI_ERROR(st)) return; row = da->row; col = da->col; conout->SetCursorPosition(conout, col, row); for (i = 0; i < da->width; i++) efi_cons_efiputchar(data[i]); } static void efi_cons_cursor(struct vis_conscursor *cc) { switch (cc->action) { case VIS_HIDE_CURSOR: if (plat_stdout_is_framebuffer()) gfx_fb_display_cursor(cc); else plat_tem_hide_prom_cursor(); break; case VIS_DISPLAY_CURSOR: if (plat_stdout_is_framebuffer()) gfx_fb_display_cursor(cc); else plat_tem_display_prom_cursor(cc->row, cc->col); break; case VIS_GET_CURSOR: { /* only used at startup */ uint32_t row, col; row = col = 0; plat_tem_get_prom_pos(&row, &col); cc->row = row; cc->col = col; } break; } } static int efi_cons_ioctl(struct console *cp, int cmd, void *data) { struct efi_console_data *ecd = cp->c_private; struct visual_ops *ops = ecd->ecd_visual_ops; switch (cmd) { case VIS_GETIDENTIFIER: memmove(data, ops->ident, sizeof (struct vis_identifier)); break; case VIS_DEVINIT: return (ops->devinit(data)); case VIS_CONSCLEAR: return (ops->cons_clear(data)); case VIS_CONSCOPY: ops->cons_copy(data); break; case VIS_CONSDISPLAY: ops->cons_display(data); break; case VIS_CONSCURSOR: ops->cons_cursor(data); break; default: return (EINVAL); } return (0); } static void efi_framebuffer_setup(void) { int bpp, pos; EFI_STATUS status; bpp = fls(efifb.fb_mask_red | efifb.fb_mask_green | efifb.fb_mask_blue | efifb.fb_mask_reserved); /* * To save heap space, allocate shadow fb with AllocatePages(). * FB memory can be rather large and its size depends on resolution. */ if (shadow_fb != NULL) { BS->FreePages((EFI_PHYSICAL_ADDRESS)(uintptr_t)shadow_fb, shadow_sz); } shadow_sz = EFI_SIZE_TO_PAGES(efifb.fb_width * efifb.fb_height * sizeof (*shadow_fb)); status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, shadow_sz, (EFI_PHYSICAL_ADDRESS *)&shadow_fb); if (status != EFI_SUCCESS) shadow_fb = NULL; gfx_fb.framebuffer_common.mb_type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; gfx_fb.framebuffer_common.mb_size = sizeof (gfx_fb); gfx_fb.framebuffer_common.framebuffer_addr = efifb.fb_addr; gfx_fb.framebuffer_common.framebuffer_width = efifb.fb_width; gfx_fb.framebuffer_common.framebuffer_height = efifb.fb_height; gfx_fb.framebuffer_common.framebuffer_bpp = bpp; gfx_fb.framebuffer_common.framebuffer_pitch = efifb.fb_stride * (bpp >> 3); gfx_fb.framebuffer_common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; gfx_fb.framebuffer_common.mb_reserved = 0; pos = ffs(efifb.fb_mask_red); if (pos != 0) pos--; gfx_fb.u.fb2.framebuffer_red_mask_size = fls(efifb.fb_mask_red >> pos); gfx_fb.u.fb2.framebuffer_red_field_position = pos; pos = ffs(efifb.fb_mask_green); if (pos != 0) pos--; gfx_fb.u.fb2.framebuffer_green_mask_size = fls(efifb.fb_mask_green >> pos); gfx_fb.u.fb2.framebuffer_green_field_position = pos; pos = ffs(efifb.fb_mask_blue); if (pos != 0) pos--; gfx_fb.u.fb2.framebuffer_blue_mask_size = fls(efifb.fb_mask_blue >> pos); gfx_fb.u.fb2.framebuffer_blue_field_position = pos; } static void efi_cons_probe(struct console *cp) { struct efi_console_data *ecd; void *coninex; EFI_STATUS status; cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; if (cp->c_private != NULL) return; memset(keybuf, 0, KEYBUFSZ); conout = ST->ConOut; ecd = calloc(1, sizeof (*ecd)); /* * As console probing is called very early, the only reason for * out of memory can be that we just do not have enough memory. */ if (ecd == NULL) panic("efi_cons_probe: This system has not enough memory\n"); cp->c_private = ecd; ecd->ecd_conin = ST->ConIn; /* * Try to set up for SimpleTextInputEx protocol. If not available, * we will use SimpleTextInput protocol. */ coninex = NULL; status = BS->OpenProtocol(ST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, &coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (status == EFI_SUCCESS) ecd->ecd_coninex = coninex; if (efi_find_framebuffer(&efifb)) { console_mode = EfiConsoleControlScreenText; ecd->ecd_visual_ops = &text_ops; } else { efi_framebuffer_setup(); console_mode = EfiConsoleControlScreenGraphics; ecd->ecd_visual_ops = &fb_ops; } /* * UEFI console is tricky, it may be video or serial device(s), * or both, SimpleTextOutput protocol will output on all listed * devices in "ConOut". If video console is present, we will not * use SimpleTextOutput and render the text on video screen only. */ if (console_mode == EfiConsoleControlScreenGraphics) (void) setenv("console", cp->c_name, 1); } static int efi_cons_init(struct console *cp, int arg __unused) { EFI_STATUS status; UINTN i, max_dim, best_mode, cols, rows; if (tem != NULL) return (0); conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR, DEFAULT_BGCOLOR)); status = BS->LocateProtocol(&gEfiConsoleControlProtocolGuid, NULL, (void **)&console_control); max_dim = best_mode = 0; for (i = 0; i <= conout->Mode->MaxMode; i++) { status = conout->QueryMode(conout, i, &cols, &rows); if (EFI_ERROR(status)) continue; if (cols * rows > max_dim) { max_dim = cols * rows; best_mode = i; } } if (max_dim > 0) conout->SetMode(conout, best_mode); status = conout->QueryMode(conout, best_mode, &cols, &rows); if (EFI_ERROR(status)) { setenv("screen-#rows", "24", 1); setenv("screen-#cols", "80", 1); } else { char env[8]; snprintf(env, sizeof (env), "%u", (unsigned)rows); setenv("screen-#rows", env, 1); snprintf(env, sizeof (env), "%u", (unsigned)cols); setenv("screen-#cols", env, 1); } if (console_control != NULL) (void) console_control->SetMode(console_control, console_mode); /* some firmware enables the cursor when switching modes */ conout->EnableCursor(conout, FALSE); gfx_framework_init(); if (tem_info_init(cp) == 0 && tem == NULL) { tem = tem_init(); if (tem != NULL) tem_activate(tem, B_TRUE); } if (tem == NULL) panic("Failed to set up console terminal"); return (0); } static void efi_cons_putchar(struct console *cp __unused, int c) { uint8_t buf = c; /* make sure we have some console output, support for panic() */ if (tem == NULL) efi_cons_efiputchar(c); else tem_write(tem, &buf, sizeof (buf)); } static int keybuf_getchar(void) { int i, c = 0; for (i = 0; i < KEYBUFSZ; i++) { if (keybuf[i] != 0) { c = keybuf[i]; keybuf[i] = 0; break; } } return (c); } static bool keybuf_ischar(void) { int i; for (i = 0; i < KEYBUFSZ; i++) { if (keybuf[i] != 0) return (true); } return (false); } /* * We are not reading input before keybuf is empty, so we are safe * just to fill keybuf from the beginning. */ static void keybuf_inschar(EFI_INPUT_KEY *key) { switch (key->ScanCode) { case SCAN_UP: /* UP */ keybuf[0] = 0x1b; /* esc */ keybuf[1] = '['; keybuf[2] = 'A'; break; case SCAN_DOWN: /* DOWN */ keybuf[0] = 0x1b; /* esc */ keybuf[1] = '['; keybuf[2] = 'B'; break; case SCAN_RIGHT: /* RIGHT */ keybuf[0] = 0x1b; /* esc */ keybuf[1] = '['; keybuf[2] = 'C'; break; case SCAN_LEFT: /* LEFT */ keybuf[0] = 0x1b; /* esc */ keybuf[1] = '['; keybuf[2] = 'D'; break; case SCAN_DELETE: keybuf[0] = CHAR_BACKSPACE; break; case SCAN_ESC: keybuf[0] = 0x1b; /* esc */ break; default: keybuf[0] = key->UnicodeChar; break; } } static bool efi_readkey(SIMPLE_INPUT_INTERFACE *conin) { EFI_STATUS status; EFI_INPUT_KEY key; status = conin->ReadKeyStroke(conin, &key); if (status == EFI_SUCCESS) { keybuf_inschar(&key); return (true); } return (false); } static bool efi_readkey_ex(EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *coninex) { EFI_STATUS status; EFI_INPUT_KEY *kp; EFI_KEY_DATA key_data; uint32_t kss; status = coninex->ReadKeyStrokeEx(coninex, &key_data); if (status == EFI_SUCCESS) { kss = key_data.KeyState.KeyShiftState; kp = &key_data.Key; if (kss & EFI_SHIFT_STATE_VALID) { /* * quick mapping to control chars, replace with * map lookup later. */ if (kss & EFI_RIGHT_CONTROL_PRESSED || kss & EFI_LEFT_CONTROL_PRESSED) { if (kp->UnicodeChar >= 'a' && kp->UnicodeChar <= 'z') { kp->UnicodeChar -= 'a'; kp->UnicodeChar++; } } } /* * The shift state and/or toggle state may not be valid, * but we still can have ScanCode or UnicodeChar. */ if (kp->ScanCode == 0 && kp->UnicodeChar == 0) return (false); keybuf_inschar(kp); return (true); } return (false); } static int efi_cons_getchar(struct console *cp) { struct efi_console_data *ecd; int c; if ((c = keybuf_getchar()) != 0) return (c); if (!has_boot_services) return (-1); ecd = cp->c_private; key_pending = 0; if (ecd->ecd_coninex == NULL) { if (efi_readkey(ecd->ecd_conin)) return (keybuf_getchar()); } else { if (efi_readkey_ex(ecd->ecd_coninex)) return (keybuf_getchar()); } return (-1); } static int efi_cons_poll(struct console *cp) { struct efi_console_data *ecd; EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *coninex; SIMPLE_INPUT_INTERFACE *conin; EFI_STATUS status; if (keybuf_ischar() || key_pending) return (1); if (!has_boot_services) return (0); ecd = cp->c_private; coninex = ecd->ecd_coninex; conin = ecd->ecd_conin; /* * Some EFI implementation (u-boot for example) do not support * WaitForKey(). * CheckEvent() can clear the signaled state. */ if (coninex != NULL) { if (coninex->WaitForKeyEx == NULL) key_pending = efi_readkey_ex(coninex); else { status = BS->CheckEvent(coninex->WaitForKeyEx); key_pending = status == EFI_SUCCESS; } } else { if (conin->WaitForKey == NULL) key_pending = efi_readkey(conin); else { status = BS->CheckEvent(conin->WaitForKey); key_pending = status == EFI_SUCCESS; } } return (key_pending); } /* Plain direct access to EFI OutputString(). */ void efi_cons_efiputchar(int c) { CHAR16 buf[2]; EFI_STATUS status; buf[0] = c; buf[1] = 0; /* terminate string */ status = conout->TestString(conout, buf); if (EFI_ERROR(status)) buf[0] = '?'; conout->OutputString(conout, buf); } static void efi_cons_devinfo_print(EFI_HANDLE handle) { EFI_DEVICE_PATH *dp; CHAR16 *text; dp = efi_lookup_devpath(handle); if (dp == NULL) return; text = efi_devpath_name(dp); if (text == NULL) return; printf("\t%S", text); efi_free_devpath_name(text); } static void efi_cons_devinfo(struct console *cp __unused) { EFI_HANDLE *handles; uint_t nhandles; EFI_STATUS status; if (gop != NULL) status = efi_get_protocol_handles( &gEfiGraphicsOutputProtocolGuid, &nhandles, &handles); else status = efi_get_protocol_handles(&gEfiUgaDrawProtocolGuid, &nhandles, &handles); if (EFI_ERROR(status)) return; for (uint_t i = 0; i < nhandles; i++) efi_cons_devinfo_print(handles[i]); free(handles); } /* * Copyright (c) 2017 Eric McCorkle * All rights reserved. * * 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. * * 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. */ #include #include #include #include "efi_driver_utils.h" EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID; EFI_STATUS connect_controllers(EFI_GUID *filter) { EFI_STATUS status; EFI_HANDLE *handles; uint_t nhandles, i; status = efi_get_protocol_handles(filter, &nhandles, &handles); if (EFI_ERROR(status)) { return (status); } for (i = 0; i < nhandles; i++) { BS->ConnectController(handles[i], NULL, NULL, true); } free(handles); return (status); } EFI_STATUS install_driver(EFI_DRIVER_BINDING_PROTOCOL *driver) { EFI_STATUS status; driver->ImageHandle = IH; driver->DriverBindingHandle = NULL; status = BS->InstallMultipleProtocolInterfaces( &(driver->DriverBindingHandle), &gEfiDriverBindingProtocolGuid, driver, NULL); if (EFI_ERROR(status)) { printf("Failed to install driver (%ld)!\n", DECODE_ERROR(status)); } return (status); } /* * Copyright (c) 2010 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include int ucs2len(const CHAR16 *str) { int i; i = 0; while (*str++) i++; return (i); } /* * If nm were converted to utf8, what what would strlen * return on the resulting string? */ static size_t utf8_len_of_ucs2(const CHAR16 *nm) { size_t len; CHAR16 c; len = 0; while (*nm) { c = *nm++; if (c > 0x7ff) len += 3; else if (c > 0x7f) len += 2; else len++; } return (len); } int ucs2_to_utf8(const CHAR16 *nm, char **name) { size_t len, sz; CHAR16 c; char *cp; int freeit = *name == NULL; sz = utf8_len_of_ucs2(nm) + 1; len = 0; if (*name != NULL) cp = *name; else cp = *name = malloc(sz); if (*name == NULL) return (ENOMEM); while (*nm) { c = *nm++; if (c > 0x7ff) { if (len++ < sz) *cp++ = (char)(0xE0 | (c >> 12)); if (len++ < sz) *cp++ = (char)(0x80 | ((c >> 6) & 0x3f)); if (len++ < sz) *cp++ = (char)(0x80 | (c & 0x3f)); } else if (c > 0x7f) { if (len++ < sz) *cp++ = (char)(0xC0 | ((c >> 6) & 0x1f)); if (len++ < sz) *cp++ = (char)(0x80 | (c & 0x3f)); } else { if (len++ < sz) *cp++ = (char)(c & 0x7f); } } if (len >= sz) { /* Absent bugs, we'll never return EOVERFLOW */ if (freeit) { free(*name); *name = NULL; } return (EOVERFLOW); } *cp++ = '\0'; return (0); } int utf8_to_ucs2(const char *name, CHAR16 **nmp, size_t *len) { CHAR16 *nm; size_t sz; uint32_t ucs4; int c, bytes; int freeit = *nmp == NULL; sz = strlen(name) * 2 + 2; if (*nmp == NULL) *nmp = malloc(sz); if (*nmp == NULL) return (ENOMEM); nm = *nmp; *len = sz; ucs4 = 0; bytes = 0; while (sz > 1 && *name != '\0') { c = *name++; /* * Conditionalize on the two major character types: * initial and followup characters. */ if ((c & 0xc0) != 0x80) { /* Initial characters. */ if (bytes != 0) goto ilseq; if ((c & 0xf8) == 0xf0) { ucs4 = c & 0x07; bytes = 3; } else if ((c & 0xf0) == 0xe0) { ucs4 = c & 0x0f; bytes = 2; } else if ((c & 0xe0) == 0xc0) { ucs4 = c & 0x1f; bytes = 1; } else { ucs4 = c & 0x7f; bytes = 0; } } else { /* Followup characters. */ if (bytes > 0) { ucs4 = (ucs4 << 6) + (c & 0x3f); bytes--; } else if (bytes == 0) { goto ilseq; } } if (bytes == 0) { if (ucs4 > 0xffff) goto ilseq; *nm++ = (CHAR16)ucs4; sz -= 2; } } if (sz < 2) { if (freeit) { free(nm); *nmp = NULL; } return (EDOOFUS); } sz -= 2; *nm = 0; *len -= sz; return (0); ilseq: if (freeit) { free(nm); *nmp = NULL; } return (EILSEQ); } /* * Copyright (c) 2018 Netflix, Inc. * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include EFI_GUID gillumosBootVarGuid = ILLUMOS_BOOT_VAR_GUID; EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE; EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len) { size_t ul; CHAR16 *uv; UINT32 attr; UINTN dl; EFI_STATUS rv; uv = NULL; if (utf8_to_ucs2(v, &uv, &ul) != 0) return (EFI_OUT_OF_RESOURCES); dl = *len; rv = RS->GetVariable(uv, g, &attr, &dl, data); if (rv == EFI_SUCCESS || rv == EFI_BUFFER_TOO_SMALL) *len = dl; free(uv); return (rv); } EFI_STATUS efi_setenv(EFI_GUID *g, uint32_t attr, const char *v, void *data, size_t len) { size_t ul; CHAR16 *uv; EFI_STATUS rv; uv = NULL; if (utf8_to_ucs2(v, &uv, &ul) != 0) return (EFI_OUT_OF_RESOURCES); rv = RS->SetVariable(uv, g, attr, len, data); free(uv); return (rv); } EFI_STATUS efi_global_getenv(const char *v, void *data, size_t *len) { return (efi_getenv(&gEfiGlobalVariableGuid, v, data, len)); } EFI_STATUS efi_global_setenv(const char *v, void *data, size_t len) { return (efi_setenv(&gEfiGlobalVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, v, data, len)); } EFI_STATUS efi_illumos_getenv(const char *v, void *data, size_t *len) { return (efi_getenv(&gillumosBootVarGuid, v, data, len)); } EFI_STATUS efi_setenv_illumos_wcs(const char *var, CHAR16 *valstr) { return (efi_setenv(&gillumosBootVarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, var, valstr, (ucs2len(valstr) + 1) * sizeof (CHAR16))); } /* * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef MDE_CPU_X64 #include #endif EFI_GUID gEfiIsaIoProtocolGuid = EFI_ISA_IO_PROTOCOL_GUID; #define COMC_TXWAIT 0x40000 /* transmit timeout */ #define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */ #define COMC_DIV2BPS(x) (115200 / (x)) /* DLAB divisor to speed */ #ifndef COMSPEED #define COMSPEED 9600 #endif #define COM1_IOADDR 0x3f8 #define COM2_IOADDR 0x2f8 #define COM3_IOADDR 0x3e8 #define COM4_IOADDR 0x2e8 #ifdef MDE_CPU_X64 static uint_t io_ports[] = { COM1_IOADDR, COM2_IOADDR, COM3_IOADDR, COM4_IOADDR }; #endif #define STOP1 0x00 #define STOP2 0x04 #define PARODD 0x00 #define PAREN 0x08 #define PAREVN 0x10 #define PARMARK 0x20 #define BITS5 0x00 /* 5 bits per char */ #define BITS6 0x01 /* 6 bits per char */ #define BITS7 0x02 /* 7 bits per char */ #define BITS8 0x03 /* 8 bits per char */ #define PNP0501 0x501 /* 16550A-compatible COM port */ static void efi_isa_probe(struct console *); static int efi_isa_init(struct console *, int); static void efi_isa_putchar(struct console *, int); static int efi_isa_getchar(struct console *); static int efi_isa_ischar(struct console *); static int efi_isa_ioctl(struct console *, int, void *); static void efi_isa_devinfo(struct console *); static bool efi_isa_setup(struct console *); static char *efi_isa_asprint_mode(struct serial *); static int efi_isa_parse_mode(struct serial *, const char *); static int efi_isa_mode_set(struct env_var *, int, const void *); static int efi_isa_cd_set(struct env_var *, int, const void *); static int efi_isa_rtsdtr_set(struct env_var *, int, const void *); extern struct console efi_console; static bool efi_isa_port_is_present(struct serial *sp) { EFI_STATUS status; #define COMC_TEST 0xbb uint8_t test = COMC_TEST; /* * Write byte to scratch register and read it out. */ status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_scr, 1, &test); test = 0; if (status == EFI_SUCCESS) { status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_scr, 1, &test); } return (test == COMC_TEST); #undef COMC_TEST } static bool efi_isa_should_append(const char *name, struct serial *port) { EFI_DEVICE_PATH *node, *dev; EFI_STATUS status; char *buf; size_t sz; bool rv = true; if (port->currdev == NULL) return (rv); buf = NULL; sz = 0; status = efi_global_getenv(name, buf, &sz); if (status == EFI_BUFFER_TOO_SMALL) { buf = malloc(sz); if (buf == NULL) return (rv); status = efi_global_getenv(name, buf, &sz); } if (EFI_ERROR(status)) { free(buf); return (rv); } dev = efi_lookup_devpath(port->currdev); if (dev == NULL) { free(buf); return (rv); } node = (EFI_DEVICE_PATH *)buf; /* * We only need to know if this port is first in list. * This is only important when "os_console" is not set. */ if (!IsDevicePathEnd(node) && efi_devpath_is_prefix(dev, node)) rv = false; efi_close_devpath(port->currdev); free(buf); return (rv); } static void efi_isa_setup_env(struct console *tty) { struct serial *port = tty->c_private; char name[20]; char value[20]; char *env; (void) snprintf(name, sizeof (name), "%s-mode", tty->c_name); env = getenv(name); if (env != NULL) (void) efi_isa_parse_mode(port, env); env = efi_isa_asprint_mode(port); if (env != NULL) { (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, env, efi_isa_mode_set, env_nounset); if (port->is_efi_console) { (void) snprintf(name, sizeof (name), "%s-spcr-mode", tty->c_name); (void) setenv(name, env, 1); free(env); /* Add us to console list. */ (void) snprintf(name, sizeof (name), "console"); env = getenv(name); if (env == NULL) { (void) setenv(name, tty->c_name, 1); } else { char *ptr; int rv; /* * we have "text" already in place, * consult ConOut if we need to add * serial console before or after. */ if (efi_isa_should_append("ConOut", port)) rv = asprintf(&ptr, "%s,%s", env, tty->c_name); else rv = asprintf(&ptr, "%s,%s", tty->c_name, env); if (rv > 0) { (void) setenv(name, ptr, 1); free(ptr); } else { printf("%s: %s\n", __func__, strerror(ENOMEM)); } } } else { free(env); } } (void) snprintf(name, sizeof (name), "%s-ignore-cd", tty->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) port->ignore_cd = 1; else if (strcmp(env, "false") == 0) port->ignore_cd = 0; } (void) snprintf(value, sizeof (value), "%s", port->ignore_cd? "true" : "false"); (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, value, efi_isa_cd_set, env_nounset); (void) snprintf(name, sizeof (name), "%s-rts-dtr-off", tty->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) port->rtsdtr_off = 1; else if (strcmp(env, "false") == 0) port->rtsdtr_off = 0; } (void) snprintf(value, sizeof (value), "%s", port->rtsdtr_off? "true" : "false"); (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, value, efi_isa_rtsdtr_set, env_nounset); } static void efi_check_and_set_condev(struct serial *port, const char *name) { EFI_DEVICE_PATH *node, *dev; EFI_STATUS status; char *buf; size_t sz; if (port->currdev == NULL) return; buf = NULL; sz = 0; status = efi_global_getenv(name, buf, &sz); if (status == EFI_BUFFER_TOO_SMALL) { buf = malloc(sz); if (buf == NULL) return; status = efi_global_getenv(name, buf, &sz); } if (EFI_ERROR(status)) { free(buf); return; } dev = efi_lookup_devpath(port->currdev); if (dev == NULL) { free(buf); return; } node = (EFI_DEVICE_PATH *)buf; while (!IsDevicePathEnd(node)) { /* Sanity check the node before moving to the next node. */ if (DevicePathNodeLength(node) < sizeof (*node)) break; if (efi_devpath_is_prefix(dev, node)) { port->is_efi_console = true; break; } node = efi_devpath_next_instance(node); } efi_close_devpath(port->currdev); free(buf); } /* * Return number of ports created (0 or 1). */ static uint_t efi_isa_create_port(EFI_HANDLE handle) { struct serial *port; EFI_ISA_IO_PROTOCOL *io; EFI_STATUS status; status = BS->OpenProtocol(handle, &gEfiIsaIoProtocolGuid, (void**)&io, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(status)) { return (0); } /* Is this serial port? */ if (io->ResourceList->Device.HID != EISA_PNP_ID(PNP0501)) return (0); /* We assume I/O port */ if (io->ResourceList->ResourceItem->Type != EfiIsaAcpiResourceIo) return (0); port = calloc(1, sizeof (*port)); if (port == NULL) { return (0); } /* Set up port descriptor */ port->ignore_cd = true; port->currdev = handle; port->ioaddr = 0; for (uint_t i = 0; io->ResourceList->ResourceItem[i].Type != EfiIsaAcpiResourceEndOfList; i++) { if (io->ResourceList->ResourceItem[i].Type == EfiIsaAcpiResourceIo) { port->ioaddr = io->ResourceList->ResourceItem[i].StartRange; break; } } port->guid = &gEfiIsaIoProtocolGuid; port->io.isa = io; /* Use 8,n,1 for defaults */ port->databits = 8; port->parity = NoParity; port->stopbits = OneStopBit; STAILQ_INSERT_TAIL(&serials, port, next); return (1); } #ifdef MDE_CPU_X64 static EFI_STATUS efi_isa_create_io(EFI_ISA_IO_PROTOCOL **iop) { EFI_ISA_IO_PROTOCOL *io; io = calloc(1, sizeof (*io)); if (io == NULL) { return (EFI_OUT_OF_RESOURCES); } io->ResourceList = malloc(sizeof (*io->ResourceList)); if (io->ResourceList == NULL) { free(io); return (EFI_OUT_OF_RESOURCES); } io->ResourceList->ResourceItem = calloc(2, sizeof (*io->ResourceList->ResourceItem)); if (io->ResourceList == NULL) { free(io->ResourceList); free(io); return (EFI_OUT_OF_RESOURCES); } *iop = io; return (EFI_SUCCESS); } static EFI_STATUS EFIAPI _Read(EFI_ISA_IO_PROTOCOL *this __unused, EFI_ISA_IO_PROTOCOL_WIDTH Width __unused, UINT32 Offset, UINTN Count, VOID *Buffer) { uint8_t *buf = (uint8_t *)Buffer; while ((Count--) != 0) { *buf++ = inb(Offset); } return (EFI_SUCCESS); } static EFI_STATUS EFIAPI _Write(EFI_ISA_IO_PROTOCOL *this __unused, EFI_ISA_IO_PROTOCOL_WIDTH Width __unused, UINT32 Offset, UINTN Count, VOID *Buffer) { uint8_t *buf = (uint8_t *)Buffer; while ((Count--) != 0) { outb(Offset, *buf++); } return (EFI_SUCCESS); } static EFI_STATUS efi_isa_create_io_ports(void) { struct serial *port; EFI_ISA_IO_PROTOCOL *io; EFI_STATUS status = EFI_SUCCESS; port = NULL; for (uint_t i = 0; i < nitems(io_ports); i++) { if (port == NULL) { status = efi_isa_create_io(&io); if (EFI_ERROR(status)) return (status); io->Io.Read = _Read; io->Io.Write = _Write; io->ResourceList->Device.HID = EISA_PNP_ID(PNP0501); io->ResourceList->ResourceItem[0].Type = EfiIsaAcpiResourceIo; io->ResourceList->ResourceItem[1].Type = EfiIsaAcpiResourceEndOfList; port = calloc(1, sizeof (*port)); if (port == NULL) { free(io->ResourceList->ResourceItem); free(io->ResourceList); free(io); return (EFI_OUT_OF_RESOURCES); } /* Set up port descriptor */ port->io.isa = io; /* Use 8,n,1 for defaults */ port->databits = 8; port->parity = NoParity; port->stopbits = OneStopBit; port->ignore_cd = true; port->guid = &gEfiIsaIoProtocolGuid; } io->ResourceList->Device.UID = i; io->ResourceList->ResourceItem[0].StartRange = io_ports[i]; port->ioaddr = io_ports[i]; if (efi_isa_port_is_present(port)) { STAILQ_INSERT_TAIL(&serials, port, next); port = NULL; } } if (port != NULL) { free(io->ResourceList->ResourceItem); free(io->ResourceList); free(io); free(port); } return (status); } #endif /* MDE_CPU_X64 */ /* * Get IsaIo protocol handles and build port list for us. * returns EFI_SUCCESS or EFI_NOT_FOUND. */ static EFI_STATUS efi_isa_probe_ports(void) { EFI_STATUS status; EFI_HANDLE *handles; struct serial *port; uint_t count, nhandles, index; count = 0; nhandles = 0; handles = NULL; status = efi_get_protocol_handles(&gEfiIsaIoProtocolGuid, &nhandles, &handles); if (!EFI_ERROR(status)) { for (index = 0; index < nhandles; index++) { /* skip if we are iodev for serialio port */ STAILQ_FOREACH(port, &serials, next) { if (port->iodev == handles[index]) break; } if (port == NULL) count += efi_isa_create_port(handles[index]); } free(handles); if (count == 0) status = EFI_NOT_FOUND; } return (status); } /* * Set up list of possible serial consoles. * This function is run very early, so we do not expect to * run out of memory, and on error, we can not print output. * * isaio protocols can include serial ports, parallel ports, * keyboard, mouse. We walk protocol handles, create list of * serial ports, then create console descriptors. */ void efi_isa_ini(void) { EFI_STATUS status; uint_t c, n; struct console **tmp; struct console *tty; struct serial *port; status = efi_isa_probe_ports(); #ifdef MDE_CPU_X64 if (status == EFI_NOT_FOUND) { /* * We have no IsaIo serial ports. But, as this implementation * is very similar to one used in BIOS comconsole driver, * and in order to avoid using comconsole as last resort * fallback on x86 platform, we implement fake IsaIo. */ if (STAILQ_EMPTY(&serials)) status = efi_isa_create_io_ports(); } #endif if (EFI_ERROR(status)) return; n = 0; /* Count ports we have */ STAILQ_FOREACH(port, &serials, next) { if (uuid_equal((uuid_t *)port->guid, (uuid_t *)&gEfiIsaIoProtocolGuid, NULL) == 1) n++; } if (n == 0) return; /* no serial ports here */ c = cons_array_size(); if (c == 0) n++; /* For NULL pointer */ tmp = realloc(consoles, (c + n) * sizeof (*consoles)); if (tmp == NULL) { return; } consoles = tmp; if (c > 0) c--; STAILQ_FOREACH(port, &serials, next) { char id; if (uuid_equal((uuid_t *)port->guid, (uuid_t *)&gEfiIsaIoProtocolGuid, NULL) == 0) { continue; } tty = calloc(1, sizeof (*tty)); if (tty == NULL) { /* Out of memory?! */ continue; } switch (port->ioaddr) { case 0: /* bad ioaddr */ continue; case COM1_IOADDR: id = 'a'; break; case COM2_IOADDR: id = 'b'; break; case COM3_IOADDR: id = 'c'; break; case COM4_IOADDR: id = 'd'; break; default: /* * We should not see this happening, but assigning * this id would let us help to identify unexpected * configuration. */ id = '0'; } /* Set up serial device descriptor */ (void) asprintf(&tty->c_name, "tty%c", id); (void) asprintf(&tty->c_desc, "serial port %c", id); tty->c_flags = C_PRESENTIN | C_PRESENTOUT; tty->c_probe = efi_isa_probe; tty->c_init = efi_isa_init; tty->c_out = efi_isa_putchar; tty->c_in = efi_isa_getchar; tty->c_ready = efi_isa_ischar; tty->c_ioctl = efi_isa_ioctl; tty->c_devinfo = efi_isa_devinfo; tty->c_private = port; consoles[c++] = tty; /* Reset terminal to initial normal settings with ESC [ 0 m */ efi_isa_putchar(tty, 0x1b); efi_isa_putchar(tty, '['); efi_isa_putchar(tty, '0'); efi_isa_putchar(tty, 'm'); /* drain input from random data */ while (efi_isa_getchar(tty) != -1) ; } consoles[c] = NULL; } static EFI_STATUS efi_isa_getspeed(struct serial *sp) { EFI_STATUS status; uint_t divisor; uchar_t dlbh; uchar_t dlbl; uchar_t cfcr; uchar_t c; status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_cfcr, 1, &cfcr); if (EFI_ERROR(status)) return (status); c = CFCR_DLAB | cfcr; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_cfcr, 1, &c); if (EFI_ERROR(status)) return (status); status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_dlbl, 1, &dlbl); if (EFI_ERROR(status)) return (status); status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_dlbh, 1, &dlbh); if (EFI_ERROR(status)) return (status); status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_cfcr, 1, &cfcr); if (EFI_ERROR(status)) return (status); divisor = dlbh << 8 | dlbl; if (divisor == 0) return (EFI_DEVICE_ERROR); sp->baudrate = COMC_DIV2BPS(divisor); return (EFI_SUCCESS); } static void efi_isa_probe(struct console *cp) { struct serial *sp = cp->c_private; EFI_STATUS status; uint8_t lcr; if (!efi_isa_port_is_present(sp)) { return; } status = efi_isa_getspeed(sp); if (EFI_ERROR(status)) { /* Use fallback value. */ sp->baudrate = COMSPEED; } status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_lcr, 1, &lcr); if (EFI_ERROR(status)) { return; } sp->databits = (lcr & BITS8) == BITS8? 8:7; sp->stopbits = (lcr & STOP2) == STOP2? TwoStopBits:OneStopBit; if ((lcr & (PAREN|PAREVN)) == (PAREN|PAREVN)) sp->parity = EvenParity; else if ((lcr & PAREN) == PAREN) sp->parity = OddParity; else sp->parity = NoParity; /* check if we are listed in ConIn */ efi_check_and_set_condev(sp, "ConIn"); efi_isa_setup_env(cp); if (!efi_isa_setup(cp)) printf("Failed to set up %s\n", cp->c_name); } static int efi_isa_init(struct console *cp, int arg __unused) { if (efi_isa_setup(cp)) return (CMD_OK); cp->c_flags = 0; return (CMD_ERROR); } static void efi_isa_putchar(struct console *cp, int c) { int wait; EFI_STATUS status; UINTN bufsz = 1; char control, cb = c; struct serial *sp = cp->c_private; for (wait = COMC_TXWAIT; wait > 0; wait--) { status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_lsr, bufsz, &control); if (EFI_ERROR(status)) continue; if ((control & LSR_TXRDY) != LSR_TXRDY) continue; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_data, bufsz, &cb); if (status != EFI_TIMEOUT) break; } } static int efi_isa_getchar(struct console *cp) { EFI_STATUS status; UINTN bufsz = 1; char c; struct serial *sp = cp->c_private; /* * if this device is also used as ConIn, some firmwares * fail to return all input via SIO protocol. */ if (sp->is_efi_console) { return (efi_console.c_in(&efi_console)); } if (!efi_isa_ischar(cp)) return (-1); status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_data, bufsz, &c); if (EFI_ERROR(status)) return (-1); return (c); } static int efi_isa_ischar(struct console *cp) { EFI_STATUS status; uint8_t control; struct serial *sp = cp->c_private; /* * if this device is also used as ConIn, some firmwares * fail to return all input via SIO protocol. */ if (sp->is_efi_console) { return (efi_console.c_ready(&efi_console)); } status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_lsr, 1, &control); if (EFI_ERROR(status)) return (0); return (control & LSR_RXRDY); } static int efi_isa_ioctl(struct console *cp __unused, int cmd __unused, void *data __unused) { return (ENOTTY); } static void efi_isa_devinfo(struct console *cp) { struct serial *port = cp->c_private; EFI_DEVICE_PATH *dp; CHAR16 *text; if (port->currdev != NULL) { dp = efi_lookup_devpath(port->currdev); if (dp == NULL) return; text = efi_devpath_name(dp); if (text == NULL) return; printf("\tISA IO device %S", text); efi_free_devpath_name(text); efi_close_devpath(port->currdev); return; } if (port->ioaddr != 0) { printf("\tISA IO port %#x", port->ioaddr); } } static char * efi_isa_asprint_mode(struct serial *sp) { char par, *buf, *stop; if (sp == NULL) return (NULL); switch (sp->parity) { case NoParity: par = 'n'; break; case EvenParity: par = 'e'; break; case OddParity: par = 'o'; break; case MarkParity: par = 'm'; break; case SpaceParity: par = 's'; break; default: par = 'n'; break; } switch (sp->stopbits) { case OneStopBit: stop = "1"; break; case TwoStopBits: stop = "2"; break; case OneFiveStopBits: stop = "1.5"; break; default: stop = "1"; break; } (void) asprintf(&buf, "%ju,%d,%c,%s,-", sp->baudrate, sp->databits, par, stop); return (buf); } static int efi_isa_parse_mode(struct serial *sp, const char *value) { unsigned long n; uint64_t baudrate; uint8_t databits; EFI_PARITY_TYPE parity; EFI_STOP_BITS_TYPE stopbits; char *ep; if (value == NULL || *value == '\0') return (CMD_ERROR); errno = 0; n = strtoul(value, &ep, 10); if (errno != 0 || *ep != ',') return (CMD_ERROR); baudrate = n; ep++; n = strtoul(ep, &ep, 10); if (errno != 0 || *ep != ',') return (CMD_ERROR); switch (n) { case 5: databits = 5; break; case 6: databits = 6; break; case 7: databits = 7; break; case 8: databits = 8; break; default: return (CMD_ERROR); } ep++; switch (*ep++) { case 'n': parity = NoParity; break; case 'e': parity = EvenParity; break; case 'o': parity = OddParity; break; default: return (CMD_ERROR); } if (*ep == ',') ep++; else return (CMD_ERROR); switch (*ep++) { case '1': stopbits = OneStopBit; break; case '2': stopbits = TwoStopBits; break; default: return (CMD_ERROR); } /* handshake is ignored, but we check syntax anyhow */ if (*ep == ',') ep++; else return (CMD_ERROR); switch (*ep++) { case '-': case 'h': case 's': break; default: return (CMD_ERROR); } if (*ep != '\0') return (CMD_ERROR); sp->baudrate = baudrate; sp->databits = databits; sp->parity = parity; sp->stopbits = stopbits; return (CMD_OK); } /* * CMD_ERROR will cause set/setenv/setprop command to fail, * when used in loader scripts (forth), this will cause processing * of boot scripts to fail, rendering bootloading impossible. * To prevent such unfortunate situation, we return CMD_OK when * there is no such port, or there is invalid value in mode line. */ static int efi_isa_mode_set(struct env_var *ev, int flags, const void *value) { struct console *cp; char name[15]; if (value == NULL) return (CMD_ERROR); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_OK); /* Do not override serial setup if port is listed in ConIn */ (void) snprintf(name, sizeof (name), "%s-spcr-mode", cp->c_name); if (getenv(name) == NULL) { if (efi_isa_parse_mode(cp->c_private, value) == CMD_ERROR) { printf("%s: invalid mode: %s\n", ev->ev_name, (char *)value); return (CMD_OK); } (void) efi_isa_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); } return (CMD_OK); } /* * CMD_ERROR will cause set/setenv/setprop command to fail, * when used in loader scripts (forth), this will cause processing * of boot scripts to fail, rendering bootloading impossible. * To prevent such unfortunate situation, we return CMD_OK when * there is no such port or invalid value was used. */ static int efi_isa_cd_set(struct env_var *ev, int flags, const void *value) { struct console *cp; struct serial *sp; if (value == NULL) return (CMD_OK); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_OK); sp = cp->c_private; if (strcmp(value, "true") == 0) { sp->ignore_cd = 1; } else if (strcmp(value, "false") == 0) { sp->ignore_cd = 0; } else { printf("%s: invalid value: %s\n", ev->ev_name, (char *)value); return (CMD_OK); } (void) efi_isa_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } /* * CMD_ERROR will cause set/setenv/setprop command to fail, * when used in loader scripts (forth), this will cause processing * of boot scripts to fail, rendering bootloading impossible. * To prevent such unfortunate situation, we return CMD_OK when * there is no such port, or invalid value was used. */ static int efi_isa_rtsdtr_set(struct env_var *ev, int flags, const void *value) { struct console *cp; struct serial *sp; if (value == NULL) return (CMD_OK); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_OK); sp = cp->c_private; if (strcmp(value, "true") == 0) { sp->rtsdtr_off = 1; } else if (strcmp(value, "false") == 0) { sp->rtsdtr_off = 0; } else { printf("%s: invalid value: %s\n", ev->ev_name, (char *)value); return (CMD_OK); } (void) efi_isa_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } /* * In case of error, we also reset ACTIVE flags, so the console * framefork will try alternate consoles. */ static bool efi_isa_setup(struct console *cp) { EFI_STATUS status; uint8_t data, lcr; struct serial *sp = cp->c_private; uint_t tries, try_count = 1000000; if (sp->baudrate == 0) return (false); switch (sp->databits) { case 8: lcr = BITS8; break; case 7: lcr = BITS7; break; case 6: lcr = BITS6; break; case 5: lcr = BITS5; break; default: lcr = BITS8; break; } switch (sp->parity) { case NoParity: break; case OddParity: lcr |= PAREN|PARODD; break; case EvenParity: lcr |= PAREN|PAREVN; break; default: break; } switch (sp->stopbits) { case OneStopBit: break; case TwoStopBits: lcr |= STOP2; break; default: break; } data = CFCR_DLAB | lcr; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_cfcr, 1, &data); if (EFI_ERROR(status)) return (false); data = COMC_BPS(sp->baudrate) & 0xff; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_dlbl, 1, &data); if (EFI_ERROR(status)) return (false); data = COMC_BPS(sp->baudrate) >> 8; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_dlbh, 1, &data); if (EFI_ERROR(status)) return (false); status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_cfcr, 1, &lcr); if (EFI_ERROR(status)) return (false); data = sp->rtsdtr_off? ~(MCR_RTS | MCR_DTR) : MCR_RTS | MCR_DTR; status = sp->io.isa->Io.Write(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_mcr, 1, &data); if (EFI_ERROR(status)) return (false); tries = 0; do { status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_data, 1, &data); status = sp->io.isa->Io.Read(sp->io.isa, EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT, sp->ioaddr + com_lsr, 1, &data); } while (data & LSR_RXRDY && ++tries < try_count); if (tries == try_count) return (false); /* Mark this port usable. */ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); return (true); } /* * Copyright (c) 2001 Doug Rabson * Copyright (c) 2002, 2006 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include EFI_GUID gEfiArpProtocolGuid = EFI_ARP_PROTOCOL_GUID; EFI_GUID gEfiArpServiceBindingProtocolGuid = EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiSimpleNetworkProtocolGuid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; EFI_GUID gEfiVlanConfigProtocolGuid = EFI_VLAN_CONFIG_PROTOCOL_GUID; static void efinet_end(struct netif *); static ssize_t efinet_get(struct iodesc *, void **, time_t); static void efinet_init(struct iodesc *, void *); static int efinet_match(struct netif *, void *); static int efinet_probe(struct netif *, void *); static ssize_t efinet_put(struct iodesc *, void *, size_t); struct netif_driver efinetif = { .netif_bname = "efinet", .netif_match = efinet_match, .netif_probe = efinet_probe, .netif_init = efinet_init, .netif_get = efinet_get, .netif_put = efinet_put, .netif_end = efinet_end, .netif_ifs = NULL, .netif_nifs = 0 }; #ifdef EFINET_DEBUG static void dump_mode(EFI_SIMPLE_NETWORK_MODE *mode) { int i; printf("State = %x\n", mode->State); printf("HwAddressSize = %u\n", mode->HwAddressSize); printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize); printf("MaxPacketSize = %u\n", mode->MaxPacketSize); printf("NvRamSize = %u\n", mode->NvRamSize); printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize); printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask); printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting); printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount); printf("MCastFilterCount = %u\n", mode->MCastFilterCount); printf("MCastFilter = {"); for (i = 0; i < mode->MCastFilterCount; i++) printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr)); printf(" }\n"); printf("CurrentAddress = %s\n", ether_sprintf(mode->CurrentAddress.Addr)); printf("BroadcastAddress = %s\n", ether_sprintf(mode->BroadcastAddress.Addr)); printf("PermanentAddress = %s\n", ether_sprintf(mode->PermanentAddress.Addr)); printf("IfType = %u\n", mode->IfType); printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable); printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported); printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported); printf("MediaPresent = %d\n", mode->MediaPresent); } #endif static int efinet_match(struct netif *nif, void *machdep_hint) { struct devdesc *dev = machdep_hint; if (dev->d_unit == nif->nif_unit) return (1); return (0); } static int efinet_probe(struct netif *nif, void *machdep_hint __unused) { EFI_SIMPLE_NETWORK *net; EFI_HANDLE h; EFI_STATUS status; h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; /* * Open the network device in exclusive mode. Without this * we will be racing with the UEFI network stack. It will * pull packets off the network leading to lost packets. */ status = BS->OpenProtocol(h, &gEfiSimpleNetworkProtocolGuid, (void **)&net, IH, NULL, EFI_OPEN_PROTOCOL_EXCLUSIVE); if (status != EFI_SUCCESS) { printf("Unable to open network interface %d for " "exclusive access: %lu\n", nif->nif_unit, DECODE_ERROR(status)); } return (0); } static ssize_t efinet_put(struct iodesc *desc, void *pkt, size_t len) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_STATUS status; void *buf; net = nif->nif_devdata; if (net == NULL) return (-1); status = net->Transmit(net, 0, len, pkt, NULL, NULL, NULL); if (status != EFI_SUCCESS) return (-1); /* Wait for the buffer to be transmitted */ do { buf = NULL; /* XXX Is this needed? */ status = net->GetStatus(net, NULL, &buf); /* * XXX EFI1.1 and the E1000 card returns a different * address than we gave. Sigh. */ } while (status == EFI_SUCCESS && buf == NULL); /* XXX How do we deal with status != EFI_SUCCESS now? */ return ((status == EFI_SUCCESS) ? len : -1); } static ssize_t efinet_get(struct iodesc *desc, void **pkt, time_t timeout) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_STATUS status; UINTN bufsz; time_t t; char *buf, *ptr; ssize_t ret = -1; net = nif->nif_devdata; if (net == NULL) return (ret); bufsz = net->Mode->MaxPacketSize + ETHER_HDR_LEN + ETHER_CRC_LEN; buf = malloc(bufsz + ETHER_ALIGN); if (buf == NULL) return (ret); ptr = buf + ETHER_ALIGN; t = getsecs(); while ((getsecs() - t) < timeout) { status = net->Receive(net, NULL, &bufsz, ptr, NULL, NULL, NULL); if (status == EFI_SUCCESS) { *pkt = buf; ret = (ssize_t)bufsz; break; } if (status != EFI_NOT_READY) break; } if (ret == -1) free(buf); return (ret); } static void efinet_init(struct iodesc *desc, void *machdep_hint __unused) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_HANDLE h; EFI_STATUS status; UINT32 mask; if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) { printf("Invalid network interface %d\n", nif->nif_unit); return; } h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; status = OpenProtocolByHandle(h, &gEfiSimpleNetworkProtocolGuid, (void **)&nif->nif_devdata); if (status != EFI_SUCCESS) { printf("net%d: cannot fetch interface data (status=%lu)\n", nif->nif_unit, DECODE_ERROR(status)); return; } net = nif->nif_devdata; if (net->Mode->State == EfiSimpleNetworkStopped) { status = net->Start(net); if (status != EFI_SUCCESS) { printf("net%d: cannot start interface (status=%lu)\n", nif->nif_unit, DECODE_ERROR(status)); return; } } if (net->Mode->State != EfiSimpleNetworkInitialized) { status = net->Initialize(net, 0, 0); if (status != EFI_SUCCESS) { printf("net%d: cannot init. interface (status=%lu)\n", nif->nif_unit, DECODE_ERROR(status)); return; } } mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; status = net->ReceiveFilters(net, mask, 0, FALSE, 0, NULL); if (status != EFI_SUCCESS) printf("net%d: cannot set rx. filters (status=%lu)\n", nif->nif_unit, DECODE_ERROR(status)); #ifdef EFINET_DEBUG dump_mode(net->Mode); #endif bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6); desc->xid = 1; } static void efinet_end(struct netif *nif) { EFI_SIMPLE_NETWORK *net = nif->nif_devdata; if (net == NULL) return; net->Shutdown(net); } static int efinet_dev_init(void); static int efinet_dev_print(int); struct devsw efinet_dev = { .dv_name = "net", .dv_type = DEVT_NET, .dv_init = efinet_dev_init, .dv_strategy = NULL, /* Will be set in efinet_dev_init */ .dv_open = NULL, /* Will be set in efinet_dev_init */ .dv_close = NULL, /* Will be set in efinet_dev_init */ .dv_ioctl = noioctl, .dv_print = efinet_dev_print, .dv_cleanup = NULL }; static int efinet_dev_init(void) { struct netif_dif *dif; struct netif_stats *stats; EFI_DEVICE_PATH *devpath, *node; EFI_HANDLE *handles, *handles2; EFI_STATUS status; uint_t i, nhandles, nifs; int err; extern struct devsw netdev; status = efi_get_protocol_handles(&gEfiSimpleNetworkProtocolGuid, &nhandles, &handles); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); handles2 = (EFI_HANDLE *)malloc(nhandles * sizeof (EFI_HANDLE)); if (handles2 == NULL) { free(handles); return (ENOMEM); } nifs = 0; for (i = 0; i < nhandles; i++) { devpath = efi_lookup_devpath(handles[i]); if (devpath == NULL) continue; if ((node = efi_devpath_last_node(devpath)) == NULL) continue; if (DevicePathType(node) != MESSAGING_DEVICE_PATH || DevicePathSubType(node) != MSG_MAC_ADDR_DP) continue; handles2[nifs] = handles[i]; nifs++; } free(handles); if (nifs == 0) { err = ENOENT; goto done; } err = efi_register_handles(&efinet_dev, handles2, NULL, nifs); if (err != 0) goto done; efinetif.netif_ifs = calloc(nifs, sizeof (struct netif_dif)); stats = calloc(nifs, sizeof (struct netif_stats)); if (efinetif.netif_ifs == NULL || stats == NULL) { free(efinetif.netif_ifs); free(stats); efinetif.netif_ifs = NULL; err = ENOMEM; goto done; } efinetif.netif_nifs = nifs; for (i = 0; i < nifs; i++) { dif = &efinetif.netif_ifs[i]; dif->dif_unit = i; dif->dif_nsel = 1; dif->dif_stats = &stats[i]; dif->dif_private = handles2[i]; } efinet_dev.dv_open = netdev.dv_open; efinet_dev.dv_close = netdev.dv_close; efinet_dev.dv_strategy = netdev.dv_strategy; done: free(handles2); return (err); } static int efinet_dev_print(int verbose) { CHAR16 *text; EFI_HANDLE h; int unit, ret = 0; printf("%s devices:", efinet_dev.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); for (unit = 0, h = efi_find_handle(&efinet_dev, 0); h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) { printf(" %s%d:", efinet_dev.dv_name, unit); if (verbose) { text = efi_devpath_name(efi_lookup_devpath(h)); if (text != NULL) { printf(" %S", text); efi_free_devpath_name(text); } } if ((ret = pager_output("\n")) != 0) break; } return (ret); } /* * Copyright (c) 2010 Marcel Moolenaar * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID; EFI_GUID gEfiBlockIo2ProtocolGuid = EFI_BLOCK_IO2_PROTOCOL_GUID; typedef bool (*pd_test_cb_t)(pdinfo_t *, pdinfo_t *); static int efipart_initfd(void); static int efipart_initcd(void); static int efipart_inithd(void); static void efipart_cdinfo_add(pdinfo_t *); static int efipart_strategy(void *, int, daddr_t, size_t, char *, size_t *); static int efipart_realstrategy(void *, int, daddr_t, size_t, char *, size_t *); static int efipart_open(struct open_file *, ...); static int efipart_close(struct open_file *); static int efipart_ioctl(struct open_file *, unsigned long, void *); static int efipart_printfd(int); static int efipart_printcd(int); static int efipart_printhd(int); /* EISA PNP ID's for floppy controllers */ #define PNP0604 0x604 #define PNP0700 0x700 #define PNP0701 0x701 /* Bounce buffer max size */ #define BIO_BUFFER_SIZE 0x4000 struct devsw efipart_fddev = { .dv_name = "fd", .dv_type = DEVT_FD, .dv_init = efipart_initfd, .dv_strategy = efipart_strategy, .dv_open = efipart_open, .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printfd, .dv_cleanup = NULL }; struct devsw efipart_cddev = { .dv_name = "cd", .dv_type = DEVT_CD, .dv_init = efipart_initcd, .dv_strategy = efipart_strategy, .dv_open = efipart_open, .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printcd, .dv_cleanup = NULL }; struct devsw efipart_hddev = { .dv_name = "disk", .dv_type = DEVT_DISK, .dv_init = efipart_inithd, .dv_strategy = efipart_strategy, .dv_open = efipart_open, .dv_close = efipart_close, .dv_ioctl = efipart_ioctl, .dv_print = efipart_printhd, .dv_cleanup = NULL }; static pdinfo_list_t fdinfo = STAILQ_HEAD_INITIALIZER(fdinfo); static pdinfo_list_t cdinfo = STAILQ_HEAD_INITIALIZER(cdinfo); static pdinfo_list_t hdinfo = STAILQ_HEAD_INITIALIZER(hdinfo); /* * efipart_inithandles() is used to build up the pdinfo list from * block device handles. Then each devsw init callback is used to * pick items from pdinfo and move to proper device list. * In ideal world, we should end up with empty pdinfo once all * devsw initializers are called. */ static pdinfo_list_t pdinfo = STAILQ_HEAD_INITIALIZER(pdinfo); pdinfo_list_t * efiblk_get_pdinfo_list(struct devsw *dev) { if (dev->dv_type == DEVT_DISK) return (&hdinfo); if (dev->dv_type == DEVT_CD) return (&cdinfo); if (dev->dv_type == DEVT_FD) return (&fdinfo); return (NULL); } /* XXX this gets called way way too often, investigate */ pdinfo_t * efiblk_get_pdinfo(struct devdesc *dev) { pdinfo_list_t *pdi; pdinfo_t *pd = NULL; pdi = efiblk_get_pdinfo_list(dev->d_dev); if (pdi == NULL) return (pd); STAILQ_FOREACH(pd, pdi, pd_link) { if (pd->pd_unit == dev->d_unit) return (pd); } return (pd); } static bool same_handle(pdinfo_t *pd, EFI_HANDLE h) { return (pd->pd_handle == h || pd->pd_alias == h); } pdinfo_t * efiblk_get_pdinfo_by_handle(EFI_HANDLE h) { pdinfo_t *dp, *pp; /* * Check hard disks, then cd, then floppy */ STAILQ_FOREACH(dp, &hdinfo, pd_link) { if (same_handle(dp, h)) return (dp); STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { if (same_handle(pp, h)) return (pp); } } STAILQ_FOREACH(dp, &cdinfo, pd_link) { if (same_handle(dp, h)) return (dp); STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { if (same_handle(pp, h)) return (pp); } } STAILQ_FOREACH(dp, &fdinfo, pd_link) { if (same_handle(dp, h)) return (dp); } return (NULL); } static int efiblk_pdinfo_count(pdinfo_list_t *pdi) { pdinfo_t *pd; int i = 0; STAILQ_FOREACH(pd, pdi, pd_link) { i++; } return (i); } static pdinfo_t * efipart_find_parent(pdinfo_list_t *pdi, EFI_DEVICE_PATH *devpath) { pdinfo_t *pd; EFI_DEVICE_PATH *parent; /* We want to find direct parent */ parent = efi_devpath_trim(devpath); /* We should not get out of memory here but be careful. */ if (parent == NULL) return (NULL); STAILQ_FOREACH(pd, pdi, pd_link) { /* We must have exact match. */ if (efi_devpath_match(pd->pd_devpath, parent)) break; } free(parent); return (pd); } /* * Return true when we should ignore this device. */ static bool efipart_ignore_device(EFI_HANDLE h, EFI_BLOCK_IO *blkio, EFI_DEVICE_PATH *devpath) { EFI_DEVICE_PATH *node, *parent; /* * We assume the block size 512 or greater power of 2. * Also skip devices with block size > 64k (16 is max * ashift supported by zfs). * iPXE is known to insert stub BLOCK IO device with * BlockSize 1. */ if (blkio->Media->BlockSize < 512 || blkio->Media->BlockSize > (1 << 16) || !powerof2(blkio->Media->BlockSize)) { efi_close_devpath(h); return (true); } /* Allowed values are 0, 1 and power of 2. */ if (blkio->Media->IoAlign > 1 && !powerof2(blkio->Media->IoAlign)) { efi_close_devpath(h); return (true); } /* * With device tree setup: * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x1) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x2) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x3) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x3)/CDROM.. * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x3)/CDROM.. * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x4) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x5) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x6) * PciRoot(0x0)/Pci(0x14,0x0)/USB(0x5,0)/USB(0x2,0x0)/Unit(0x7) * * In above exmple only Unit(0x3) has media, all other nodes are * missing media and should not be used. * * No media does not always mean there is no device, but in above * case, we can not really assume there is any device. * Therefore, if this node is USB, or this node is Unit (LUN) and * direct parent is USB and we have no media, we will ignore this * device. * * Variation of the same situation, but with SCSI devices: * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x1) * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x2) * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x3) * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x3)/CD.. * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x3)/CD.. * PciRoot(0x0)/Pci(0x1a,0x0)/USB(0x1,0)/USB(0x3,0x0)/SCSI(0x0,0x4) * * Here above the SCSI luns 1,2 and 4 have no media. */ /* Do not ignore device with media. */ if (blkio->Media->MediaPresent) return (false); node = efi_devpath_last_node(devpath); if (node == NULL) return (false); /* USB without media present */ if (DevicePathType(node) == MESSAGING_DEVICE_PATH && DevicePathSubType(node) == MSG_USB_DP) { efi_close_devpath(h); return (true); } parent = efi_devpath_trim(devpath); if (parent != NULL) { bool parent_is_usb = false; node = efi_devpath_last_node(parent); if (node == NULL) { free(parent); return (false); } if (DevicePathType(node) == MESSAGING_DEVICE_PATH && DevicePathSubType(node) == MSG_USB_DP) parent_is_usb = true; free(parent); node = efi_devpath_last_node(devpath); if (node == NULL) return (false); if (parent_is_usb && DevicePathType(node) == MESSAGING_DEVICE_PATH) { /* * no media, parent is USB and devicepath is * LUN or SCSI. */ if (DevicePathSubType(node) == MSG_DEVICE_LOGICAL_UNIT_DP || DevicePathSubType(node) == MSG_SCSI_DP) { efi_close_devpath(h); return (true); } } } return (false); } int efipart_inithandles(void) { uint_t i, nin; EFI_HANDLE *hin; EFI_DEVICE_PATH *devpath; EFI_BLOCK_IO *blkio; EFI_STATUS status; pdinfo_t *pd; if (!STAILQ_EMPTY(&pdinfo)) return (0); status = efi_get_protocol_handles(&gEfiBlockIoProtocolGuid, &nin, &hin); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); #ifdef EFIPART_DEBUG printf("%s: Got %d BLOCK IO MEDIA handle(s)\n", __func__, nin); #endif for (i = 0; i < nin; i++) { /* * Get devpath and open protocol. * We should not get errors here */ if ((devpath = efi_lookup_devpath(hin[i])) == NULL) continue; status = OpenProtocolByHandle(hin[i], &gEfiBlockIoProtocolGuid, (void **)&blkio); if (EFI_ERROR(status)) { printf("error %lu\n", DECODE_ERROR(status)); continue; } if (efipart_ignore_device(hin[i], blkio, devpath)) continue; /* This is bad. */ if ((pd = calloc(1, sizeof (*pd))) == NULL) { printf("efipart_inithandles: Out of memory.\n"); free(hin); return (ENOMEM); } STAILQ_INIT(&pd->pd_part); pd->pd_handle = hin[i]; pd->pd_devpath = devpath; pd->pd_blkio = blkio; STAILQ_INSERT_TAIL(&pdinfo, pd, pd_link); } /* * Walk pdinfo and set parents based on device path. */ STAILQ_FOREACH(pd, &pdinfo, pd_link) { pd->pd_parent = efipart_find_parent(&pdinfo, pd->pd_devpath); } free(hin); return (0); } /* * Get node identified by pd_test() from plist. */ static pdinfo_t * efipart_get_pd(pdinfo_list_t *plist, pd_test_cb_t pd_test, pdinfo_t *data) { pdinfo_t *pd; STAILQ_FOREACH(pd, plist, pd_link) { if (pd_test(pd, data)) break; } return (pd); } static ACPI_HID_DEVICE_PATH * efipart_floppy(EFI_DEVICE_PATH *node) { ACPI_HID_DEVICE_PATH *acpi; if (DevicePathType(node) == ACPI_DEVICE_PATH && DevicePathSubType(node) == ACPI_DP) { acpi = (ACPI_HID_DEVICE_PATH *) node; if (acpi->HID == EISA_PNP_ID(PNP0604) || acpi->HID == EISA_PNP_ID(PNP0700) || acpi->HID == EISA_PNP_ID(PNP0701)) { return (acpi); } } return (NULL); } static bool efipart_testfd(pdinfo_t *fd, pdinfo_t *data __unused) { EFI_DEVICE_PATH *node; node = efi_devpath_last_node(fd->pd_devpath); if (node == NULL) return (false); if (efipart_floppy(node) != NULL) return (true); return (false); } static int efipart_initfd(void) { EFI_DEVICE_PATH *node; ACPI_HID_DEVICE_PATH *acpi; pdinfo_t *parent, *fd; while ((fd = efipart_get_pd(&pdinfo, efipart_testfd, NULL)) != NULL) { if ((node = efi_devpath_last_node(fd->pd_devpath)) == NULL) continue; if ((acpi = efipart_floppy(node)) == NULL) continue; STAILQ_REMOVE(&pdinfo, fd, pdinfo, pd_link); parent = fd->pd_parent; if (parent != NULL) { STAILQ_REMOVE(&pdinfo, parent, pdinfo, pd_link); parent->pd_alias = fd->pd_handle; parent->pd_unit = acpi->UID; free(fd); fd = parent; } else { fd->pd_unit = acpi->UID; } fd->pd_devsw = &efipart_fddev; STAILQ_INSERT_TAIL(&fdinfo, fd, pd_link); } bcache_add_dev(efiblk_pdinfo_count(&fdinfo)); return (0); } /* * Add or update entries with new handle data. */ static void efipart_cdinfo_add(pdinfo_t *cd) { pdinfo_t *parent, *pd, *last; if (cd == NULL) return; parent = cd->pd_parent; /* Make sure we have parent added */ efipart_cdinfo_add(parent); STAILQ_FOREACH(pd, &pdinfo, pd_link) { if (efi_devpath_match(pd->pd_devpath, cd->pd_devpath)) { STAILQ_REMOVE(&pdinfo, cd, pdinfo, pd_link); break; } } if (pd == NULL) { /* This device is already added. */ return; } if (parent != NULL) { last = STAILQ_LAST(&parent->pd_part, pdinfo, pd_link); if (last != NULL) cd->pd_unit = last->pd_unit + 1; else cd->pd_unit = 0; cd->pd_devsw = &efipart_cddev; STAILQ_INSERT_TAIL(&parent->pd_part, cd, pd_link); return; } last = STAILQ_LAST(&cdinfo, pdinfo, pd_link); if (last != NULL) cd->pd_unit = last->pd_unit + 1; else cd->pd_unit = 0; cd->pd_devsw = &efipart_cddev; STAILQ_INSERT_TAIL(&cdinfo, cd, pd_link); } static bool efipart_testcd(pdinfo_t *cd, pdinfo_t *data __unused) { EFI_DEVICE_PATH *node; node = efi_devpath_last_node(cd->pd_devpath); if (node == NULL) return (false); if (efipart_floppy(node) != NULL) return (false); if (DevicePathType(node) == MEDIA_DEVICE_PATH && DevicePathSubType(node) == MEDIA_CDROM_DP) { return (true); } /* cd drive without the media. */ if (cd->pd_blkio->Media->RemovableMedia && !cd->pd_blkio->Media->MediaPresent) { return (true); } return (false); } /* * Test if pd is parent for device. */ static bool efipart_testchild(pdinfo_t *dev, pdinfo_t *pd) { /* device with no parent. */ if (dev->pd_parent == NULL) return (false); if (efi_devpath_match(dev->pd_parent->pd_devpath, pd->pd_devpath)) { return (true); } return (false); } static int efipart_initcd(void) { pdinfo_t *cd; while ((cd = efipart_get_pd(&pdinfo, efipart_testcd, NULL)) != NULL) efipart_cdinfo_add(cd); /* Find all children of CD devices we did add above. */ STAILQ_FOREACH(cd, &cdinfo, pd_link) { pdinfo_t *child; for (child = efipart_get_pd(&pdinfo, efipart_testchild, cd); child != NULL; child = efipart_get_pd(&pdinfo, efipart_testchild, cd)) efipart_cdinfo_add(child); } bcache_add_dev(efiblk_pdinfo_count(&cdinfo)); return (0); } static void efipart_hdinfo_add_node(pdinfo_t *hd, EFI_DEVICE_PATH *node) { pdinfo_t *parent, *ptr; if (node == NULL) return; parent = hd->pd_parent; /* * If the node is not MEDIA_HARDDRIVE_DP, it is sub-partition. * This can happen with Vendor nodes, and since we do not know * the more about those nodes, we just count them. */ if (DevicePathSubType(node) != MEDIA_HARDDRIVE_DP) { ptr = STAILQ_LAST(&parent->pd_part, pdinfo, pd_link); if (ptr != NULL) hd->pd_unit = ptr->pd_unit + 1; else hd->pd_unit = 0; } else { hd->pd_unit = ((HARDDRIVE_DEVICE_PATH *)node)->PartitionNumber; } hd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&parent->pd_part, hd, pd_link); } /* * The MEDIA_FILEPATH_DP has device name. * From U-Boot sources it looks like names are in the form * of typeN:M, where type is interface type, N is disk id * and M is partition id. */ static void efipart_hdinfo_add_filepath(pdinfo_t *hd, FILEPATH_DEVICE_PATH *node) { char *pathname, *p; int len; pdinfo_t *last; last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) hd->pd_unit = last->pd_unit + 1; else hd->pd_unit = 0; /* FILEPATH_DEVICE_PATH has 0 terminated string */ len = ucs2len(node->PathName); if ((pathname = malloc(len + 1)) == NULL) { printf("Failed to add disk, out of memory\n"); free(hd); return; } cpy16to8(node->PathName, pathname, len + 1); p = strchr(pathname, ':'); /* * Assume we are receiving handles in order, first disk handle, * then partitions for this disk. If this assumption proves * false, this code would need update. */ if (p == NULL) { /* no colon, add the disk */ hd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); free(pathname); return; } p++; /* skip the colon */ errno = 0; hd->pd_unit = (int)strtol(p, NULL, 0); if (errno != 0) { printf("Bad unit number for partition \"%s\"\n", pathname); free(pathname); free(hd); return; } /* * We should have disk registered, if not, we are receiving * handles out of order, and this code should be reworked * to create "blank" disk for partition, and to find the * disk based on PathName compares. */ if (last == NULL) { printf("BUG: No disk for partition \"%s\"\n", pathname); free(pathname); free(hd); return; } /* Add the partition. */ hd->pd_parent = last; hd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&last->pd_part, hd, pd_link); free(pathname); } static void efipart_hdinfo_add(pdinfo_t *hd) { pdinfo_t *parent, *pd, *last; EFI_DEVICE_PATH *node; if (hd == NULL) return; parent = hd->pd_parent; /* Make sure we have parent added */ efipart_hdinfo_add(parent); STAILQ_FOREACH(pd, &pdinfo, pd_link) { if (efi_devpath_match(pd->pd_devpath, hd->pd_devpath)) { STAILQ_REMOVE(&pdinfo, hd, pdinfo, pd_link); break; } } if (pd == NULL) { /* This device is already added. */ return; } if ((node = efi_devpath_last_node(hd->pd_devpath)) == NULL) return; if (DevicePathType(node) == MEDIA_DEVICE_PATH && DevicePathSubType(node) == MEDIA_FILEPATH_DP) { efipart_hdinfo_add_filepath(hd, (FILEPATH_DEVICE_PATH *)node); return; } if (parent != NULL) { efipart_hdinfo_add_node(hd, node); return; } last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) hd->pd_unit = last->pd_unit + 1; else hd->pd_unit = 0; /* Add the disk. */ hd->pd_devsw = &efipart_hddev; STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link); } static bool efipart_testhd(pdinfo_t *hd, pdinfo_t *data __unused) { if (efipart_testfd(hd, NULL)) return (false); if (efipart_testcd(hd, NULL)) return (false); /* Anything else must be HD. */ return (true); } static int efipart_inithd(void) { pdinfo_t *hd; while ((hd = efipart_get_pd(&pdinfo, efipart_testhd, NULL)) != NULL) efipart_hdinfo_add(hd); bcache_add_dev(efiblk_pdinfo_count(&hdinfo)); return (0); } static int efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose) { int ret = 0; EFI_BLOCK_IO *blkio; EFI_STATUS status; EFI_HANDLE h; pdinfo_t *pd; CHAR16 *text; struct disk_devdesc pd_dev; char line[80]; if (STAILQ_EMPTY(pdlist)) return (0); printf("%s devices:", dev->dv_name); if ((ret = pager_output("\n")) != 0) return (ret); STAILQ_FOREACH(pd, pdlist, pd_link) { h = pd->pd_handle; if (verbose) { /* Output the device path. */ text = efi_devpath_name(efi_lookup_devpath(h)); if (text != NULL) { printf(" %S", text); efi_free_devpath_name(text); if ((ret = pager_output("\n")) != 0) break; } } snprintf(line, sizeof (line), " %s%d", dev->dv_name, pd->pd_unit); printf("%s:", line); status = OpenProtocolByHandle(h, &gEfiBlockIoProtocolGuid, (void **)&blkio); if (!EFI_ERROR(status)) { printf(" %llu", blkio->Media->LastBlock == 0? 0: (unsigned long long) (blkio->Media->LastBlock + 1)); if (blkio->Media->LastBlock != 0) { printf(" X %u", blkio->Media->BlockSize); } printf(" blocks"); if (blkio->Media->MediaPresent) { if (blkio->Media->RemovableMedia) printf(" (removable)"); } else { printf(" (no media)"); } if ((ret = pager_output("\n")) != 0) break; if (!blkio->Media->MediaPresent) continue; pd->pd_blkio = blkio; pd_dev.dd.d_dev = dev; pd_dev.dd.d_unit = pd->pd_unit; pd_dev.d_slice = D_SLICENONE; pd_dev.d_partition = D_PARTNONE; ret = disk_open(&pd_dev, blkio->Media->BlockSize * (blkio->Media->LastBlock + 1), blkio->Media->BlockSize); if (ret == 0) { ret = disk_print(&pd_dev, line, verbose); disk_close(&pd_dev); if (ret != 0) return (ret); } else { /* Do not fail from disk_open() */ ret = 0; } } else { if ((ret = pager_output("\n")) != 0) break; } } return (ret); } static int efipart_printfd(int verbose) { return (efipart_print_common(&efipart_fddev, &fdinfo, verbose)); } static int efipart_printcd(int verbose) { return (efipart_print_common(&efipart_cddev, &cdinfo, verbose)); } static int efipart_printhd(int verbose) { return (efipart_print_common(&efipart_hddev, &hdinfo, verbose)); } static int efipart_open(struct open_file *f, ...) { va_list args; struct disk_devdesc *dev; pdinfo_t *pd; EFI_BLOCK_IO *blkio; EFI_STATUS status; va_start(args, f); dev = va_arg(args, struct disk_devdesc *); va_end(args); if (dev == NULL) return (EINVAL); pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EIO); if (pd->pd_blkio == NULL) { status = OpenProtocolByHandle(pd->pd_handle, &gEfiBlockIoProtocolGuid, (void **)&pd->pd_blkio); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); } blkio = pd->pd_blkio; if (!blkio->Media->MediaPresent) return (EAGAIN); pd->pd_open++; if (pd->pd_bcache == NULL) pd->pd_bcache = bcache_allocate(); if (dev->dd.d_dev->dv_type == DEVT_DISK) { int rc; rc = disk_open(dev, blkio->Media->BlockSize * (blkio->Media->LastBlock + 1), blkio->Media->BlockSize); if (rc != 0) { pd->pd_open--; if (pd->pd_open == 0) { pd->pd_blkio = NULL; bcache_free(pd->pd_bcache); pd->pd_bcache = NULL; } } return (rc); } return (0); } static int efipart_close(struct open_file *f) { struct disk_devdesc *dev; pdinfo_t *pd; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); pd->pd_open--; if (pd->pd_open == 0) { pd->pd_blkio = NULL; if (dev->dd.d_dev->dv_type != DEVT_DISK) { bcache_free(pd->pd_bcache); pd->pd_bcache = NULL; } } if (dev->dd.d_dev->dv_type == DEVT_DISK) return (disk_close(dev)); return (0); } static int efipart_ioctl(struct open_file *f, unsigned long cmd, void *data) { struct disk_devdesc *dev; pdinfo_t *pd; int rc; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); if (dev->dd.d_dev->dv_type == DEVT_DISK) { rc = disk_ioctl(dev, cmd, data); if (rc != ENOTTY) return (rc); } switch (cmd) { case DIOCGSECTORSIZE: *(uint_t *)data = pd->pd_blkio->Media->BlockSize; break; case DIOCGMEDIASIZE: *(uint64_t *)data = pd->pd_blkio->Media->BlockSize * (pd->pd_blkio->Media->LastBlock + 1); break; default: return (ENOTTY); } return (0); } /* * efipart_readwrite() * Internal equivalent of efipart_strategy(), which operates on the * media-native block size. This function expects all I/O requests * to be within the media size and returns an error if such is not * the case. */ static int efipart_readwrite(pdinfo_t *pd, int rw, daddr_t blk, daddr_t nblks, char *buf) { EFI_STATUS status; EFI_BLOCK_IO *blkio = pd->pd_blkio; if (blkio == NULL) return (ENXIO); if (blk < 0 || blk > blkio->Media->LastBlock) return (EIO); if ((blk + nblks - 1) > blkio->Media->LastBlock) return (EIO); switch (rw & F_MASK) { case F_READ: status = blkio->ReadBlocks(blkio, blkio->Media->MediaId, blk, nblks * blkio->Media->BlockSize, buf); break; case F_WRITE: if (blkio->Media->ReadOnly) return (EROFS); status = blkio->WriteBlocks(blkio, blkio->Media->MediaId, blk, nblks * blkio->Media->BlockSize, buf); break; default: return (ENOSYS); } if (EFI_ERROR(status)) { CHAR16 *pathname; pathname = efi_devpath_name(pd->pd_devpath); if (pathname != NULL) { printf("%S: ", pathname); efi_free_devpath_name(pathname); } printf("%s error: blk=%ju size=%ju status=%lu\n", (rw & F_MASK) == F_READ ? "read" : "write", blk, nblks, DECODE_ERROR(status)); } return (efi_status_to_errno(status)); } static int efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct bcache_devdata bcd; struct disk_devdesc *dev; pdinfo_t *pd; dev = (struct disk_devdesc *)devdata; if (dev == NULL) return (EINVAL); pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); if (pd->pd_blkio->Media->RemovableMedia && !pd->pd_blkio->Media->MediaPresent) return (ENXIO); bcd.dv_strategy = efipart_realstrategy; bcd.dv_devdata = devdata; bcd.dv_cache = pd->pd_bcache; if (dev->dd.d_dev->dv_type == DEVT_DISK) { daddr_t offset; offset = dev->d_offset * pd->pd_blkio->Media->BlockSize; offset /= 512; return (bcache_strategy(&bcd, rw, blk + offset, size, buf, rsize)); } return (bcache_strategy(&bcd, rw, blk, size, buf, rsize)); } static int efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { struct disk_devdesc *dev = (struct disk_devdesc *)devdata; pdinfo_t *pd; EFI_BLOCK_IO *blkio; uint64_t off, disk_blocks, d_offset = 0; char *blkbuf; size_t blkoff, blksz, bio_size; unsigned ioalign; bool need_buf; int rc; uint64_t diskend, readstart; if (dev == NULL || blk < 0) return (EINVAL); pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); blkio = pd->pd_blkio; if (blkio == NULL) return (ENXIO); if (size == 0 || (size % 512) != 0) return (EIO); off = blk * 512; /* * Get disk blocks, this value is either for whole disk or for * partition. */ disk_blocks = 0; if (dev->dd.d_dev->dv_type == DEVT_DISK) { if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { /* DIOCGMEDIASIZE does return bytes. */ disk_blocks /= blkio->Media->BlockSize; } d_offset = dev->d_offset; } if (disk_blocks == 0) disk_blocks = blkio->Media->LastBlock + 1 - d_offset; /* make sure we don't read past disk end */ if ((off + size) / blkio->Media->BlockSize > d_offset + disk_blocks) { diskend = d_offset + disk_blocks; readstart = off / blkio->Media->BlockSize; if (diskend <= readstart) { if (rsize != NULL) *rsize = 0; return (EIO); } size = diskend - readstart; size = size * blkio->Media->BlockSize; } need_buf = true; /* Do we need bounce buffer? */ if ((size % blkio->Media->BlockSize == 0) && (off % blkio->Media->BlockSize == 0)) need_buf = false; /* Do we have IO alignment requirement? */ ioalign = blkio->Media->IoAlign; if (ioalign == 0) ioalign++; if (ioalign > 1 && (uintptr_t)buf != roundup2((uintptr_t)buf, ioalign)) need_buf = true; if (need_buf) { for (bio_size = BIO_BUFFER_SIZE; bio_size > 0; bio_size -= blkio->Media->BlockSize) { blkbuf = memalign(ioalign, bio_size); if (blkbuf != NULL) break; } } else { blkbuf = buf; bio_size = size; } if (blkbuf == NULL) return (ENOMEM); if (rsize != NULL) *rsize = size; rc = 0; blk = off / blkio->Media->BlockSize; blkoff = off % blkio->Media->BlockSize; while (size > 0) { size_t x = min(size, bio_size); if (x < blkio->Media->BlockSize) x = 1; else x /= blkio->Media->BlockSize; switch (rw & F_MASK) { case F_READ: blksz = blkio->Media->BlockSize * x - blkoff; if (size < blksz) blksz = size; rc = efipart_readwrite(pd, rw, blk, x, blkbuf); if (rc != 0) goto error; if (need_buf) bcopy(blkbuf + blkoff, buf, blksz); break; case F_WRITE: rc = 0; if (blkoff != 0) { /* * We got offset to sector, read 1 sector to * blkbuf. */ x = 1; blksz = blkio->Media->BlockSize - blkoff; blksz = min(blksz, size); rc = efipart_readwrite(pd, F_READ, blk, x, blkbuf); } else if (size < blkio->Media->BlockSize) { /* * The remaining block is not full * sector. Read 1 sector to blkbuf. */ x = 1; blksz = size; rc = efipart_readwrite(pd, F_READ, blk, x, blkbuf); } else { /* We can write full sector(s). */ blksz = blkio->Media->BlockSize * x; } if (rc != 0) goto error; /* * Put your Data In, Put your Data out, * Put your Data In, and shake it all about */ if (need_buf) bcopy(buf, blkbuf + blkoff, blksz); rc = efipart_readwrite(pd, F_WRITE, blk, x, blkbuf); if (rc != 0) goto error; break; default: /* DO NOTHING */ rc = EROFS; goto error; } blkoff = 0; buf += blksz; size -= blksz; blk += x; } error: if (rsize != NULL) *rsize -= size; if (need_buf) free(blkbuf); return (rc); } /* * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include EFI_GUID gEfiSerialIoProtocolGuid = SERIAL_IO_PROTOCOL; EFI_GUID gEfiSerialTerminalDeviceTypeGuid = \ EFI_SERIAL_TERMINAL_DEVICE_TYPE_GUID; EFI_GUID gEfiSioProtocolGuid = EFI_SIO_PROTOCOL_GUID; #define COMC_TXWAIT 0x40000 /* transmit timeout */ #define COM1_IOADDR 0x3f8 #define COM2_IOADDR 0x2f8 #define COM3_IOADDR 0x3e8 #define COM4_IOADDR 0x2e8 #define PNP0501 0x501 /* 16550A-compatible COM port */ /* List of serial ports, set up by efi_serial_ini() */ serial_list_t serials = STAILQ_HEAD_INITIALIZER(serials); static void efi_serial_probe(struct console *); static int efi_serial_init(struct console *, int); static void efi_serial_putchar(struct console *, int); static int efi_serial_getchar(struct console *); static int efi_serial_ischar(struct console *); static int efi_serial_ioctl(struct console *, int, void *); static void efi_serial_devinfo(struct console *); static bool efi_serial_setup(struct console *); static char *efi_serial_asprint_mode(struct serial *); static int efi_serial_parse_mode(struct serial *, const char *); static int efi_serial_mode_set(struct env_var *, int, const void *); static int efi_serial_cd_set(struct env_var *, int, const void *); static int efi_serial_rtsdtr_set(struct env_var *, int, const void *); extern struct console efi_console; static bool efi_serial_should_append(struct serial *port) { EFI_DEVICE_PATH *node, *dev; EFI_STATUS status; const char *name; char *buf; size_t sz; bool rv = true; if (port->currdev == NULL) return (rv); buf = NULL; sz = 0; name = "ConOut"; status = efi_global_getenv(name, buf, &sz); /* Some systems do not provide ConOut, also check ConIn */ if (EFI_ERROR(status) && status != EFI_BUFFER_TOO_SMALL) { name = "ConIn"; status = efi_global_getenv(name, buf, &sz); } if (status == EFI_BUFFER_TOO_SMALL) { buf = malloc(sz); if (buf == NULL) return (rv); status = efi_global_getenv(name, buf, &sz); } if (EFI_ERROR(status)) { free(buf); return (rv); } dev = efi_lookup_devpath(port->currdev); if (dev == NULL) { free(buf); return (rv); } node = (EFI_DEVICE_PATH *)buf; /* * We only need to know if this port is first in list. * This is only important when "os_console" is not set. */ if (!IsDevicePathEnd(node) && efi_devpath_is_prefix(dev, node)) rv = false; efi_close_devpath(port->currdev); free(buf); return (rv); } static void efi_serial_setup_env(struct console *tty) { struct serial *port = tty->c_private; char name[20]; char value[20]; char *env; (void) snprintf(name, sizeof (name), "%s-mode", tty->c_name); env = getenv(name); if (env != NULL) (void) efi_serial_parse_mode(port, env); env = efi_serial_asprint_mode(port); if (env != NULL) { (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, env, efi_serial_mode_set, env_nounset); if (port->is_efi_console) { (void) snprintf(name, sizeof (name), "%s-spcr-mode", tty->c_name); (void) setenv(name, env, 1); free(env); /* Add us to console list. */ (void) snprintf(name, sizeof (name), "console"); env = getenv(name); if (env == NULL) { (void) setenv(name, tty->c_name, 1); } else { char *ptr; int rv; /* * we have "text" already in place, * check if we need to add * serial console before or after. */ if (efi_serial_should_append(port)) rv = asprintf(&ptr, "%s,%s", env, tty->c_name); else rv = asprintf(&ptr, "%s,%s", tty->c_name, env); if (rv > 0) { (void) setenv(name, ptr, 1); free(ptr); } else { printf("%s: %s\n", __func__, strerror(ENOMEM)); } } } else { free(env); } } (void) snprintf(name, sizeof (name), "%s-ignore-cd", tty->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) port->ignore_cd = 1; else if (strcmp(env, "false") == 0) port->ignore_cd = 0; } (void) snprintf(value, sizeof (value), "%s", port->ignore_cd? "true" : "false"); (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, value, efi_serial_cd_set, env_nounset); (void) snprintf(name, sizeof (name), "%s-rts-dtr-off", tty->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) port->rtsdtr_off = 1; else if (strcmp(env, "false") == 0) port->rtsdtr_off = 0; } (void) snprintf(value, sizeof (value), "%s", port->rtsdtr_off? "true" : "false"); (void) unsetenv(name); (void) env_setenv(name, EV_VOLATILE, value, efi_serial_rtsdtr_set, env_nounset); } static void efi_check_and_set_condev(struct serial *port, const char *name) { EFI_DEVICE_PATH *node, *dev; EFI_STATUS status; char *buf; size_t sz; if (port->currdev == NULL) return; buf = NULL; sz = 0; status = efi_global_getenv(name, buf, &sz); if (status == EFI_BUFFER_TOO_SMALL) { buf = malloc(sz); if (buf == NULL) return; status = efi_global_getenv(name, buf, &sz); } if (EFI_ERROR(status)) { free(buf); return; } dev = efi_lookup_devpath(port->currdev); if (dev == NULL) { free(buf); return; } node = (EFI_DEVICE_PATH *)buf; while (!IsDevicePathEnd(node)) { /* Sanity check the node before moving to the next node. */ if (DevicePathNodeLength(node) < sizeof (*node)) break; if (efi_devpath_is_prefix(dev, node)) { port->is_efi_console = true; break; } node = efi_devpath_next_instance(node); } efi_close_devpath(port->currdev); free(buf); } /* * Get list of super io handles, get device path and check if this * sio device path is parent of serial io device. */ static EFI_STATUS efi_get_io_handle(EFI_HANDLE *handles, uint_t nhandles, EFI_DEVICE_PATH *dp, EFI_HANDLE *hp) { EFI_HANDLE h; EFI_DEVICE_PATH *parent; h = NULL; for (uint_t i = 0; i < nhandles; i++) { parent = efi_lookup_devpath(handles[i]); if (parent == NULL) continue; if (efi_devpath_is_prefix(parent, dp)) { h = handles[i]; efi_close_devpath(h); break; } efi_close_devpath(handles[i]); } if (h == NULL) return (EFI_NOT_FOUND); *hp = h; return (EFI_SUCCESS); } /* * Use this super io protocol instance to identify serial port. */ static EFI_STATUS efi_get_sio_serial_name(EFI_HANDLE handle, char *id) { EFI_STATUS status; EFI_SIO_PROTOCOL *sio; ACPI_RESOURCE_HEADER_PTR rl; EFI_ACPI_IO_PORT_DESCRIPTOR *io; EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *fixedio; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *as; UINT64 base_address = 0; char name; status = BS->OpenProtocol(handle, &gEfiSioProtocolGuid, (void **)&sio, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!EFI_ERROR(status)) { status = sio->GetResources(sio, &rl); (void) BS->CloseProtocol(handle, &gEfiSioProtocolGuid, IH, NULL); } if (EFI_ERROR(status)) { return (status); } while (rl.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR && base_address == 0) { switch (rl.SmallHeader->Byte) { case ACPI_IO_PORT_DESCRIPTOR: io = (EFI_ACPI_IO_PORT_DESCRIPTOR *)rl.SmallHeader; if (io->Length != 0) base_address = io->BaseAddressMin; break; case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR: fixedio = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) rl.SmallHeader; if (fixedio->Length != 0) base_address = fixedio->BaseAddress; break; case ACPI_ADDRESS_SPACE_DESCRIPTOR: as = (void *)rl.SmallHeader; if (as->AddrLen != 0) base_address = as->AddrRangeMin; break; } if (rl.SmallHeader->Bits.Type == 0) { rl.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *)rl.SmallHeader + rl.SmallHeader->Bits.Length + sizeof (rl.SmallHeader)); } else { rl.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *)rl.LargeHeader + rl.LargeHeader->Length + sizeof (rl.LargeHeader)); } } /* * On x86, we name COM1-COM4 as ttya-ttyd. */ switch (base_address) { case COM1_IOADDR: name = 'a'; break; case COM2_IOADDR: name = 'b'; break; case COM3_IOADDR: name = 'c'; break; case COM4_IOADDR: name = 'd'; break; default: return (EFI_NOT_FOUND); } *id = name; return (status); } /* * Use this ISA io protocol instance to identify serial port. */ static EFI_STATUS efi_get_isaio_serial_name(EFI_HANDLE handle, char *id) { EFI_STATUS status; EFI_ISA_IO_PROTOCOL *io; UINT32 StartRange = 0; char name; status = BS->OpenProtocol(handle, &gEfiIsaIoProtocolGuid, (void **)&io, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(status)) return (status); for (uint_t i = 0; io->ResourceList->ResourceItem[i].Type != EfiIsaAcpiResourceEndOfList; i++) { switch (io->ResourceList->ResourceItem[i].Type) { case EfiIsaAcpiResourceIo: StartRange = io->ResourceList->ResourceItem[i].StartRange; break; default: break; } } (void) BS->CloseProtocol(handle, &gEfiIsaIoProtocolGuid, IH, NULL); switch (StartRange) { case COM1_IOADDR: name = 'a'; break; case COM2_IOADDR: name = 'b'; break; case COM3_IOADDR: name = 'c'; break; case COM4_IOADDR: name = 'd'; break; default: return (EFI_NOT_FOUND); } *id = name; return (status); } /* * Return UID from ACPI_EXTENDED_HID_DEVICE_PATH. */ uint32_t efi_get_acpiex_uid(ACPI_EXTENDED_HID_DEVICE_PATH *acpiex) { char *_HIDSTR, *_UIDSTR; unsigned long tmp; char *end; _HIDSTR = (char *)acpiex + 16; _UIDSTR = _HIDSTR + strlen(_HIDSTR) + 1; if (*_UIDSTR != '\0') { errno = 0; tmp = strtoul(_UIDSTR, &end, 0); if (errno == 0) { return (tmp); } /* * in case of error, we have option to panic * or return UID. There is no screen output yet. */ } return (acpiex->UID); } /* * walk device path and check each node. * if node is ACPI dp for serial port, use UID to set name. */ static EFI_STATUS efi_get_acpi_name(EFI_DEVICE_PATH *dp, char *id) { ACPI_HID_DEVICE_PATH *acpi; ACPI_EXTENDED_HID_DEVICE_PATH *acpiex; EFI_STATUS status; char *_HIDSTR; status = EFI_NOT_FOUND; acpiex = NULL; _HIDSTR = NULL; while (!IsDevicePathEnd(dp)) { if (DevicePathType(dp) == ACPI_DEVICE_PATH) { acpi = (ACPI_HID_DEVICE_PATH *)dp; if (DevicePathSubType(dp) == ACPI_DP && acpi->HID == EISA_PNP_ID(PNP0501)) { *id = 'a' + acpi->UID; status = EFI_SUCCESS; break; } acpiex = (ACPI_EXTENDED_HID_DEVICE_PATH *)dp; /* * acpi extended structure may additionally have * _HIDSTR, _UIDSTR, _CIDSTR string data, * if present, they override HID, UID and CID * fields. Either HID or _HIDSTR must be present. */ _HIDSTR = (char *)dp + 16; /* * From note in ACPICA source (AcpiNsRepair_HID()), * there are many machines with ID starting with * asterisk. We use same approach here as in acpica. * Note: I have no idea if UEFI device path creation * already handles this, but lets play safe. */ if (*_HIDSTR == '*') _HIDSTR++; if (DevicePathSubType(dp) == ACPI_EXTENDED_DP && (acpiex->HID == EISA_PNP_ID(PNP0501) || acpiex->CID == EISA_PNP_ID(PNP0501) || strncmp(_HIDSTR, "UART", 4) == 0)) { *id = 'a' + efi_get_acpiex_uid(acpiex); status = EFI_SUCCESS; break; } } dp = NextDevicePathNode(dp); } return (status); } /* * SERIAL IO protocol is abstraction on top of actual device */ static void efi_set_serial_name(struct console *tty) { struct serial *p, *port = tty->c_private; EFI_DEVICE_PATH *dp; EFI_STATUS status; EFI_HANDLE *handles, handle; uint_t nhandles; dp = efi_lookup_devpath(port->currdev); if (dp != NULL) { /* Try to detect actual IO protocol */ status = efi_get_protocol_handles(&gEfiSioProtocolGuid, &nhandles, &handles); if (!EFI_ERROR(status)) { status = efi_get_io_handle(handles, nhandles, dp, &handle); free(handles); if (!EFI_ERROR(status)) { port->iodev = handle; status = efi_get_sio_serial_name(handle, &port->name); /* It is SIO serial device, we are done. */ goto done; } } status = efi_get_protocol_handles(&gEfiIsaIoProtocolGuid, &nhandles, &handles); if (!EFI_ERROR(status)) { status = efi_get_io_handle(handles, nhandles, dp, &handle); free(handles); if (!EFI_ERROR(status)) { port->iodev = handle; status = efi_get_isaio_serial_name(handle, &port->name); /* It is ISAIO serial device, we are done. */ goto done; } } /* * Still nothing? check, if we have ACPI device path. */ status = efi_get_acpi_name(dp, &port->name); done: if (EFI_ERROR(status)) { /* * We have serial port but unknown hw driver. * If we do not have serial ports registered, * start from ttya, otherwise from tty0. * Other option would be to do this only in case of * VenHw device path. */ if (STAILQ_EMPTY(&serials)) port->name = 'a'; else port->name = '0'; STAILQ_FOREACH(p, &serials, next) { if (p->name == port->name) port->name++; } } efi_close_devpath(port->currdev); } (void) asprintf(&tty->c_name, "tty%c", port->name); (void) asprintf(&tty->c_desc, "serial port %c", port->name); } static uint_t efi_serial_create_port(uint_t c, EFI_HANDLE handle) { struct console *tty; struct serial *port; EFI_STATUS status; tty = calloc(1, sizeof (*tty)); if (tty == NULL) { /* Out of memory?! can not continue */ consoles[c] = tty; return (c); } port = calloc(1, sizeof (*port)); if (port == NULL) { free(tty); consoles[c] = NULL; return (c); } /* Set up port descriptor */ port->currdev = handle; status = BS->OpenProtocol(handle, &gEfiSerialIoProtocolGuid, (void **)&port->io.sio, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(status)) { free(tty); free(port); consoles[c] = NULL; return (c); } port->guid = &gEfiSerialIoProtocolGuid; port->baudrate = port->io.sio->Mode->BaudRate; port->timeout = port->io.sio->Mode->Timeout; port->receivefifodepth = port->io.sio->Mode->ReceiveFifoDepth; port->databits = port->io.sio->Mode->DataBits; port->parity = port->io.sio->Mode->Parity; port->stopbits = port->io.sio->Mode->StopBits; port->ignore_cd = true; /* ignore cd */ port->rtsdtr_off = false; /* rts-dtr is on */ /* Set up serial device descriptor */ tty->c_private = port; efi_set_serial_name(tty); tty->c_flags = C_PRESENTIN | C_PRESENTOUT; tty->c_probe = efi_serial_probe; tty->c_init = efi_serial_init; tty->c_out = efi_serial_putchar; tty->c_in = efi_serial_getchar; tty->c_ready = efi_serial_ischar; tty->c_ioctl = efi_serial_ioctl; tty->c_devinfo = efi_serial_devinfo; STAILQ_INSERT_TAIL(&serials, port, next); consoles[c++] = tty; consoles[c] = NULL; /* Reset terminal to initial normal settings with ESC [ 0 m */ efi_serial_putchar(tty, 0x1b); efi_serial_putchar(tty, '['); efi_serial_putchar(tty, '0'); efi_serial_putchar(tty, 'm'); /* drain input from random data */ while (efi_serial_getchar(tty) != -1) ; /* check if we are listed in ConIn */ efi_check_and_set_condev(port, "ConIn"); efi_serial_setup_env(tty); return (c); } /* * Set up list of possible serial consoles. * This function is run very early, so we do not expect to * run out of memory, and on error, we can not print output. */ void efi_serial_ini(void) { EFI_STATUS status; EFI_HANDLE *handles; uint_t c, n, index, nhandles; struct console **tmp; status = efi_get_protocol_handles(&gEfiSerialIoProtocolGuid, &nhandles, &handles); if (EFI_ERROR(status)) return; if (nhandles == 0) return; n = nhandles; c = cons_array_size(); if (c == 0) n++; /* For NULL pointer */ tmp = realloc(consoles, (c + n) * sizeof (*consoles)); if (tmp == NULL) { free(handles); return; } consoles = tmp; if (c > 0) c--; for (index = 0; index < nhandles; index++) { c = efi_serial_create_port(c, handles[index]); } free(handles); } static void efi_serial_probe(struct console *cp) { cp->c_flags = C_PRESENTIN | C_PRESENTOUT; } static int efi_serial_init(struct console *cp, int arg __unused) { if (efi_serial_setup(cp)) return (CMD_OK); cp->c_flags = 0; return (CMD_ERROR); } static void efi_serial_putchar(struct console *cp, int c) { int wait; EFI_STATUS status; UINTN bufsz = 1; char cb = c; struct serial *sp = cp->c_private; if (sp->io.sio == NULL) return; for (wait = COMC_TXWAIT; wait > 0; wait--) { status = sp->io.sio->Write(sp->io.sio, &bufsz, &cb); if (status != EFI_TIMEOUT) break; } } static int efi_serial_getchar(struct console *cp) { EFI_STATUS status; UINTN bufsz = 1; char c; struct serial *sp = cp->c_private; /* * if this device is also used as ConIn, some firmwares * fail to return all input via SIO protocol. */ if (sp->is_efi_console) { return (efi_console.c_in(&efi_console)); } if (sp->io.sio == NULL || !efi_serial_ischar(cp)) return (-1); status = sp->io.sio->Read(sp->io.sio, &bufsz, &c); if (EFI_ERROR(status) || bufsz == 0) return (-1); return (c); } static int efi_serial_ischar(struct console *cp) { EFI_STATUS status; uint32_t control; struct serial *sp = cp->c_private; /* * if this device is also used as ConIn, some firmwares * fail to return all input via SIO protocol. */ if (sp->is_efi_console) { return (efi_console.c_ready(&efi_console)); } if (sp->io.sio == NULL) return (0); status = sp->io.sio->GetControl(sp->io.sio, &control); if (EFI_ERROR(status)) return (0); return (!(control & EFI_SERIAL_INPUT_BUFFER_EMPTY)); } static int efi_serial_ioctl(struct console *cp __unused, int cmd __unused, void *data __unused) { return (ENOTTY); } static void efi_serial_devinfo(struct console *cp) { struct serial *port = cp->c_private; EFI_DEVICE_PATH *dp; CHAR16 *text; if (port->currdev == NULL) { printf("\tdevice is not present"); return; } dp = efi_lookup_devpath(port->currdev); if (dp == NULL) return; text = efi_devpath_name(dp); if (text == NULL) return; printf("\t%S", text); efi_free_devpath_name(text); efi_close_devpath(port->currdev); } static char * efi_serial_asprint_mode(struct serial *sp) { char par, *buf; char *stop; if (sp == NULL) return (NULL); switch (sp->parity) { case NoParity: par = 'n'; break; case EvenParity: par = 'e'; break; case OddParity: par = 'o'; break; case MarkParity: par = 'm'; break; case SpaceParity: par = 's'; break; default: par = 'n'; break; } switch (sp->stopbits) { case OneStopBit: stop = "1"; break; case TwoStopBits: stop = "2"; break; case OneFiveStopBits: stop = "1.5"; break; default: stop = "1"; break; } (void) asprintf(&buf, "%ju,%d,%c,%s,-", sp->baudrate, sp->databits, par, stop); return (buf); } static int efi_serial_parse_mode(struct serial *sp, const char *value) { unsigned long n; uint64_t baudrate; uint8_t databits = 8; int parity = NoParity; int stopbits = OneStopBit; char *ep; if (value == NULL || *value == '\0') return (CMD_ERROR); errno = 0; n = strtoul(value, &ep, 10); if (errno != 0 || *ep != ',') return (CMD_ERROR); baudrate = n; ep++; n = strtoul(ep, &ep, 10); if (errno != 0 || *ep != ',') return (CMD_ERROR); switch (n) { case 5: databits = 5; break; case 6: databits = 6; break; case 7: databits = 7; break; case 8: databits = 8; break; default: return (CMD_ERROR); } ep++; switch (*ep++) { case 'n': parity = NoParity; break; case 'e': parity = EvenParity; break; case 'o': parity = OddParity; break; case 'm': parity = MarkParity; break; case 's': parity = SpaceParity; break; default: return (CMD_ERROR); } if (*ep == ',') ep++; else return (CMD_ERROR); switch (*ep++) { case '1': stopbits = OneStopBit; if (ep[0] == '.' && ep[1] == '5') { ep += 2; stopbits = OneFiveStopBits; } break; case '2': stopbits = TwoStopBits; break; default: return (CMD_ERROR); } /* handshake is ignored, but we check syntax anyhow */ if (*ep == ',') ep++; else return (CMD_ERROR); switch (*ep++) { case '-': case 'h': case 's': break; default: return (CMD_ERROR); } if (*ep != '\0') return (CMD_ERROR); sp->baudrate = baudrate; sp->databits = databits; sp->parity = parity; sp->stopbits = stopbits; return (CMD_OK); } static int efi_serial_mode_set(struct env_var *ev, int flags, const void *value) { struct console *cp; if (value == NULL) return (CMD_ERROR); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_ERROR); if (efi_serial_parse_mode(cp->c_private, value) == CMD_ERROR) return (CMD_ERROR); (void) efi_serial_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } static int efi_serial_cd_set(struct env_var *ev, int flags, const void *value) { struct console *cp; struct serial *sp; if (value == NULL) return (CMD_OK); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_OK); sp = cp->c_private; if (strcmp(value, "true") == 0) sp->ignore_cd = true; else if (strcmp(value, "false") == 0) sp->ignore_cd = false; else return (CMD_OK); (void) efi_serial_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } static int efi_serial_rtsdtr_set(struct env_var *ev, int flags, const void *value) { struct console *cp; struct serial *sp; if (value == NULL) return (CMD_OK); if ((cp = cons_get_console(ev->ev_name)) == NULL) return (CMD_OK); sp = cp->c_private; if (strcmp(value, "true") == 0) sp->rtsdtr_off = true; else if (strcmp(value, "false") == 0) sp->rtsdtr_off = false; else return (CMD_OK); (void) efi_serial_setup(cp); (void) env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); return (CMD_OK); } /* * In case of error, we also reset ACTIVE flags, so the console * framefork will try alternate consoles. */ static bool efi_serial_setup(struct console *cp) { EFI_STATUS status; UINT32 control, new_control; struct serial *sp = cp->c_private; uint64_t baudrate; uint32_t timeout, receivefifodepth, databits; EFI_PARITY_TYPE parity; EFI_STOP_BITS_TYPE stopbits; bool change = false; /* port is not usable */ if (sp->io.sio == NULL) return (false); if (sp->io.sio->Reset != NULL) { status = sp->io.sio->Reset(sp->io.sio); if (EFI_ERROR(status)) return (false); } if (sp->baudrate == sp->io.sio->Mode->BaudRate) { baudrate = 0; } else { baudrate = sp->baudrate; change = true; } if (sp->receivefifodepth == sp->io.sio->Mode->ReceiveFifoDepth) { receivefifodepth = 0; } else { receivefifodepth = sp->receivefifodepth; change = true; } if (sp->timeout == sp->io.sio->Mode->Timeout) { timeout = 0; } else { timeout = sp->timeout; change = true; } if (sp->parity == sp->io.sio->Mode->Parity) { parity = DefaultParity; } else { parity = sp->parity; change = true; } if (sp->databits == sp->io.sio->Mode->DataBits) { databits = 0; } else { databits = sp->databits; change = true; } if (sp->stopbits == sp->io.sio->Mode->StopBits) { stopbits = DefaultStopBits; } else { stopbits = sp->stopbits; change = true; } if (change && sp->io.sio->SetAttributes != NULL) { status = sp->io.sio->SetAttributes(sp->io.sio, baudrate, receivefifodepth, timeout, parity, databits, stopbits); if (EFI_ERROR(status)) return (false); } /* * Perform SetControl() only in case there was change in settings. */ control = new_control = 0; status = sp->io.sio->GetControl(sp->io.sio, &control); if (!EFI_ERROR(status)) { new_control = control; if (sp->rtsdtr_off) { new_control &= ~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY); } else { new_control |= EFI_SERIAL_REQUEST_TO_SEND; } } if (control != new_control) (void) sp->io.sio->SetControl(sp->io.sio, new_control); /* Mark this port usable. */ cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); return (true); } /* * Copyright (c) 2008-2010 Rui Paulo * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include #include #include #include #include #include #include #include "efizfs.h" static zfsinfo_list_t zfsinfo; uint64_t pool_guid; zfsinfo_list_t * efizfs_get_zfsinfo_list(void) { return (&zfsinfo); } EFI_HANDLE efizfs_get_handle_by_guid(uint64_t guid) { zfsinfo_t *zi; STAILQ_FOREACH(zi, &zfsinfo, zi_link) { if (zi->zi_pool_guid == guid) { return (zi->zi_handle); } } return (NULL); } bool efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid) { zfsinfo_t *zi; if (guid == NULL) return (false); STAILQ_FOREACH(zi, &zfsinfo, zi_link) { if (zi->zi_handle == handle) { *guid = zi->zi_pool_guid; return (true); } } return (false); } static void insert_zfs(EFI_HANDLE handle, uint64_t guid) { zfsinfo_t *zi; zi = malloc(sizeof(zfsinfo_t)); zi->zi_handle = handle; zi->zi_pool_guid = guid; STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link); } void efi_zfs_probe(void) { pdinfo_list_t *hdi; pdinfo_t *hd, *pd = NULL; char devname[SPECNAMELEN + 1]; uint64_t guid; hdi = efiblk_get_pdinfo_list(&efipart_hddev); STAILQ_INIT(&zfsinfo); /* * Find the handle for the boot device. The boot1 did find the * device with loader binary, now we need to search for the * same device and if it is part of the zfs pool, we record the * pool GUID for currdev setup. */ STAILQ_FOREACH(hd, hdi, pd_link) { STAILQ_FOREACH(pd, &hd->pd_part, pd_link) { snprintf(devname, sizeof(devname), "%s%dp%d:", efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit); if (zfs_probe_dev(devname, &guid) == 0) { insert_zfs(pd->pd_handle, guid); if (efi_zfs_is_preferred(pd->pd_handle)) pool_guid = guid; } } } } /* * Copyright (c) 2015 Netflix, Inc. All Rights Reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "ficl.h" /* * About ENABLE_UPDATES * * The UEFI variables are identified only by GUID and name, there is no * way to (auto)detect the type for the value, so we need to process the * variables case by case, as we do learn about them. * * While showing the variable name and the value is safe, we must not store * random values nor allow removing (random) variables. * * Since we do have stub code to set/unset the variables, I do want to keep * it to make the future development a bit easier, but the updates are disabled * by default till: * a) the validation and data translation to values is properly implemented * b) We have established which variables we do allow to be updated. * Therefore the set/unset code is included only for developers aid. */ /* If GUID is not defined elsewhere, define it here. */ EFI_GUID gEfiAbsolutePointerProtocolGuid = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID; EFI_GUID gEfiAdapterInformationProtocolGuid = EFI_ADAPTER_INFORMATION_PROTOCOL_GUID; EFI_GUID gEfiAtaPassThruProtocolGuid = EFI_ATA_PASS_THRU_PROTOCOL_GUID; EFI_GUID gEfiBdsArchProtocolGuid = EFI_BDS_ARCH_PROTOCOL_GUID; EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid = EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID; EFI_GUID gEfiCapsuleArchProtocolGuid = EFI_CAPSULE_ARCH_PROTOCOL_GUID; EFI_GUID gEfiComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID; EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID; EFI_GUID gEfiCpuArchProtocolGuid = EFI_CPU_ARCH_PROTOCOL_GUID; EFI_GUID gEfiCpuIo2ProtocolGuid = EFI_CPU_IO2_PROTOCOL_GUID; EFI_GUID gEfiDataHubProtocolGuid = EFI_DATA_HUB_PROTOCOL_GUID; EFI_GUID gEfiDebugImageInfoTableGuid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID; EFI_GUID gEfiDecompressProtocolGuid = EFI_DECOMPRESS_PROTOCOL_GUID; EFI_GUID gEfiDeviceIoProtocolGuid = EFI_DEVICE_IO_PROTOCOL_GUID; EFI_GUID gEfiDhcp4ProtocolGuid = EFI_DHCP4_PROTOCOL_GUID; EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid = EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiDhcp6ProtocolGuid = EFI_DHCP4_PROTOCOL_GUID; EFI_GUID gEfiDhcp6ServiceBindingProtocolGuid = EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID; EFI_GUID gEfiDiskIoProtocolGuid = EFI_DISK_IO_PROTOCOL_GUID; EFI_GUID gEfiDiskIo2ProtocolGuid = EFI_DISK_IO2_PROTOCOL_GUID; EFI_GUID gEfiDpcProtocolGuid = EFI_DPC_PROTOCOL_GUID; EFI_GUID gEfiDriverConfigurationProtocolGuid = EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID; EFI_GUID gEfiDriverConfiguration2ProtocolGuid = EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID; EFI_GUID gEfiDriverDiagnosticsProtocolGuid = EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID; EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID; EFI_GUID gEfiDriverFamilyOverrideProtocolGuid = EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID; EFI_GUID gEfiDriverHealthProtocolGuid = EFI_DRIVER_HEALTH_PROTOCOL_GUID; EFI_GUID gEfiDriverSupportedEfiVersionProtocolGuid = EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL_GUID; EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID; EFI_GUID gEfiEbcProtocolGuid = EFI_EBC_INTERPRETER_PROTOCOL_GUID; EFI_GUID gEfiFormBrowser2ProtocolGuid = EFI_FORM_BROWSER2_PROTOCOL_GUID; EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID; EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid = EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID; EFI_GUID gEfiHiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID; EFI_GUID gEfiConfigKeywordHandlerProtocolGuid = EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL_GUID; EFI_GUID gEfiHiiConfigRoutingProtocolGuid = EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID; EFI_GUID gEfiHiiFontProtocolGuid = EFI_HII_FONT_PROTOCOL_GUID; EFI_GUID gEfiHiiImageProtocolGuid = EFI_HII_IMAGE_PROTOCOL_GUID; EFI_GUID gEfiHiiStringProtocolGuid = EFI_HII_STRING_PROTOCOL_GUID; EFI_GUID gEfiHiiDatabaseProtocolGuid = EFI_HII_DATABASE_PROTOCOL_GUID; EFI_GUID gEfiHobListGuid = HOB_LIST_GUID; EFI_GUID gEfiIdeControllerInitProtocolGuid = EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID; EFI_GUID gEfiIp4ProtocolGuid = EFI_IP4_PROTOCOL_GUID; EFI_GUID gEfiIp4ServiceBindingProtocolGuid = EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiIp4ConfigProtocolGuid = EFI_IP4_CONFIG_PROTOCOL_GUID; EFI_GUID gEfiIp4Config2ProtocolGuid = EFI_IP4_CONFIG2_PROTOCOL_GUID; EFI_GUID gEfiIp6ProtocolGuid = EFI_IP6_PROTOCOL_GUID; EFI_GUID gEfiIp6ServiceBindingProtocolGuid = EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiIp6ConfigProtocolGuid = EFI_IP6_CONFIG_PROTOCOL_GUID; EFI_GUID gEfiIpSecProtocolGuid = EFI_IPSEC_PROTOCOL_GUID; EFI_GUID gEfiIpSec2ProtocolGuid = EFI_IPSEC2_PROTOCOL_GUID; EFI_GUID gEfiIpSecConfigProtocolGuid = EFI_IPSEC_CONFIG_PROTOCOL_GUID; EFI_GUID gEfiIsaAcpiProtocolGuid = EFI_ISA_ACPI_PROTOCOL_GUID; EFI_GUID gEfiKmsProtocolGuid = EFI_KMS_PROTOCOL_GUID; EFI_GUID gEfiLegacy8259ProtocolGuid = EFI_LEGACY_8259_PROTOCOL_GUID; EFI_GUID gEfiLoadFileProtocolGuid = EFI_LOAD_FILE_PROTOCOL_GUID; EFI_GUID gEfiLoadFile2ProtocolGuid = EFI_LOAD_FILE2_PROTOCOL_GUID; EFI_GUID gEfiManagedNetworkProtocolGuid = EFI_MANAGED_NETWORK_PROTOCOL_GUID; EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid = EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiMemoryTypeInformationGuid = EFI_MEMORY_TYPE_INFORMATION_GUID; EFI_GUID gEfiMetronomeArchProtocolGuid = EFI_METRONOME_ARCH_PROTOCOL_GUID; EFI_GUID gEfiMonotonicCounterArchProtocolGuid = EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID; EFI_GUID gEfiMpServiceProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID; EFI_GUID gEfiMpsTableGuid = MPS_TABLE_GUID; EFI_GUID gEfiMtftp4ProtocolGuid = EFI_MTFTP4_PROTOCOL_GUID; EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid = EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiMtftp6ProtocolGuid = EFI_MTFTP6_PROTOCOL_GUID; EFI_GUID gEfiMtftp6ServiceBindingProtocolGuid = EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID; EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31 = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31; EFI_GUID gEfiNvmExpressPassThruProtocolGuid = EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID; EFI_GUID gEfiPartTypeLegacyMbrGuid = EFI_PART_TYPE_LEGACY_MBR_GUID; EFI_GUID gEfiPartTypeSystemPartGuid = EFI_PART_TYPE_EFI_SYSTEM_PART_GUID; EFI_GUID gEfiPcdProtocolGuid = EFI_PCD_PROTOCOL_GUID; EFI_GUID gEfiPciEnumerationCompleteProtocolGuid = EFI_PCI_ENUMERATION_COMPLETE_GUID; EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; EFI_GUID gEfiPlatformDriverOverrideProtocolGuid = EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID; EFI_GUID gEfiPlatformToDriverConfigurationProtocolGuid = EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL_GUID; EFI_GUID gEfiPrint2SProtocolGuid = EFI_PRINT2_PROTOCOL_GUID; EFI_GUID gEfiPxeBaseCodeProtocolGuid = EFI_PXE_BASE_CODE_PROTOCOL_GUID; EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid = EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID; EFI_GUID gEfiRealTimeClockArchProtocolGuid = EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID; EFI_GUID gEfiResetArchProtocolGuid = EFI_RESET_ARCH_PROTOCOL_GUID; EFI_GUID gEfiRngProtocolGuid = EFI_RNG_PROTOCOL_GUID; EFI_GUID gEfiRuntimeArchProtocolGuid = EFI_RUNTIME_ARCH_PROTOCOL_GUID; EFI_GUID gEfiScsiIoProtocolGuid = EFI_SCSI_IO_PROTOCOL_GUID; EFI_GUID gEfiScsiPassThruProtocolGuid = EFI_SCSI_PASS_THRU_PROTOCOL_GUID; EFI_GUID gEfiExtScsiPassThruProtocolGuid = EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID; EFI_GUID gEfiSecurityArchProtocolGuid = EFI_SECURITY_ARCH_PROTOCOL_GUID; EFI_GUID gEfiSecurity2ArchProtocolGuid = EFI_SECURITY2_ARCH_PROTOCOL_GUID; EFI_GUID gEfiSecurityPolicyProtocolGuid = EFI_SECURITY_POLICY_PROTOCOL_GUID; EFI_GUID gEfiSimpleFileSystemProtocolGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_GUID gEfiSimplePointerProtocolGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID; EFI_GUID gEfiSmartCardReaderProtocolGuid = EFI_SMART_CARD_READER_PROTOCOL_GUID; EFI_GUID gEfiStatusCodeRuntimeProtocolGuid = EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID; EFI_GUID gEfiStorageSecurityCommandProtocolGuid = EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID; EFI_GUID gEfiTcg2ProtocolGuid = EFI_TCG2_PROTOCOL_GUID; EFI_GUID gEfiTcp4ProtocolGuid = EFI_TCP4_PROTOCOL_GUID; EFI_GUID gEfiTcp4ServiceBindingProtocolGuid = EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiTcp6ProtocolGuid = EFI_TCP6_PROTOCOL_GUID; EFI_GUID gEfiTcp6ServiceBindingProtocolGuid = EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiTimerArchProtocolGuid = EFI_TIMER_ARCH_PROTOCOL_GUID; EFI_GUID gEfiUdp4ProtocolGuid = EFI_UDP4_PROTOCOL_GUID; EFI_GUID gEfiUdp4ServiceBindingProtocolGuid = EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiUdp6ProtocolGuid = EFI_UDP6_PROTOCOL_GUID; EFI_GUID gEfiUdp6ServiceBindingProtocolGuid = EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID; EFI_GUID gEfiUnicodeCollationProtocolGuid = EFI_UNICODE_COLLATION_PROTOCOL_GUID; EFI_GUID gEfiUnicodeCollation2ProtocolGuid = EFI_UNICODE_COLLATION_PROTOCOL2_GUID; EFI_GUID gEfiUsbIoProtocolGuid = EFI_USB_IO_PROTOCOL_GUID; EFI_GUID gEfiUsb2HcProtocolGuid = EFI_USB2_HC_PROTOCOL_GUID; EFI_GUID gEfiVariableArchProtocolGuid = EFI_VARIABLE_ARCH_PROTOCOL_GUID; EFI_GUID gEfiVariableWriteArchProtocolGuid = EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID; EFI_GUID gEfiWatchdogTimerArchProtocolGuid = EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID; EFI_GUID gFdtTableGuid = FDT_TABLE_GUID; EFI_GUID gLzmaCompress = LZMA_COMPRESS_GUID; EFI_GUID gMtcVendorGuid = MTC_VENDOR_GUID; EFI_GUID gPcdProtocolGuid = PCD_PROTOCOL_GUID; static struct efi_uuid_mapping { const char *efi_guid_name; EFI_GUID *efi_guid; } efi_uuid_mapping[] = { { .efi_guid_name = "global", .efi_guid = &gEfiGlobalVariableGuid }, { .efi_guid_name = "illumos", .efi_guid = &gillumosBootVarGuid }, /* EFI Systab entry names. */ { .efi_guid_name = "MPS Table", .efi_guid = &gEfiMpsTableGuid }, { .efi_guid_name = "ACPI Table", .efi_guid = &gEfiAcpiTableGuid }, { .efi_guid_name = "ACPI 2.0 Table", .efi_guid = &gEfiAcpi20TableGuid }, { .efi_guid_name = "ATA pass thru", .efi_guid = &gEfiAtaPassThruProtocolGuid }, { .efi_guid_name = "SMBIOS Table", .efi_guid = &gEfiSmbiosTableGuid }, { .efi_guid_name = "SMBIOS3 Table", .efi_guid = &gEfiSmbios3TableGuid }, { .efi_guid_name = "DXE Table", .efi_guid = &gEfiDxeServicesTableGuid }, { .efi_guid_name = "HOB List Table", .efi_guid = &gEfiHobListGuid }, { .efi_guid_name = EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, .efi_guid = &gEfiMemoryTypeInformationGuid }, { .efi_guid_name = "Debug Image Info Table", .efi_guid = &gEfiDebugImageInfoTableGuid }, { .efi_guid_name = "FDT Table", .efi_guid = &gFdtTableGuid }, /* * Protocol names for debug purposes. * Can be removed along with lsefi command. */ { .efi_guid_name = "absolute pointer", .efi_guid = &gEfiAbsolutePointerProtocolGuid }, { .efi_guid_name = "device path", .efi_guid = &gEfiDevicePathProtocolGuid }, { .efi_guid_name = "block io", .efi_guid = &gEfiBlockIoProtocolGuid }, { .efi_guid_name = "block io2", .efi_guid = &gEfiBlockIo2ProtocolGuid }, { .efi_guid_name = "disk io", .efi_guid = &gEfiDiskIoProtocolGuid }, { .efi_guid_name = "disk io2", .efi_guid = &gEfiDiskIo2ProtocolGuid }, { .efi_guid_name = "disk info", .efi_guid = &gEfiDiskInfoProtocolGuid }, { .efi_guid_name = "simple fs", .efi_guid = &gEfiSimpleFileSystemProtocolGuid }, { .efi_guid_name = "load file", .efi_guid = &gEfiLoadFileProtocolGuid }, { .efi_guid_name = "load file2", .efi_guid = &gEfiLoadFile2ProtocolGuid }, { .efi_guid_name = "device io", .efi_guid = &gEfiDeviceIoProtocolGuid }, { .efi_guid_name = "unicode collation", .efi_guid = &gEfiUnicodeCollationProtocolGuid }, { .efi_guid_name = "unicode collation2", .efi_guid = &gEfiUnicodeCollation2ProtocolGuid }, { .efi_guid_name = "simple network", .efi_guid = &gEfiSimpleNetworkProtocolGuid }, { .efi_guid_name = "simple pointer", .efi_guid = &gEfiSimplePointerProtocolGuid }, { .efi_guid_name = "simple text output", .efi_guid = &gEfiSimpleTextOutProtocolGuid }, { .efi_guid_name = "simple text input", .efi_guid = &gEfiSimpleTextInProtocolGuid }, { .efi_guid_name = "simple text ex input", .efi_guid = &gEfiSimpleTextInputExProtocolGuid }, { .efi_guid_name = "console control", .efi_guid = &gEfiConsoleControlProtocolGuid }, { .efi_guid_name = "stdin", .efi_guid = &gEfiConsoleInDeviceGuid }, { .efi_guid_name = "stdout", .efi_guid = &gEfiConsoleOutDeviceGuid }, { .efi_guid_name = "stderr", .efi_guid = &gEfiStandardErrorDeviceGuid }, { .efi_guid_name = "GOP", .efi_guid = &gEfiGraphicsOutputProtocolGuid }, { .efi_guid_name = "UGA draw", .efi_guid = &gEfiUgaDrawProtocolGuid }, { .efi_guid_name = "UGA io", .efi_guid = &gEfiUgaIoProtocolGuid }, { .efi_guid_name = "PXE base code", .efi_guid = &gEfiPxeBaseCodeProtocolGuid }, { .efi_guid_name = "PXE base code callback", .efi_guid = &gEfiPxeBaseCodeCallbackProtocolGuid }, { .efi_guid_name = "serial io", .efi_guid = &gEfiSerialIoProtocolGuid }, { .efi_guid_name = "serial device type", .efi_guid = &gEfiSerialTerminalDeviceTypeGuid }, { .efi_guid_name = "loaded image", .efi_guid = &gEfiLoadedImageProtocolGuid }, { .efi_guid_name = "loaded image device path", .efi_guid = &gEfiLoadedImageDevicePathProtocolGuid }, { .efi_guid_name = "ISA ACPI", .efi_guid = &gEfiIsaAcpiProtocolGuid }, { .efi_guid_name = "ISA io", .efi_guid = &gEfiIsaIoProtocolGuid }, { .efi_guid_name = "Super io", .efi_guid = &gEfiSioProtocolGuid }, { .efi_guid_name = "IDE controller init", .efi_guid = &gEfiIdeControllerInitProtocolGuid }, { .efi_guid_name = "PCI", .efi_guid = &gEfiPciIoProtocolGuid }, { .efi_guid_name = "PCI enumeration", .efi_guid = &gEfiPciEnumerationCompleteProtocolGuid }, { .efi_guid_name = "PCI root bridge", .efi_guid = &gEfiPciRootBridgeIoProtocolGuid }, { .efi_guid_name = "driver binding", .efi_guid = &gEfiDriverBindingProtocolGuid }, { .efi_guid_name = "driver configuration", .efi_guid = &gEfiDriverConfigurationProtocolGuid }, { .efi_guid_name = "driver configuration2", .efi_guid = &gEfiDriverConfiguration2ProtocolGuid }, { .efi_guid_name = "driver diagnostics", .efi_guid = &gEfiDriverDiagnosticsProtocolGuid }, { .efi_guid_name = "driver diagnostics2", .efi_guid = &gEfiDriverDiagnostics2ProtocolGuid }, { .efi_guid_name = "driver override", .efi_guid = &gEfiPlatformDriverOverrideProtocolGuid }, { .efi_guid_name = "bus specific driver override", .efi_guid = &gEfiBusSpecificDriverOverrideProtocolGuid }, { .efi_guid_name = "platform to driver configuration", .efi_guid = &gEfiPlatformToDriverConfigurationProtocolGuid }, { .efi_guid_name = "driver supported EFI version", .efi_guid = &gEfiDriverSupportedEfiVersionProtocolGuid }, { .efi_guid_name = "driver family override", .efi_guid = &gEfiDriverFamilyOverrideProtocolGuid }, { .efi_guid_name = "driver health", .efi_guid = &gEfiDriverHealthProtocolGuid }, { .efi_guid_name = "adapter information", .efi_guid = &gEfiAdapterInformationProtocolGuid }, { .efi_guid_name = "VLAN config", .efi_guid = &gEfiVlanConfigProtocolGuid }, { .efi_guid_name = "ARP service binding", .efi_guid = &gEfiArpServiceBindingProtocolGuid }, { .efi_guid_name = "ARP", .efi_guid = &gEfiArpProtocolGuid }, { .efi_guid_name = "IPv4 service binding", .efi_guid = &gEfiIp4ServiceBindingProtocolGuid }, { .efi_guid_name = "IPv4", .efi_guid = &gEfiIp4ProtocolGuid }, { .efi_guid_name = "IPv4 config", .efi_guid = &gEfiIp4ConfigProtocolGuid }, { .efi_guid_name = "IPv4 config2", .efi_guid = &gEfiIp4Config2ProtocolGuid }, { .efi_guid_name = "IPv6 service binding", .efi_guid = &gEfiIp6ServiceBindingProtocolGuid }, { .efi_guid_name = "IPv6", .efi_guid = &gEfiIp6ProtocolGuid }, { .efi_guid_name = "IPv6 config", .efi_guid = &gEfiIp6ConfigProtocolGuid }, { .efi_guid_name = "NVMe pass thru", .efi_guid = &gEfiNvmExpressPassThruProtocolGuid }, { .efi_guid_name = "UDPv4", .efi_guid = &gEfiUdp4ProtocolGuid }, { .efi_guid_name = "UDPv4 service binding", .efi_guid = &gEfiUdp4ServiceBindingProtocolGuid }, { .efi_guid_name = "UDPv6", .efi_guid = &gEfiUdp6ProtocolGuid }, { .efi_guid_name = "UDPv6 service binding", .efi_guid = &gEfiUdp6ServiceBindingProtocolGuid }, { .efi_guid_name = "TCPv4", .efi_guid = &gEfiTcp4ProtocolGuid }, { .efi_guid_name = "TCPv4 service binding", .efi_guid = &gEfiTcp4ServiceBindingProtocolGuid }, { .efi_guid_name = "TCPv6", .efi_guid = &gEfiTcp6ProtocolGuid }, { .efi_guid_name = "TCPv6 service binding", .efi_guid = &gEfiTcp6ServiceBindingProtocolGuid }, { .efi_guid_name = "EFI System partition", .efi_guid = &gEfiPartTypeSystemPartGuid }, { .efi_guid_name = "MBR legacy", .efi_guid = &gEfiPartTypeLegacyMbrGuid }, { .efi_guid_name = "USB io", .efi_guid = &gEfiUsbIoProtocolGuid }, { .efi_guid_name = "USB2 HC", .efi_guid = &gEfiUsb2HcProtocolGuid }, { .efi_guid_name = "component name", .efi_guid = &gEfiComponentNameProtocolGuid }, { .efi_guid_name = "component name2", .efi_guid = &gEfiComponentName2ProtocolGuid }, { .efi_guid_name = "decompress", .efi_guid = &gEfiDecompressProtocolGuid }, { .efi_guid_name = "ebc interpreter", .efi_guid = &gEfiEbcProtocolGuid }, { .efi_guid_name = "network interface identifier", .efi_guid = &gEfiNetworkInterfaceIdentifierProtocolGuid }, { .efi_guid_name = "network interface identifier_31", .efi_guid = &gEfiNetworkInterfaceIdentifierProtocolGuid_31 }, { .efi_guid_name = "managed network service binding", .efi_guid = &gEfiManagedNetworkServiceBindingProtocolGuid }, { .efi_guid_name = "managed network", .efi_guid = &gEfiManagedNetworkProtocolGuid }, { .efi_guid_name = "form browser", .efi_guid = &gEfiFormBrowser2ProtocolGuid }, { .efi_guid_name = "HII config access", .efi_guid = &gEfiHiiConfigAccessProtocolGuid }, { .efi_guid_name = "HII config keyword handler", .efi_guid = &gEfiConfigKeywordHandlerProtocolGuid }, { .efi_guid_name = "HII config routing", .efi_guid = &gEfiHiiConfigRoutingProtocolGuid }, { .efi_guid_name = "HII database", .efi_guid = &gEfiHiiDatabaseProtocolGuid }, { .efi_guid_name = "HII string", .efi_guid = &gEfiHiiStringProtocolGuid }, { .efi_guid_name = "HII image", .efi_guid = &gEfiHiiImageProtocolGuid }, { .efi_guid_name = "HII font", .efi_guid = &gEfiHiiFontProtocolGuid }, { .efi_guid_name = "MTFTP3 service binding", .efi_guid = &gEfiMtftp4ServiceBindingProtocolGuid }, { .efi_guid_name = "MTFTP4", .efi_guid = &gEfiMtftp4ProtocolGuid }, { .efi_guid_name = "MTFTP6 service binding", .efi_guid = &gEfiMtftp6ServiceBindingProtocolGuid }, { .efi_guid_name = "MTFTP6", .efi_guid = &gEfiMtftp6ProtocolGuid }, { .efi_guid_name = "DHCP4 service binding", .efi_guid = &gEfiDhcp4ServiceBindingProtocolGuid }, { .efi_guid_name = "DHCP4", .efi_guid = &gEfiDhcp4ProtocolGuid }, { .efi_guid_name = "DHCP6 service binding", .efi_guid = &gEfiDhcp6ServiceBindingProtocolGuid }, { .efi_guid_name = "DHCP6", .efi_guid = &gEfiDhcp6ProtocolGuid }, { .efi_guid_name = "SCSI io", .efi_guid = &gEfiScsiIoProtocolGuid }, { .efi_guid_name = "SCSI pass thru", .efi_guid = &gEfiScsiPassThruProtocolGuid }, { .efi_guid_name = "SCSI pass thru ext", .efi_guid = &gEfiExtScsiPassThruProtocolGuid }, { .efi_guid_name = "Capsule arch", .efi_guid = &gEfiCapsuleArchProtocolGuid }, { .efi_guid_name = "monotonic counter arch", .efi_guid = &gEfiMonotonicCounterArchProtocolGuid }, { .efi_guid_name = "realtime clock arch", .efi_guid = &gEfiRealTimeClockArchProtocolGuid }, { .efi_guid_name = "variable arch", .efi_guid = &gEfiVariableArchProtocolGuid }, { .efi_guid_name = "variable write arch", .efi_guid = &gEfiVariableWriteArchProtocolGuid }, { .efi_guid_name = "watchdog timer arch", .efi_guid = &gEfiWatchdogTimerArchProtocolGuid }, { .efi_guid_name = "BDS arch", .efi_guid = &gEfiBdsArchProtocolGuid }, { .efi_guid_name = "metronome arch", .efi_guid = &gEfiMetronomeArchProtocolGuid }, { .efi_guid_name = "timer arch", .efi_guid = &gEfiTimerArchProtocolGuid }, { .efi_guid_name = "DPC", .efi_guid = &gEfiDpcProtocolGuid }, { .efi_guid_name = "print2", .efi_guid = &gEfiPrint2SProtocolGuid }, { .efi_guid_name = "device path to text", .efi_guid = &gEfiDevicePathToTextProtocolGuid }, { .efi_guid_name = "reset arch", .efi_guid = &gEfiResetArchProtocolGuid }, { .efi_guid_name = "CPU arch", .efi_guid = &gEfiCpuArchProtocolGuid }, { .efi_guid_name = "CPU IO2", .efi_guid = &gEfiCpuIo2ProtocolGuid }, { .efi_guid_name = "Legacy 8259", .efi_guid = &gEfiLegacy8259ProtocolGuid }, { .efi_guid_name = "Security arch", .efi_guid = &gEfiSecurityArchProtocolGuid }, { .efi_guid_name = "Security2 arch", .efi_guid = &gEfiSecurity2ArchProtocolGuid }, { .efi_guid_name = "Security Policy", .efi_guid = &gEfiSecurityPolicyProtocolGuid }, { .efi_guid_name = "Runtime arch", .efi_guid = &gEfiRuntimeArchProtocolGuid }, { .efi_guid_name = "status code runtime", .efi_guid = &gEfiStatusCodeRuntimeProtocolGuid }, { .efi_guid_name = "storage security command", .efi_guid = &gEfiStorageSecurityCommandProtocolGuid }, { .efi_guid_name = "data hub", .efi_guid = &gEfiDataHubProtocolGuid }, { .efi_guid_name = "PCD", .efi_guid = &gPcdProtocolGuid }, { .efi_guid_name = "EFI PCD", .efi_guid = &gEfiPcdProtocolGuid }, { .efi_guid_name = "firmware volume block", .efi_guid = &gEfiFirmwareVolumeBlockProtocolGuid }, { .efi_guid_name = "firmware volume2", .efi_guid = &gEfiFirmwareVolumeBlock2ProtocolGuid }, { .efi_guid_name = "lzma compress", .efi_guid = &gLzmaCompress }, { .efi_guid_name = "MP services", .efi_guid = &gEfiMpServiceProtocolGuid }, { .efi_guid_name = MTC_VARIABLE_NAME, .efi_guid = &gMtcVendorGuid }, { .efi_guid_name = "Active EDID", .efi_guid = &gEfiEdidActiveProtocolGuid }, { .efi_guid_name = "Discovered EDID", .efi_guid = &gEfiEdidDiscoveredProtocolGuid }, { .efi_guid_name = "key management service", .efi_guid = &gEfiKmsProtocolGuid }, { .efi_guid_name = "smart card reader", .efi_guid = &gEfiSmartCardReaderProtocolGuid }, { .efi_guid_name = "rng source", .efi_guid = &gEfiRngProtocolGuid }, { .efi_guid_name = "IPsec config", .efi_guid = &gEfiIpSecConfigProtocolGuid }, { .efi_guid_name = "IPsec", .efi_guid = &gEfiIpSecProtocolGuid }, { .efi_guid_name = "IPsec2", .efi_guid = &gEfiIpSec2ProtocolGuid }, { .efi_guid_name = "TCG2 tpm", .efi_guid = &gEfiTcg2ProtocolGuid } }; bool efi_guid_to_str(const EFI_GUID *guid, char **sp) { uint32_t status; uuid_to_string((const uuid_t *)guid, sp, &status); return (status == uuid_s_ok ? true : false); } bool efi_str_to_guid(const char *s, EFI_GUID *guid) { uint32_t status; uuid_from_string(s, (uuid_t *)guid, &status); return (status == uuid_s_ok ? true : false); } bool efi_name_to_guid(const char *name, EFI_GUID *guid) { uint32_t i; for (i = 0; i < nitems(efi_uuid_mapping); i++) { if (strcasecmp(name, efi_uuid_mapping[i].efi_guid_name) == 0) { *guid = *efi_uuid_mapping[i].efi_guid; return (true); } } return (efi_str_to_guid(name, guid)); } bool efi_guid_to_name(EFI_GUID *guid, char **name) { uint32_t i; int rv; for (i = 0; i < nitems(efi_uuid_mapping); i++) { rv = uuid_equal((uuid_t *)guid, (uuid_t *)efi_uuid_mapping[i].efi_guid, NULL); if (rv != 0) { *name = strdup(efi_uuid_mapping[i].efi_guid_name); if (*name == NULL) return (false); return (true); } } return (efi_guid_to_str(guid, name)); } void efi_init_environment(void) { char var[128]; snprintf(var, sizeof (var), "%d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); env_setenv("efi-version", EV_VOLATILE, var, env_noset, env_nounset); } COMMAND_SET(efishow, "efi-show", "print some or all EFI variables", command_efi_show); static int efi_print_other_value(uint8_t *data, UINTN datasz) { UINTN i; bool is_ascii = true; printf(" = "); for (i = 0; i < datasz - 1; i++) { /* * Quick hack to see if this ascii-ish string is printable * range plus tab, cr and lf. */ if ((data[i] < 32 || data[i] > 126) && data[i] != 9 && data[i] != 10 && data[i] != 13) { is_ascii = false; break; } } if (data[datasz - 1] != '\0') is_ascii = false; if (is_ascii == true) { printf("%s", data); if (pager_output("\n")) return (CMD_WARN); } else { if (pager_output("\n")) return (CMD_WARN); /* * Dump hex bytes grouped by 4. */ for (i = 0; i < datasz; i++) { printf("%02x ", data[i]); if ((i + 1) % 4 == 0) printf(" "); if ((i + 1) % 20 == 0) { if (pager_output("\n")) return (CMD_WARN); } } if (pager_output("\n")) return (CMD_WARN); } return (CMD_OK); } /* This appears to be some sort of UEFI shell alias table. */ static int efi_print_shell_str(const CHAR16 *varnamearg __unused, uint8_t *data, UINTN datasz __unused) { printf(" = %S", (CHAR16 *)data); if (pager_output("\n")) return (CMD_WARN); return (CMD_OK); } const char * efi_memory_type(EFI_MEMORY_TYPE type) { const char *types[] = { "Reserved", "LoaderCode", "LoaderData", "BootServicesCode", "BootServicesData", "RuntimeServicesCode", "RuntimeServicesData", "ConventionalMemory", "UnusableMemory", "ACPIReclaimMemory", "ACPIMemoryNVS", "MemoryMappedIO", "MemoryMappedIOPortSpace", "PalCode", "PersistentMemory" }; switch (type) { case EfiReservedMemoryType: case EfiLoaderCode: case EfiLoaderData: case EfiBootServicesCode: case EfiBootServicesData: case EfiRuntimeServicesCode: case EfiRuntimeServicesData: case EfiConventionalMemory: case EfiUnusableMemory: case EfiACPIReclaimMemory: case EfiACPIMemoryNVS: case EfiMemoryMappedIO: case EfiMemoryMappedIOPortSpace: case EfiPalCode: case EfiPersistentMemory: return (types[type]); default: return ("Unknown"); } } /* Print memory type table. */ static int efi_print_mem_type(const CHAR16 *varnamearg __unused, uint8_t *data, UINTN datasz) { int i, n; EFI_MEMORY_TYPE_INFORMATION *ti; ti = (EFI_MEMORY_TYPE_INFORMATION *)data; if (pager_output(" = \n")) return (CMD_WARN); n = datasz / sizeof (EFI_MEMORY_TYPE_INFORMATION); for (i = 0; i < n && ti[i].NumberOfPages != 0; i++) { printf("\t%23s pages: %u", efi_memory_type(ti[i].Type), ti[i].NumberOfPages); if (pager_output("\n")) return (CMD_WARN); } return (CMD_OK); } /* * Print illumos variables. * We have LoaderPath and LoaderDev as CHAR16 strings. */ static int efi_print_illumos(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz __unused) { int rv = -1; char *var = NULL; if (ucs2_to_utf8(varnamearg, &var) != 0) return (CMD_ERROR); if (strcmp("LoaderPath", var) == 0 || strcmp("LoaderDev", var) == 0) { printf(" = "); printf("%S", (CHAR16 *)data); if (pager_output("\n")) rv = CMD_WARN; else rv = CMD_OK; } free(var); return (rv); } /* Print global variables. */ static int efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) { int rv = -1; char *var = NULL; if (ucs2_to_utf8(varnamearg, &var) != 0) return (CMD_ERROR); if (strcmp("AuditMode", var) == 0) { printf(" = "); printf("0x%x", *data); /* 8-bit int */ goto done; } if (strcmp("BootOptionSupport", var) == 0) { printf(" = "); printf("0x%x", *((uint32_t *)data)); /* UINT32 */ goto done; } if (strcmp("BootCurrent", var) == 0 || strcmp("BootNext", var) == 0 || strcmp("Timeout", var) == 0) { printf(" = "); printf("%u", *((uint16_t *)data)); /* UINT16 */ goto done; } if (strcmp("BootOrder", var) == 0 || strcmp("DriverOrder", var) == 0) { int i; UINT16 *u16 = (UINT16 *)data; printf(" ="); for (i = 0; i < datasz / sizeof (UINT16); i++) printf(" %u", u16[i]); goto done; } if (strncmp("Boot", var, 4) == 0 || strncmp("Driver", var, 5) == 0 || strncmp("SysPrep", var, 7) == 0 || strncmp("OsRecovery", var, 10) == 0) { UINT16 filepathlistlen; CHAR16 *text; int desclen; EFI_DEVICE_PATH *dp; data += sizeof (UINT32); filepathlistlen = *(uint16_t *)data; data += sizeof (UINT16); text = (CHAR16 *)data; for (desclen = 0; text[desclen] != 0; desclen++) ; if (desclen != 0) { /* Add terminating zero and we have CHAR16. */ desclen = (desclen + 1) * 2; } printf(" = "); printf("%S", text); if (filepathlistlen != 0) { /* Output pathname from new line. */ if (pager_output("\n")) { rv = CMD_WARN; goto done; } dp = malloc(filepathlistlen); if (dp == NULL) goto done; memcpy(dp, data + desclen, filepathlistlen); text = efi_devpath_name(dp); if (text != NULL) { printf("\t%S", text); efi_free_devpath_name(text); } free(dp); } goto done; } if (strcmp("ConIn", var) == 0 || strcmp("ConInDev", var) == 0 || strcmp("ConOut", var) == 0 || strcmp("ConOutDev", var) == 0 || strcmp("ErrOut", var) == 0 || strcmp("ErrOutDev", var) == 0) { CHAR16 *text; printf(" = "); text = efi_devpath_name((EFI_DEVICE_PATH *)data); if (text != NULL) { printf("%S", text); efi_free_devpath_name(text); } goto done; } if (strcmp("PlatformLang", var) == 0 || strcmp("PlatformLangCodes", var) == 0 || strcmp("LangCodes", var) == 0 || strcmp("Lang", var) == 0) { printf(" = "); printf("%s", data); /* ASCII string */ goto done; } /* * Feature bitmap from firmware to OS. * Older UEFI provides UINT32, newer UINT64. */ if (strcmp("OsIndicationsSupported", var) == 0) { printf(" = "); if (datasz == 4) printf("0x%x", *((uint32_t *)data)); else printf("0x%jx", *((uint64_t *)data)); goto done; } /* Fallback for anything else. */ rv = efi_print_other_value(data, datasz); done: if (rv == -1) { if (pager_output("\n")) rv = CMD_WARN; else rv = CMD_OK; } free(var); return (rv); } static void efi_print_var_attr(UINT32 attr) { bool comma = false; if (attr & EFI_VARIABLE_NON_VOLATILE) { printf("NV"); comma = true; } if (attr & EFI_VARIABLE_BOOTSERVICE_ACCESS) { if (comma == true) printf(","); printf("BS"); comma = true; } if (attr & EFI_VARIABLE_RUNTIME_ACCESS) { if (comma == true) printf(","); printf("RS"); comma = true; } if (attr & EFI_VARIABLE_HARDWARE_ERROR_RECORD) { if (comma == true) printf(","); printf("HR"); comma = true; } if (attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { if (comma == true) printf(","); printf("AT"); comma = true; } } static int efi_print_var(CHAR16 *varnamearg, EFI_GUID *matchguid, int lflag) { UINTN datasz; EFI_STATUS status; UINT32 attr; char *str; uint8_t *data; int rv = CMD_OK; str = NULL; datasz = 0; status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, NULL); if (status != EFI_BUFFER_TOO_SMALL) { printf("Can't get the variable: error %#lx\n", DECODE_ERROR(status)); return (CMD_ERROR); } data = malloc(datasz); if (data == NULL) { printf("Out of memory\n"); return (CMD_ERROR); } status = RS->GetVariable(varnamearg, matchguid, &attr, &datasz, data); if (status != EFI_SUCCESS) { printf("Can't get the variable: error %#lx\n", DECODE_ERROR(status)); free(data); return (CMD_ERROR); } if (efi_guid_to_name(matchguid, &str) == false) { rv = CMD_ERROR; goto done; } printf("%s ", str); efi_print_var_attr(attr); printf(" %S", varnamearg); if (lflag == 0) { if (strcmp(str, "global") == 0) rv = efi_print_global(varnamearg, data, datasz); else if (strcmp(str, "illumos") == 0) rv = efi_print_illumos(varnamearg, data, datasz); else if (strcmp(str, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME) == 0) rv = efi_print_mem_type(varnamearg, data, datasz); else if (strcmp(str, "47c7b227-c42a-11d2-8e57-00a0c969723b") == 0) rv = efi_print_shell_str(varnamearg, data, datasz); else if (strcmp(str, MTC_VARIABLE_NAME) == 0) { printf(" = "); printf("%u", *((uint32_t *)data)); /* UINT32 */ rv = CMD_OK; if (pager_output("\n")) rv = CMD_WARN; } else rv = efi_print_other_value(data, datasz); } else if (pager_output("\n")) rv = CMD_WARN; done: free(str); free(data); return (rv); } static int command_efi_show(int argc, char *argv[]) { /* * efi-show [-a] * print all the env * efi-show -g UUID * print all the env vars tagged with UUID * efi-show -v var * search all the env vars and print the ones matching var * efi-show -g UUID -v var * efi-show UUID var * print all the env vars that match UUID and var */ /* NB: We assume EFI_GUID is the same as uuid_t */ int aflag = 0, gflag = 0, lflag = 0, vflag = 0; int ch, rv; unsigned i; EFI_STATUS status; EFI_GUID varguid = ZERO_GUID; EFI_GUID matchguid = ZERO_GUID; CHAR16 *varname; CHAR16 *newnm; CHAR16 varnamearg[128]; UINTN varalloc; UINTN varsz; optind = 1; optreset = 1; opterr = 1; while ((ch = getopt(argc, argv, "ag:lv:")) != -1) { switch (ch) { case 'a': aflag = 1; break; case 'g': gflag = 1; if (efi_name_to_guid(optarg, &matchguid) == false) { printf("uuid %s could not be parsed\n", optarg); return (CMD_ERROR); } break; case 'l': lflag = 1; break; case 'v': vflag = 1; if (strlen(optarg) >= nitems(varnamearg)) { printf("Variable %s is longer than %zu " "characters\n", optarg, nitems(varnamearg)); return (CMD_ERROR); } cpy8to16(optarg, varnamearg, nitems(varnamearg)); break; default: return (CMD_ERROR); } } if (argc == 1) /* default is -a */ aflag = 1; if (aflag && (gflag || vflag)) { printf("-a isn't compatible with -g or -v\n"); return (CMD_ERROR); } if (aflag && optind < argc) { printf("-a doesn't take any args\n"); return (CMD_ERROR); } argc -= optind; argv += optind; pager_open(); if (vflag && gflag) { rv = efi_print_var(varnamearg, &matchguid, lflag); if (rv == CMD_WARN) rv = CMD_OK; pager_close(); return (rv); } if (argc == 2) { optarg = argv[0]; if (strlen(optarg) >= nitems(varnamearg)) { printf("Variable %s is longer than %zu characters\n", optarg, nitems(varnamearg)); pager_close(); return (CMD_ERROR); } for (i = 0; i < strlen(optarg); i++) varnamearg[i] = optarg[i]; varnamearg[i] = 0; optarg = argv[1]; if (efi_name_to_guid(optarg, &matchguid) == false) { printf("uuid %s could not be parsed\n", optarg); pager_close(); return (CMD_ERROR); } rv = efi_print_var(varnamearg, &matchguid, lflag); if (rv == CMD_WARN) rv = CMD_OK; pager_close(); return (rv); } if (argc > 0) { printf("Too many args: %d\n", argc); pager_close(); return (CMD_ERROR); } /* * Initiate the search -- note the standard takes pain * to specify the initial call must be a poiner to a NULL * character. */ varalloc = 1024; varname = malloc(varalloc); if (varname == NULL) { printf("Can't allocate memory to get variables\n"); pager_close(); return (CMD_ERROR); } varname[0] = 0; while (1) { varsz = varalloc; status = RS->GetNextVariableName(&varsz, varname, &varguid); if (status == EFI_BUFFER_TOO_SMALL) { varalloc = varsz; newnm = realloc(varname, varalloc); if (newnm == NULL) { printf("Can't allocate memory to get " "variables\n"); rv = CMD_ERROR; break; } varname = newnm; continue; /* Try again with bigger buffer */ } if (status == EFI_NOT_FOUND) { rv = CMD_OK; break; } if (status != EFI_SUCCESS) { rv = CMD_ERROR; break; } if (aflag) { rv = efi_print_var(varname, &varguid, lflag); if (rv != CMD_OK) { if (rv == CMD_WARN) rv = CMD_OK; break; } continue; } if (vflag) { if (wcscmp(varnamearg, varname) == 0) { rv = efi_print_var(varname, &varguid, lflag); if (rv != CMD_OK) { if (rv == CMD_WARN) rv = CMD_OK; break; } continue; } } if (gflag) { rv = uuid_equal((uuid_t *)&varguid, (uuid_t *)&matchguid, NULL); if (rv != 0) { rv = efi_print_var(varname, &varguid, lflag); if (rv != CMD_OK) { if (rv == CMD_WARN) rv = CMD_OK; break; } continue; } } } free(varname); pager_close(); return (rv); } COMMAND_SET(efiset, "efi-set", "set EFI variables", command_efi_set); static int command_efi_set(int argc, char *argv[]) { char *uuid, *var, *val; CHAR16 wvar[128]; EFI_GUID guid; #if defined(ENABLE_UPDATES) EFI_STATUS err; #endif if (argc != 4) { printf("efi-set uuid var new-value\n"); return (CMD_ERROR); } uuid = argv[1]; var = argv[2]; val = argv[3]; if (efi_name_to_guid(uuid, &guid) == false) { printf("Invalid uuid %s\n", uuid); return (CMD_ERROR); } cpy8to16(var, wvar, nitems(wvar)); #if defined(ENABLE_UPDATES) err = RS->SetVariable(wvar, &guid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, strlen(val) + 1, val); if (EFI_ERROR(err)) { printf("Failed to set variable: error %lu\n", DECODE_ERROR(err)); return (CMD_ERROR); } #else printf("would set %s %s = %s\n", uuid, var, val); #endif return (CMD_OK); } COMMAND_SET(efiunset, "efi-unset", "delete / unset EFI variables", command_efi_unset); static int command_efi_unset(int argc, char *argv[]) { char *uuid, *var; CHAR16 wvar[128]; EFI_GUID guid; #if defined(ENABLE_UPDATES) EFI_STATUS err; #endif if (argc != 3) { printf("efi-unset uuid var\n"); return (CMD_ERROR); } uuid = argv[1]; var = argv[2]; if (efi_name_to_guid(uuid, &guid) == false) { printf("Invalid uuid %s\n", uuid); return (CMD_ERROR); } cpy8to16(var, wvar, nitems(wvar)); #if defined(ENABLE_UPDATES) err = RS->SetVariable(wvar, &guid, 0, 0, NULL); if (EFI_ERROR(err)) { printf("Failed to unset variable: error %lu\n", DECODE_ERROR(err)); return (CMD_ERROR); } #else printf("would unset %s %s \n", uuid, var); #endif return (CMD_OK); } /* * Loader interaction words and extras * * efi-setenv ( value n name n guid n attr -- 0 | -1) * efi-getenv ( guid n addr n -- addr' n' | -1 ) * efi-unsetenv ( name n guid n'' -- ) */ /* * efi-setenv * efi-setenv ( value n name n guid n attr -- 0 | -1) * * Set environment variables using the SetVariable EFI runtime service. * * Value and guid are passed through in binary form (so guid needs to be * converted to binary form from its string form). Name is converted from * ASCII to CHAR16. Since ficl doesn't have support for internationalization, * there's no native CHAR16 interface provided. * * attr is an int in the bitmask of the following attributes for this variable. * * 1 Non volatile * 2 Boot service access * 4 Run time access * (corresponding to the same bits in the UEFI spec). */ static void ficlEfiSetenv(ficlVm *pVM) { char *value = NULL, *guid = NULL; CHAR16 *name = NULL; int i; char *namep, *valuep, *guidp; int names, values, guids, attr; EFI_STATUS status; uuid_t u; uint32_t ustatus; char *error = NULL; ficlStack *pStack = ficlVmGetDataStack(pVM); FICL_STACK_CHECK(pStack, 6, 0); attr = ficlStackPopInteger(pStack); guids = ficlStackPopInteger(pStack); guidp = (char *)ficlStackPopPointer(pStack); names = ficlStackPopInteger(pStack); namep = (char *)ficlStackPopPointer(pStack); values = ficlStackPopInteger(pStack); valuep = (char *)ficlStackPopPointer(pStack); guid = ficlMalloc(guids); if (guid == NULL) goto out; memcpy(guid, guidp, guids); uuid_from_string(guid, &u, &ustatus); if (ustatus != uuid_s_ok) { switch (ustatus) { case uuid_s_bad_version: error = "uuid: bad string"; break; case uuid_s_invalid_string_uuid: error = "uuid: invalid string"; break; case uuid_s_no_memory: error = "Out of memory"; break; default: error = "uuid: Unknown error"; break; } ficlStackPushInteger(pStack, -1); goto out; } name = ficlMalloc((names + 1) * sizeof (CHAR16)); if (name == NULL) { error = "Out of memory"; goto out; } for (i = 0; i < names; i++) name[i] = namep[i]; name[names] = 0; value = ficlMalloc(values + 1); if (value == NULL) { error = "Out of memory"; goto out; } memcpy(value, valuep, values); status = RS->SetVariable(name, (EFI_GUID *)&u, attr, values, value); if (status == EFI_SUCCESS) { ficlStackPushInteger(pStack, 0); } else { ficlStackPushInteger(pStack, -1); error = "Error: SetVariable failed"; } out: ficlFree(name); ficlFree(value); ficlFree(guid); if (error != NULL) ficlVmThrowError(pVM, error); } static void ficlEfiGetenv(ficlVm *pVM) { char *name, *value; char *namep; int names; FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 2); names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); name = ficlMalloc(names+1); if (name == NULL) ficlVmThrowError(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; value = getenv(name); ficlFree(name); if (value != NULL) { ficlStackPushPointer(ficlVmGetDataStack(pVM), value); ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(value)); } else { ficlStackPushInteger(ficlVmGetDataStack(pVM), -1); } } static void ficlEfiUnsetenv(ficlVm *pVM) { char *name; char *namep; int names; FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0); names = ficlStackPopInteger(ficlVmGetDataStack(pVM)); namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM)); name = ficlMalloc(names+1); if (name == NULL) ficlVmThrowError(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; unsetenv(name); ficlFree(name); } /* * Build platform extensions into the system dictionary */ static void ficlEfiCompilePlatform(ficlSystem *pSys) { ficlDictionary *dp = ficlSystemGetDictionary(pSys); FICL_SYSTEM_ASSERT(pSys, dp); ficlDictionarySetPrimitive(dp, "efi-setenv", ficlEfiSetenv, FICL_WORD_DEFAULT); ficlDictionarySetPrimitive(dp, "efi-getenv", ficlEfiGetenv, FICL_WORD_DEFAULT); ficlDictionarySetPrimitive(dp, "efi-unsetenv", ficlEfiUnsetenv, FICL_WORD_DEFAULT); } FICL_COMPILE_SET(ficlEfiCompilePlatform); /* * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include #include #include EFI_STATUS errno_to_efi_status(int errno) { EFI_STATUS status; switch (errno) { case EPERM: status = EFI_ACCESS_DENIED; break; case EOVERFLOW: status = EFI_BUFFER_TOO_SMALL; break; case EIO: status = EFI_DEVICE_ERROR; break; case EINVAL: status = EFI_INVALID_PARAMETER; break; case ESTALE: status = EFI_MEDIA_CHANGED; break; case ENXIO: status = EFI_NO_MEDIA; break; case ENOENT: status = EFI_NOT_FOUND; break; case ENOMEM: status = EFI_OUT_OF_RESOURCES; break; case ENOTSUP: case ENODEV: status = EFI_UNSUPPORTED; break; case ENOSPC: status = EFI_VOLUME_FULL; break; case EACCES: status = EFI_WRITE_PROTECTED; break; case 0: status = EFI_SUCCESS; break; default: status = EFI_DEVICE_ERROR; break; } return (status); } int efi_status_to_errno(EFI_STATUS status) { int errno; switch (status) { case EFI_ACCESS_DENIED: errno = EPERM; break; case EFI_BUFFER_TOO_SMALL: errno = EOVERFLOW; break; case EFI_DEVICE_ERROR: case EFI_VOLUME_CORRUPTED: errno = EIO; break; case EFI_INVALID_PARAMETER: errno = EINVAL; break; case EFI_MEDIA_CHANGED: errno = ESTALE; break; case EFI_NO_MEDIA: errno = ENXIO; break; case EFI_NOT_FOUND: errno = ENOENT; break; case EFI_OUT_OF_RESOURCES: errno = ENOMEM; break; case EFI_UNSUPPORTED: errno = ENODEV; break; case EFI_VOLUME_FULL: errno = ENOSPC; break; case EFI_WRITE_PROTECTED: errno = EACCES; break; case 0: errno = 0; break; default: errno = EDOOFUS; break; } return (errno); } /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include __FBSDID("$FreeBSD$"); #include #include struct entry { EFI_HANDLE handle; EFI_HANDLE alias; struct devsw *dev; int unit; uint64_t extra; }; struct entry *entry; int nentries; int efi_register_handles(struct devsw *sw, EFI_HANDLE *handles, EFI_HANDLE *aliases, int count) { size_t sz; int idx, unit; idx = nentries; nentries += count; sz = nentries * sizeof(struct entry); entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz); for (unit = 0; idx < nentries; idx++, unit++) { entry[idx].handle = handles[unit]; if (aliases != NULL) entry[idx].alias = aliases[unit]; else entry[idx].alias = NULL; entry[idx].dev = sw; entry[idx].unit = unit; } return (0); } EFI_HANDLE efi_find_handle(struct devsw *dev, int unit) { int idx; for (idx = 0; idx < nentries; idx++) { if (entry[idx].dev != dev) continue; if (entry[idx].unit != unit) continue; return (entry[idx].handle); } return (NULL); } int efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit, uint64_t *extra) { int idx; for (idx = 0; idx < nentries; idx++) { if (entry[idx].handle != h && entry[idx].alias != h) continue; if (dev != NULL) *dev = entry[idx].dev; if (unit != NULL) *unit = entry[idx].unit; if (extra != NULL) *extra = entry[idx].extra; return (0); } return (ENOENT); } int efi_handle_update_dev(EFI_HANDLE h, struct devsw *dev, int unit, uint64_t guid) { int idx; for (idx = 0; idx < nentries; idx++) { if (entry[idx].handle != h) continue; entry[idx].dev = dev; entry[idx].unit = unit; entry[idx].alias = NULL; entry[idx].extra = guid; return (0); } return (ENOENT); } /* * Copyright (c) 2000 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include #include #include EFI_HANDLE IH; EFI_SYSTEM_TABLE *ST; EFI_BOOT_SERVICES *BS; EFI_RUNTIME_SERVICES *RS; void * efi_get_table(EFI_GUID *tbl) { EFI_GUID *id; int i; for (i = 0; i < ST->NumberOfTableEntries; i++) { id = &ST->ConfigurationTable[i].VendorGuid; if (memcmp(id, tbl, sizeof (EFI_GUID)) == 0) return (ST->ConfigurationTable[i].VendorTable); } return (NULL); } EFI_STATUS OpenProtocolByHandle(EFI_HANDLE handle, EFI_GUID *protocol, void **interface) { return (BS->OpenProtocol(handle, protocol, interface, IH, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); } /* * Allocate memory and query list of handles for indicated protocol. * Returns EFI status, list of handles and number of handles in list. * Caller needs to release the allocated memory. */ EFI_STATUS efi_get_protocol_handles(EFI_GUID *protocolguid, uint_t *nhandles, EFI_HANDLE **handlep) { UINTN bufsz = 0; EFI_STATUS status; EFI_HANDLE *handles; /* * get buffer size */ *nhandles = 0; handles = NULL; status = BS->LocateHandle(ByProtocol, protocolguid, NULL, &bufsz, handles); if (status != EFI_BUFFER_TOO_SMALL) return (status); handles = malloc(bufsz); if (handles == NULL) return (errno_to_efi_status(ENOMEM)); *nhandles = (uint_t)(bufsz / sizeof (EFI_HANDLE)); /* * get handle array */ status = BS->LocateHandle(ByProtocol, protocolguid, NULL, &bufsz, handles); if (EFI_ERROR(status)) { free(handles); *nhandles = 0; } else { *handlep = handles; } return (status); } /* * Copyright (c) 1999, 2000 * Intel Corporation. * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * * This product includes software developed by Intel Corporation and * its contributors. * * 4. Neither the name of Intel Corporation or its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. * */ #include #include #include #include #include /* * Accurate only for the past couple of centuries; * that will probably do. * * (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) */ #define isleap(y) (((y) % 4) == 0 && \ (((y) % 100) != 0 || ((y) % 400) == 0)) #define SECSPERHOUR (60*60) #define SECSPERDAY (24 * SECSPERHOUR) /* * These arrays give the cumulative number of days up to the first of the * month number used as the index (1 -> 12) for regular and leap years. * The value at index 13 is for the whole year. */ static const time_t CumulativeDays[2][14] = { {0, 0, 31, 31 + 28, 31 + 28 + 31, 31 + 28 + 31 + 30, 31 + 28 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, {0, 0, 31, 31 + 29, 31 + 29 + 31, 31 + 29 + 31 + 30, 31 + 29 + 31 + 30 + 31, 31 + 29 + 31 + 30 + 31 + 30, 31 + 29 + 31 + 30 + 31 + 30 + 31, 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; void efi_time_init(void) { } void efi_time_fini(void) { } void to_efi_time(EFI_TIME *efi_time, time_t time) { int lyear, month; time_t seconds; if (time >= 0) { efi_time->Year = 1970; lyear = isleap(efi_time->Year); month = 13; seconds = CumulativeDays[lyear][month] * SECSPERDAY; while (time > seconds) { time -= seconds; efi_time->Year++; lyear = isleap(efi_time->Year); seconds = CumulativeDays[lyear][month] * SECSPERDAY; } efi_time->Month = 0; while (time > CumulativeDays[lyear][efi_time->Month] * SECSPERDAY) { efi_time->Month++; } month = efi_time->Month - 1; time -= CumulativeDays[lyear][month] * SECSPERDAY; for (efi_time->Day = 0; time > SECSPERDAY; efi_time->Day++) time -= SECSPERDAY; for (efi_time->Hour = 0; time > SECSPERHOUR; efi_time->Hour++) time -= SECSPERHOUR; for (efi_time->Minute = 0; time > 60; efi_time->Minute++) time -= 60; efi_time->Second = time; efi_time->Nanosecond = 0; efi_time->TimeZone = 0; efi_time->Daylight = 0; } else { memset(efi_time, 0, sizeof (EFI_TIME)); } } time_t from_efi_time(EFI_TIME *ETime) { time_t UTime; int Year; /* * Do a santity check */ if (ETime->Year < 1998 || ETime->Year > 2099 || ETime->Month == 0 || ETime->Month > 12 || ETime->Day == 0 || ETime->Month > 31 || ETime->Hour > 23 || ETime->Minute > 59 || ETime->Second > 59 || ETime->TimeZone < -1440 || (ETime->TimeZone > 1440 && ETime->TimeZone != 2047)) { return (0); } /* * Years */ UTime = 0; for (Year = 1970; Year != ETime->Year; ++Year) { UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); } /* * UTime should now be set to 00:00:00 on Jan 1 of the file's year. * * Months */ UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); /* * UTime should now be set to 00:00:00 on the first of the file's * month and year. * * Days -- Don't count the file's day */ UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); /* * Hours */ UTime += (ETime->Hour * SECSPERHOUR); /* * Minutes */ UTime += (ETime->Minute * 60); /* * Seconds */ UTime += ETime->Second; /* * EFI time is repored in local time. Adjust for any time zone * offset to get true UT */ if (ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { /* * TimeZone is kept in minues... */ UTime += (ETime->TimeZone * 60); } return (UTime); } static int EFI_GetTimeOfDay(OUT struct timeval *tp, OUT struct timezone *tzp) { EFI_TIME EfiTime; EFI_TIME_CAPABILITIES Capabilities; EFI_STATUS Status; /* * Get time from EFI */ Status = RS->GetTime(&EfiTime, &Capabilities); if (EFI_ERROR(Status)) return (-1); /* * Convert to UNIX time (ie seconds since the epoch) */ tp->tv_sec = from_efi_time(&EfiTime); tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ /* * Do something with the timezone if needed */ if (tzp != NULL) { if (EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) tzp->tz_minuteswest = 0; else tzp->tz_minuteswest = EfiTime.TimeZone; /* * This isn't quit right since it doesn't deal with * EFI_TIME_IN_DAYLIGHT */ tzp->tz_dsttime = EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; } return (0); } time_t time(time_t *tloc) { struct timeval tv; memset(&tv, 0, sizeof (tv)); EFI_GetTimeOfDay(&tv, NULL); if (tloc) *tloc = tv.tv_sec; return (tv.tv_sec); } time_t getsecs(void) { return (time(NULL)); } /* * Copyright (c) 2016 Andrew Turner * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include static EFI_EVENT time_event; static uint64_t curtime; static void time_update(EFI_EVENT event, void *context) { curtime++; } void efi_time_init(void) { /* Create a timer event */ BS->CreateEvent(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, time_update, 0, &time_event); /* Use a 1s timer */ BS->SetTimer(time_event, TimerPeriodic, 10000000); } void efi_time_fini(void) { /* Cancel the timer */ BS->SetTimer(time_event, TimerCancel, 0); BS->CloseEvent(time_event); } time_t time(time_t *tloc) { time_t t; t = curtime; if (tloc != NULL) *tloc = t; return (t); } time_t getsecs(void) { return (time(0)); } /*- * Copyright 2016 Netflix, Inc. All Rights Reserved. * * 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. * * 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. */ #include #include #include /* * CHAR16 related functions moved from loader. * Perhaps we should move those to libstand afterall, but they are * needed only by UEFI. */ int wcscmp(CHAR16 *a, CHAR16 *b) { while (*a && *b && *a == *b) { a++; b++; } return *a - *b; } /* * cpy8to16 copies a traditional C string into a CHAR16 string and * 0 terminates it. len is the size of *dst in bytes. */ void cpy8to16(const char *src, CHAR16 *dst, size_t len) { len <<= 1; /* Assume CHAR16 is 2 bytes */ while (len > 0 && *src) { *dst++ = *src++; len--; } *dst++ = (CHAR16)0; } void cpy16to8(const CHAR16 *src, char *dst, size_t len) { size_t i; for (i = 0; i < len && src[i]; i++) dst[i] = (char)src[i]; if (i < len) dst[i] = '\0'; } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # .KEEP_STATE: include $(SRC)/Makefile.master SUBDIRS = $(MACH64) all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber install : TARGET = install all clean clobber install: $(SUBDIRS) .PARALLEL: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # include $(SRC)/boot/Makefile.version include $(SRC)/boot/Makefile.inc PROG= loader.sym # architecture-specific loader code OBJS= \ acpi.o \ autoload.o \ bootinfo.o \ conf.o \ copy.o \ efi_main.o \ font.o \ $(FONT).o \ framebuffer.o \ main.o \ memmap.o \ mb_header.o \ multiboot2.o \ nvstore.o \ self_reloc.o \ tem.o \ vers.o module.o : CPPFLAGS += -I$(CRYPTOSRC) tem.o : CPPFLAGS += $(DEFAULT_CONSOLE_COLOR) main.o : CPPFLAGS += -I$(SRC)/uts/common/fs/zfs CPPFLAGS += -I../../../include -I../../../sys CPPFLAGS += -I../../../libsa include ../../Makefile.inc include ../arch/$(MACHINE)/Makefile.inc CPPFLAGS += -I. -I.. CPPFLAGS += -I../../include CPPFLAGS += -I../../include/$(MACHINE) CPPFLAGS += -I$(ZFSSRC) CPPFLAGS += -I../../../sys/cddl/boot/zfs CPPFLAGS += -I$(SRC)/uts/intel/sys/acpi CPPFLAGS += -I$(PNGLITE) CPPFLAGS += -DNO_PCI -DEFI DPLIBSA= ../../../libsa/$(MACHINE)/libsa_pics.a LIBSA= -L../../../libsa/$(MACHINE) -lsa_pics BOOT_FORTH= yes CPPFLAGS += -DBOOT_FORTH CPPFLAGS += -I$(SRC)/common/ficl CPPFLAGS += -I../../../libficl DPLIBFICL= ../../../libficl/$(MACHINE)/libficl_pics.a LIBFICL= -L../../../libficl/$(MACHINE) -lficl_pics # Always add MI sources # OBJS += boot.o commands.o console.o devopen.o interp.o \ interp_backslash.o interp_parse.o ls.o misc.o \ module.o linenoise.o zfs_cmd.o OBJS += load_elf32.o load_elf32_obj.o reloc_elf32.o \ load_elf64.o load_elf64_obj.o reloc_elf64.o OBJS += disk.o part.o dev_net.o vdisk.o CPPFLAGS += -DLOADER_DISK_SUPPORT CPPFLAGS += -DLOADER_GPT_SUPPORT CPPFLAGS += -DLOADER_MBR_SUPPORT part.o : CPPFLAGS += -I$(ZLIB) OBJS += bcache.o # Forth interpreter OBJS += interp_forth.o CPPFLAGS += -I../../../common # For multiboot2.h, must be last, to avoid conflicts CPPFLAGS += -I$(SRC)/uts/common FILES= $(EFIPROG) FILEMODE= 0555 ROOT_BOOT= $(ROOT)/boot ROOTBOOTFILES=$(FILES:%=$(ROOT_BOOT)/%) LDSCRIPT= ../arch/$(MACHINE)/ldscript.$(MACHINE) LDFLAGS = -nostdlib --eh-frame-hdr LDFLAGS += -shared --hash-style=both --enable-new-dtags LDFLAGS += -T$(LDSCRIPT) -Bsymbolic CLEANFILES= $(EFIPROG) loader.sym loader.bin CLEANFILES += $(FONT).c vers.c NEWVERSWHAT= "EFI loader" $(MACHINE) install: all $(ROOTBOOTFILES) vers.c: ../../../common/newvers.sh $(SRC)/boot/Makefile.version $(SH) ../../../common/newvers.sh $(LOADER_VERSION) $(NEWVERSWHAT) $(EFIPROG): loader.bin $(BTXLD) -V $(BOOT_VERSION) -o $@ loader.bin loader.bin: loader.sym if [ `$(OBJDUMP) -t loader.sym | fgrep '*UND*' | wc -l` != 0 ]; then \ $(OBJDUMP) -t loader.sym | fgrep '*UND*'; \ exit 1; \ fi $(OBJCOPY) --readonly-text -j .peheader -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ -j set_Xficl_compile_set \ --output-target=$(EFI_TARGET) --subsystem efi-app loader.sym $@ DPLIBEFI= ../../libefi/$(MACHINE)/libefi.a LIBEFI= -L../../libefi/$(MACHINE) -lefi DPADD= $(DPLIBFICL) $(DPLIBEFI) $(DPLIBSA) $(LDSCRIPT) LDADD= $(LIBFICL) $(LIBEFI) $(LIBSA) loader.sym: $(OBJS) $(DPADD) $(GLD) $(LDFLAGS) -o $@ $(OBJS) $(LDADD) machine: $(RM) machine $(SYMLINK) ../../../sys/$(MACHINE)/include machine x86: $(RM) x86 $(SYMLINK) ../../../sys/x86/include x86 clean clobber: $(RM) $(CLEANFILES) $(OBJS) machine x86 %.o: ../%.c $(COMPILE.c) $< %.o: ../arch/$(MACHINE)/%.c $(COMPILE.c) $< # # using -W to silence gas here, as for 32bit build, it will generate warning # for start.S because hand crafted .reloc section does not have group name # %.o: ../arch/$(MACHINE)/%.S $(COMPILE.S) -Wa,-W $< %.o: ../../../common/%.S $(COMPILE.S) $< %.o: ../../../common/%.c $(COMPILE.c) $< %.o: ../../../common/linenoise/%.c $(COMPILE.c) $< %.o: $(SRC)/common/font/%.c $(COMPILE.c) $< $(FONT).c: $(FONT_DIR)/$(FONT_SRC) $(VTFONTCVT) -f compressed-source -o $@ $(FONT_DIR)/$(FONT_SRC) $(ROOT_BOOT)/%: % $(INS.file) /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2016 Tooams Soome */ #include #include #include #include #include #include #include #include "platform/acfreebsd.h" #include "acconfig.h" #define ACPI_SYSTEM_XFACE #include "actypes.h" #include "actbl.h" ACPI_TABLE_RSDP *rsdp; EFI_GUID gEfiAcpiTableGuid = ACPI_TABLE_GUID; EFI_GUID gEfiAcpi20TableGuid = EFI_ACPI_TABLE_GUID; void acpi_detect(void) { char buf[24]; int revision; if ((rsdp = efi_get_table(&gEfiAcpi20TableGuid)) == NULL) rsdp = efi_get_table(&gEfiAcpiTableGuid); if (rsdp == NULL) return; /* export values from the RSDP */ #ifdef _LP64 snprintf(buf, sizeof (buf), "0x%016llx", (unsigned long long)rsdp); #else snprintf(buf, sizeof (buf), "0x%08x", (unsigned int)rsdp); #endif setenv("acpi.rsdp", buf, 1); revision = rsdp->Revision; if (revision == 0) revision = 1; snprintf(buf, sizeof (buf), "%d", revision); setenv("acpi.revision", buf, 1); strncpy(buf, rsdp->OemId, sizeof (rsdp->OemId)); buf[sizeof (rsdp->OemId)] = '\0'; setenv("acpi.oem", buf, 1); #ifdef _LP64 snprintf(buf, sizeof (buf), "0x%016llx", (unsigned long long)rsdp->RsdtPhysicalAddress); #else snprintf(buf, sizeof (buf), "0x%08x", rsdp->RsdtPhysicalAddress); #endif setenv("acpi.rsdt", buf, 1); if (revision >= 2) { snprintf(buf, sizeof (buf), "0x%016llx", (unsigned long long)rsdp->XsdtPhysicalAddress); setenv("acpi.xsdt", buf, 1); snprintf(buf, sizeof (buf), "%d", rsdp->Length); setenv("acpi.xsdt_length", buf, 1); } } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2016 RackTop Systems. # include $(SRC)/Makefile.master MACHINE= $(MACH64) EFIPROG= loader64.efi all: $(EFIPROG) include ../Makefile.com EFI_TARGET= pei-x86-64 LDFLAGS += -znocombreloc efi_main.o : CPPFLAGS += -DLOADER_EFI=L\"loader64.efi\" CFLAGS += -m64 $(CFLAGS64) CCASFLAGS += -m64 CLEANFILES += machine x86 $(EFIPROG) $(OBJS): machine x86 %.o: ../../../i386/libi386/%.c $(COMPILE.c) $< # Hammerhead: Removed cpuid.o, nullconsole.o, spinconsole.o — their source # files were in i386/libi386/ which was deleted with 32-bit removal (f12667bd). OBJS += multiboot_tramp.o \ start.o \ trap.o \ exec.o \ exc.o /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. * 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. * * 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. * * $FreeBSD$ */ #include .text .globl amd64_tramp /* * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend, * uint64_t modulep, uint64_t pagetable, uint64_t entry) */ amd64_tramp: cli /* Make sure we don't get interrupted. */ movq %rdi,%rsp /* Switch to our temporary stack. */ movq %rdx,%r12 /* Stash the kernel values for later. */ movq %rcx,%r13 movq %r8,%r14 movq %r9,%r15 callq *%rsi /* Call copy_finish so we're all ready to go. */ pushq %r12 /* Push kernend. */ salq $32,%r13 /* Shift modulep and push it. */ pushq %r13 pushq %r15 /* Push the entry address. */ movq %r14,%cr3 /* Switch page tables. */ ret /* "Return" to kernel entry. */ ALIGN_TEXT amd64_tramp_end: .data .globl amd64_tramp_size amd64_tramp_size: .long amd64_tramp_end-amd64_tramp /*- * Copyright (c) 1998 Michael Smith * Copyright (c) 2014 The FreeBSD Foundation * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "platform/acfreebsd.h" #include "acconfig.h" #define ACPI_SYSTEM_XFACE #include "actypes.h" #include "actbl.h" #include "loader_efi.h" static EFI_GUID acpi_guid = ACPI_TABLE_GUID; static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); static struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; static struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; struct file_format *file_formats[] = { &amd64_elf, &amd64_elf_obj, NULL }; #define PG_V 0x001 #define PG_RW 0x002 #define PG_U 0x004 #define PG_PS 0x080 typedef u_int64_t p4_entry_t; typedef u_int64_t p3_entry_t; typedef u_int64_t p2_entry_t; static p4_entry_t *PT4; static p3_entry_t *PT3; static p2_entry_t *PT2; static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, uint64_t modulep, p4_entry_t *pagetable, uint64_t entry); extern uintptr_t amd64_tramp; extern uint32_t amd64_tramp_size; /* * There is an ELF kernel and one or more ELF modules loaded. * We wish to start executing the kernel image, so make such * preparations as are required, and do so. */ static int elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *ehdr; vm_offset_t modulep, kernend, trampcode, trampstack; int err, i; ACPI_TABLE_RSDP *rsdp; char buf[24]; int revision; rsdp = efi_get_table(&acpi20_guid); if (rsdp == NULL) { rsdp = efi_get_table(&acpi_guid); } if (rsdp != NULL) { sprintf(buf, "0x%016llx", (unsigned long long)rsdp); setenv("hint.acpi.0.rsdp", buf, 1); revision = rsdp->Revision; if (revision == 0) revision = 1; sprintf(buf, "%d", revision); setenv("hint.acpi.0.revision", buf, 1); strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); buf[sizeof(rsdp->OemId)] = '\0'; setenv("hint.acpi.0.oem", buf, 1); sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); setenv("hint.acpi.0.rsdt", buf, 1); if (revision >= 2) { /* XXX extended checksum? */ sprintf(buf, "0x%016llx", (unsigned long long)rsdp->XsdtPhysicalAddress); setenv("hint.acpi.0.xsdt", buf, 1); sprintf(buf, "%d", rsdp->Length); setenv("hint.acpi.0.xsdt_length", buf, 1); } } if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); trampcode = (vm_offset_t)0x0000000040000000; err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, (EFI_PHYSICAL_ADDRESS *)&trampcode); bzero((void *)trampcode, EFI_PAGE_SIZE); trampstack = trampcode + EFI_PAGE_SIZE - 8; bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); trampoline = (void *)trampcode; PT4 = (p4_entry_t *)0x0000000040000000; err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, (EFI_PHYSICAL_ADDRESS *)&PT4); bzero(PT4, 3 * EFI_PAGE_SIZE); PT3 = &PT4[512]; PT2 = &PT3[512]; /* * This is kinda brutal, but every single 1GB VM memory segment points * to the same first 1GB of physical memory. But it is more than * adequate. */ for (i = 0; i < 512; i++) { /* Each slot of the L4 pages points to the same L3 page. */ PT4[i] = (p4_entry_t)PT3; PT4[i] |= PG_V | PG_RW | PG_U; /* Each slot of the L3 pages points to the same L2 page. */ PT3[i] = (p3_entry_t)PT2; PT3[i] |= PG_V | PG_RW | PG_U; /* The L2 page slots are mapped with 2MB pages for 1GB. */ PT2[i] = i * (2 * 1024 * 1024); PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; } printf("Start @ 0x%lx ...\n", ehdr->e_entry); efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernend); if (err != 0) { efi_time_init(); return(err); } dev_cleanup(); trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4, ehdr->e_entry); panic("exec returned"); } static int elf64_obj_exec(struct preloaded_file *fp __attribute((unused))) { return (EFTYPE); } /*- * Copyright (c) 2016 The FreeBSD Foundation * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. * * 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. * * 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. */ .macro EH N, err=1 .align 8 .globl EXC\N\()_handler EXC\N\()_handler: .if \err != 1 pushq $0 .endif pushq %rax pushq %rdx pushq %rcx movl $\N,%ecx jmp all_handlers .endm .text EH 0,0 EH 1,0 EH 2,0 EH 3,0 EH 4,0 EH 5,0 EH 6,0 EH 7,0 EH 8 EH 9,0 EH 10 EH 11 EH 12 EH 13 EH 14 EH 16,0 EH 17 EH 18,0 EH 19,0 EH 20,0 .globl exc_rsp all_handlers: cmpq %rsp,exc_rsp(%rip) je exception /* * Interrupt, not exception. * First, copy the hardware interrupt frame to the previous stack. * Our handler always has private IST stack. */ movq (6*8)(%rsp),%rax /* saved %rsp value, AKA old stack */ subq (5*8),%rax movq (3*8)(%rsp),%rdx /* copy %rip to old stack */ movq %rdx,(%rax) movq (4*8)(%rsp),%rdx /* copy %cs */ movq %rdx,(1*8)(%rax) movq (5*8)(%rsp),%rdx /* copy %rflags */ movq %rdx,(2*8)(%rax) movq (6*8)(%rsp),%rdx /* copy %rsp */ movq %rdx,(3*8)(%rax) movq (7*8)(%rsp),%rdx /* copy %ss */ movq %rdx,(4*8)(%rax) /* * Now simulate invocation of the original interrupt handler * with retq. We switch stacks and execute retq from the old * stack since there is no free registers at the last moment. */ subq $16,%rax leaq fw_intr_handlers(%rip),%rdx movq (%rdx,%rcx,8),%rdx /* push intr handler address on old stack */ movq %rdx,8(%rax) movq (2*8)(%rsp),%rcx /* saved %rax is put on top of old stack */ movq %rcx,(%rax) movq (%rsp),%rcx movq 8(%rsp),%rdx movq 32(%rsp),%rsp /* switch to old stack */ popq %rax retq exception: /* * Form the struct trapframe on our IST stack. * Skip three words, which are currently busy with temporal * saves. */ pushq %r15 pushq %r14 pushq %r13 pushq %r12 pushq %r11 pushq %r10 pushq %rbp pushq %rbx pushq $0 /* %rax */ pushq %r9 pushq %r8 pushq $0 /* %rcx */ pushq $0 /* %rdx */ pushq %rsi pushq %rdi /* * Move %rax, %rdx, %rcx values into the final location, * from the three words which were skipped above. */ movq 0x88(%rsp),%rax movq %rax,0x30(%rsp) /* tf_rax */ movq 0x78(%rsp),%rax movq %rax,0x18(%rsp) /* tf_rcx */ movq 0x80(%rsp),%rax movq %rax,0x10(%rsp) /* tf_rdx */ /* * And fill the three words themself. */ movq %cr2,%rax movq %rax,0x80(%rsp) /* tf_addr */ movl %ecx,0x78(%rsp) /* tf_trapno */ movw %ds,0x8e(%rsp) movw %es,0x8c(%rsp) movw %fs,0x7c(%rsp) movw %gs,0x7e(%rsp) movw $0,0x88(%rsp) /* tf_flags */ /* * Call dump routine. */ movq %rsp,%rdi callq report_exc /* * Hang after reporting. Interrupts are already disabled. */ 1: hlt jmp 1b /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2023 Toomas Soome */ #include #include #include extern struct file_format multiboot2; struct file_format *file_formats[] = { &multiboot2, NULL }; OUTPUT_FORMAT("elf64-x86-64-sol2", "elf64-x86-64-sol2", "elf64-x86-64-sol2") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0; ImageBase = .; .hash : { *(.hash) } /* this MUST come first! */ . = ALIGN(4096); .text : { mb_header.o(.text) *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.plt) } =0xCCCCCCCC . = ALIGN(4096); .eh_frame : { *(.eh_frame) } . = ALIGN(4096); .data : { *(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata1) *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) *(.opd) *(.data .data.* .gnu.linkonce.d.*) *(.data1) *(.plabel) *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) } . = ALIGN(4096); set_Xcommand_set : { __start_set_Xcommand_set = .; *(set_Xcommand_set) __stop_set_Xcommand_set = .; } set_Xficl_compile_set : { __start_set_Xficl_compile_set = .; *(set_Xficl_compile_set) __stop_set_Xficl_compile_set = .; } . = ALIGN(4096); __gp = .; .sdata : { *(.got.plt .got) *(.sdata .sdata.* .gnu.linkonce.s.*) *(dynsbss) *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) } . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); .rela.dyn : { *(.rela.data*) *(.rela.got) *(.rela.stab) *(.relaset_*) } . = ALIGN(4096); .reloc : { *(.reloc) } . = ALIGN(4096); .dynsym : { *(.dynsym) } . = ALIGN(4096); .dynstr : { *(.dynstr) } } /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2016 Toomas Soome */ #include .file "multiboot_tramp.s" /* * dboot expects a 32-bit multiboot environment and to execute in 32-bit mode. * * EAX: MB magic * EBX: 32-bit physical address of MBI * CS: 32-bit read/execute code segment with offset 0 and limit 0xFFFFFFFF * DS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * ES: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * FS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * GS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * SS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * A20 enabled * CR0: PG cleared, PE set * EFLAGS: VM cleared, IF cleared * interrupts disabled */ .set SEL_SCODE,0x8 .set SEL_SDATA,0x10 .text .p2align 4 .globl multiboot_tramp .type multiboot_tramp, STT_FUNC /* * void multiboot_tramp(uint32_t magic, struct relocator *relocator, * vm_offset_t entry) */ multiboot_tramp: cli movq (%rsi), %rax movq %rax, %rsp /* Switch to temporary stack. */ movq 0x8(%rsi), %rax /* relocator->copy */ pushq %rdi /* save magic */ pushq %rdx /* save entry */ movq %rsi, %rdi callq *%rax movq %rax, %rbx /* MBI */ popq %rsi /* entry to rsi */ popq %rdi /* restore magic */ lea gdt(%rip), %rax lea gdtaddr(%rip), %rdx movq %rax, (%rdx) lea gdtdesc(%rip), %rax lgdt (%rax) /* record the address */ lea multiboot_tramp_2(%rip), %rcx movq %rsp, %rax pushq $SEL_SDATA pushq %rax pushf pushq $SEL_SCODE lea multiboot_tramp_1(%rip), %rax pushq %rax iretq .code32 multiboot_tramp_1: movl $SEL_SDATA, %eax movw %ax, %ss movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movl %cr0, %eax /* disable paging */ btrl $31, %eax movl %eax, %cr0 jmp *%ecx multiboot_tramp_2: movl %cr4, %eax /* disable PAE, PGE, PSE */ andl $~(CR4_PGE | CR4_PAE | CR4_PSE), %eax movl %eax, %cr4 movl $MSR_EFER, %ecx rdmsr /* updates %edx:%eax */ btcl $8, %eax /* clear long mode */ wrmsr movl %edi, %eax /* magic */ jmp *%esi /* jump to kernel */ /* GDT record */ .p2align 4 gdt: /* * This will create access for 4GB flat memory with * base = 0x00000000, segment limit = 0xffffffff * page granulariy 4k * 32-bit protected mode * ring 0 * code segment is executable RW * data segment is not-executable RW */ .word 0x0, 0x0 /* NULL entry */ .byte 0x0, 0x0, 0x0, 0x0 .word 0xffff, 0x0 /* code segment */ .byte 0x0, 0x9a, 0xcf, 0x0 .word 0xffff, 0x0 /* data segment */ .byte 0x0, 0x92, 0xcf, 0x0 gdt_end: .p2align 4 gdtdesc: .word gdt_end - gdt - 1 /* limit */ gdtaddr: .long 0 /* base */ .long 0 multiboot_tramp_end: /*- * Copyright (C) 1999 Hewlett-Packard Co. * Contributed by David Mosberger . * Copyright (C) 2005 Intel Co. * Contributed by Fenghua Yu . * All rights reserved. * * 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. Neither the name of Hewlett-Packard Co. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT * OWNER 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. */ /* * crt0-efi-x86_64.S - x86_64 EFI startup code. * $FreeBSD$ */ .text .align 4 .globl _start _start: subq $8, %rsp pushq %rcx pushq %rdx 0: lea ImageBase(%rip), %rdi lea _DYNAMIC(%rip), %rsi popq %rcx popq %rdx pushq %rcx pushq %rdx call self_reloc popq %rdi popq %rsi call efi_main addq $8, %rsp .exit: ret /* * hand-craft a dummy .reloc section so EFI knows it's a relocatable * executable: */ .data .section .reloc, "a" .long 0 .long 10 .word 0 /* * Copyright (c) 2016 The FreeBSD Foundation * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "loader_efi.h" #define NUM_IST 8 #define NUM_EXC 32 /* * This code catches exceptions but forwards hardware interrupts to * handlers installed by firmware. It differentiates exceptions * vs. interrupts by presence of the error code on the stack, which * causes different stack pointer value on trap handler entry. * * Use kernel layout for the trapframe just to not be original. * * Use free IST slot in existing TSS, or create our own TSS if * firmware did not configured any, to have stack switched to * IST-specified one, e.g. to handle #SS. If hand-off cannot find * unused IST slot, or create a new descriptor in GDT, we bail out. */ static struct region_descriptor fw_idt; /* Descriptor for pristine fw IDT */ static struct region_descriptor loader_idt; /* Descriptor for loader shadow IDT */ static EFI_PHYSICAL_ADDRESS lidt_pa; /* Address of loader shadow IDT */ static EFI_PHYSICAL_ADDRESS tss_pa; /* Address of TSS */ static EFI_PHYSICAL_ADDRESS exc_stack_pa; /* Address of IST stack for loader */ EFI_PHYSICAL_ADDRESS exc_rsp; /* %rsp value on our IST stack when exception happens */ EFI_PHYSICAL_ADDRESS fw_intr_handlers[NUM_EXC]; /* fw handlers for < 32 IDT vectors */ static int intercepted[NUM_EXC]; static int ist; /* IST for exception handlers */ static uint32_t tss_fw_seg; /* Fw TSS segment */ static uint32_t loader_tss; /* Loader TSS segment */ static struct region_descriptor fw_gdt; /* Descriptor of pristine GDT */ static EFI_PHYSICAL_ADDRESS loader_gdt_pa; /* Address of loader shadow GDT */ void report_exc(struct trapframe *tf); void report_exc(struct trapframe *tf) { /* * printf() depends on loader runtime and UEFI firmware health * to produce the console output, in case of exception, the * loader or firmware runtime may fail to support the printf(). */ printf("====================================================" "============================\n"); printf("Exception %u\n", tf->tf_trapno); printf("ss 0x%04hx cs 0x%04hx ds 0x%04hx es 0x%04hx fs 0x%04hx " "gs 0x%04hx\n", (uint16_t)tf->tf_ss, (uint16_t)tf->tf_cs, (uint16_t)tf->tf_ds, (uint16_t)tf->tf_es, (uint16_t)tf->tf_fs, (uint16_t)tf->tf_gs); printf("err 0x%08x rfl 0x%08x addr 0x%016lx\n" "rsp 0x%016lx rip 0x%016lx\n", (uint32_t)tf->tf_err, (uint32_t)tf->tf_rflags, tf->tf_addr, tf->tf_rsp, tf->tf_rip); printf( "rdi 0x%016lx rsi 0x%016lx rdx 0x%016lx\n" "rcx 0x%016lx r8 0x%016lx r9 0x%016lx\n" "rax 0x%016lx rbx 0x%016lx rbp 0x%016lx\n" "r10 0x%016lx r11 0x%016lx r12 0x%016lx\n" "r13 0x%016lx r14 0x%016lx r15 0x%016lx\n", tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_rcx, tf->tf_r8, tf->tf_r9, tf->tf_rax, tf->tf_rbx, tf->tf_rbp, tf->tf_r10, tf->tf_r11, tf->tf_r12, tf->tf_r13, tf->tf_r14, tf->tf_r15); printf("Machine stopped.\n"); } static void prepare_exception(unsigned idx, uint64_t my_handler, int ist_use_table[static NUM_IST]) { struct gate_descriptor *fw_idt_e, *loader_idt_e; fw_idt_e = &((struct gate_descriptor *)fw_idt.rd_base)[idx]; loader_idt_e = &((struct gate_descriptor *)loader_idt.rd_base)[idx]; fw_intr_handlers[idx] = fw_idt_e->gd_looffset + (fw_idt_e->gd_hioffset << 16); intercepted[idx] = 1; ist_use_table[fw_idt_e->gd_ist]++; loader_idt_e->gd_looffset = my_handler; loader_idt_e->gd_hioffset = my_handler >> 16; /* * We reuse uefi selector for the code segment for the exception * handler code, while the reason for the fault might be the * corruption of that gdt entry. On the other hand, allocating * our own descriptor might be not much better, if gdt is corrupted. */ loader_idt_e->gd_selector = fw_idt_e->gd_selector; loader_idt_e->gd_ist = 0; loader_idt_e->gd_type = SDT_SYSIGT; loader_idt_e->gd_dpl = 0; loader_idt_e->gd_p = 1; loader_idt_e->gd_xx = 0; loader_idt_e->sd_xx1 = 0; } #define PREPARE_EXCEPTION(N) \ extern char EXC##N##_handler[]; \ prepare_exception(N, (uintptr_t)EXC##N##_handler, ist_use_table); static void free_tables(void) { if (lidt_pa != 0) { BS->FreePages(lidt_pa, EFI_SIZE_TO_PAGES(fw_idt.rd_limit)); lidt_pa = 0; } if (exc_stack_pa != 0) { BS->FreePages(exc_stack_pa, 1); exc_stack_pa = 0; } if (tss_pa != 0 && tss_fw_seg == 0) { BS->FreePages(tss_pa, EFI_SIZE_TO_PAGES(sizeof (struct amd64tss))); tss_pa = 0; } if (loader_gdt_pa != 0) { BS->FreePages(tss_pa, 2); loader_gdt_pa = 0; } ist = 0; loader_tss = 0; } static int efi_setup_tss(struct region_descriptor *gdt, uint32_t loader_tss_idx, struct amd64tss **tss) { EFI_STATUS status; struct system_segment_descriptor *tss_desc; tss_desc = (struct system_segment_descriptor *)(gdt->rd_base + (loader_tss_idx << 3)); status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, EFI_SIZE_TO_PAGES(sizeof (struct amd64tss)), &tss_pa); if (EFI_ERROR(status)) { printf("efi_setup_tss: AllocatePages tss error %lu\n", DECODE_ERROR(status)); return (0); } *tss = (struct amd64tss *)tss_pa; bzero(*tss, sizeof (**tss)); tss_desc->sd_lolimit = sizeof (struct amd64tss); tss_desc->sd_lobase = tss_pa; tss_desc->sd_type = SDT_SYSTSS; tss_desc->sd_dpl = 0; tss_desc->sd_p = 1; tss_desc->sd_hilimit = sizeof (struct amd64tss) >> 16; tss_desc->sd_gran = 0; tss_desc->sd_hibase = tss_pa >> 24; tss_desc->sd_xx0 = 0; tss_desc->sd_xx1 = 0; tss_desc->sd_mbz = 0; tss_desc->sd_xx2 = 0; return (1); } static int efi_redirect_exceptions(void) { int ist_use_table[NUM_IST]; struct gate_descriptor *loader_idt_e; struct system_segment_descriptor *tss_desc, *gdt_desc; struct amd64tss *tss; struct region_descriptor *gdt_rd, loader_gdt; uint32_t i; EFI_STATUS status; register_t rfl; sidt(&fw_idt); status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, EFI_SIZE_TO_PAGES(fw_idt.rd_limit), &lidt_pa); if (EFI_ERROR(status)) { printf("efi_redirect_exceptions: AllocatePages IDT error %lu\n", DECODE_ERROR(status)); lidt_pa = 0; return (0); } status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, 1, &exc_stack_pa); if (EFI_ERROR(status)) { printf("efi_redirect_exceptions: AllocatePages stk error %lu\n", DECODE_ERROR(status)); exc_stack_pa = 0; free_tables(); return (0); } loader_idt.rd_limit = fw_idt.rd_limit; bcopy((void *)fw_idt.rd_base, (void *)loader_idt.rd_base, loader_idt.rd_limit); bzero(ist_use_table, sizeof (ist_use_table)); bzero(fw_intr_handlers, sizeof (fw_intr_handlers)); bzero(intercepted, sizeof (intercepted)); sgdt(&fw_gdt); tss_fw_seg = read_tr(); gdt_rd = NULL; if (tss_fw_seg == 0) { for (i = 2; (i << 3) + sizeof (*gdt_desc) <= fw_gdt.rd_limit; i += 2) { gdt_desc = (struct system_segment_descriptor *)( fw_gdt.rd_base + (i << 3)); if (gdt_desc->sd_type == 0 && gdt_desc->sd_mbz == 0) { gdt_rd = &fw_gdt; break; } } if (gdt_rd == NULL) { if (i >= 8190) { printf("efi_redirect_exceptions: all slots " "in gdt are used\n"); free_tables(); return (0); } loader_gdt.rd_limit = roundup2(fw_gdt.rd_limit + sizeof (struct system_segment_descriptor), sizeof (struct system_segment_descriptor)) - 1; i = (loader_gdt.rd_limit + 1 - sizeof (struct system_segment_descriptor)) / sizeof (struct system_segment_descriptor) * 2; status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, EFI_SIZE_TO_PAGES(loader_gdt.rd_limit), &loader_gdt_pa); if (EFI_ERROR(status)) { printf("efi_setup_tss: AllocatePages gdt error " "%lu\n", DECODE_ERROR(status)); loader_gdt_pa = 0; free_tables(); return (0); } loader_gdt.rd_base = loader_gdt_pa; bzero((void *)loader_gdt.rd_base, loader_gdt.rd_limit); bcopy((void *)fw_gdt.rd_base, (void *)loader_gdt.rd_base, fw_gdt.rd_limit); gdt_rd = &loader_gdt; } loader_tss = i << 3; if (!efi_setup_tss(gdt_rd, i, &tss)) { tss_pa = 0; free_tables(); return (0); } } else { tss_desc = (struct system_segment_descriptor *)((char *) fw_gdt.rd_base + tss_fw_seg); if (tss_desc->sd_type != SDT_SYSTSS && tss_desc->sd_type != SDT_SYSBSY) { printf("LTR points to non-TSS descriptor\n"); free_tables(); return (0); } tss_pa = tss_desc->sd_lobase + (tss_desc->sd_hibase << 16); tss = (struct amd64tss *)tss_pa; tss_desc->sd_type = SDT_SYSTSS; /* unbusy */ } PREPARE_EXCEPTION(0); PREPARE_EXCEPTION(1); PREPARE_EXCEPTION(2); PREPARE_EXCEPTION(3); PREPARE_EXCEPTION(4); PREPARE_EXCEPTION(5); PREPARE_EXCEPTION(6); PREPARE_EXCEPTION(7); PREPARE_EXCEPTION(8); PREPARE_EXCEPTION(9); PREPARE_EXCEPTION(10); PREPARE_EXCEPTION(11); PREPARE_EXCEPTION(12); PREPARE_EXCEPTION(13); PREPARE_EXCEPTION(14); PREPARE_EXCEPTION(16); PREPARE_EXCEPTION(17); PREPARE_EXCEPTION(18); PREPARE_EXCEPTION(19); PREPARE_EXCEPTION(20); exc_rsp = exc_stack_pa + PAGE_SIZE - (6 /* hw exception frame */ + 3 /* scratch regs */) * 8; /* Find free IST and use it */ for (ist = 1; ist < NUM_IST; ist++) { if (ist_use_table[ist] == 0) break; } if (ist == NUM_IST) { printf("efi_redirect_exceptions: all ISTs used\n"); free_tables(); lidt_pa = 0; return (0); } for (i = 0; i < NUM_EXC; i++) { loader_idt_e = &((struct gate_descriptor *)loader_idt. rd_base)[i]; if (intercepted[i]) loader_idt_e->gd_ist = ist; } (&(tss->tss_ist1))[ist - 1] = exc_stack_pa + PAGE_SIZE; /* Switch to new IDT */ rfl = intr_disable(); if (loader_gdt_pa != 0) bare_lgdt(&loader_gdt); if (loader_tss != 0) ltr(loader_tss); lidt(&loader_idt); intr_restore(rfl); return (1); } static void efi_unredirect_exceptions(void) { register_t rfl; if (lidt_pa == 0) return; rfl = intr_disable(); if (ist != 0) (&(((struct amd64tss *)tss_pa)->tss_ist1))[ist - 1] = 0; if (loader_gdt_pa != 0) bare_lgdt(&fw_gdt); if (loader_tss != 0) ltr(tss_fw_seg); lidt(&fw_idt); intr_restore(rfl); free_tables(); } static int command_grab_faults(int argc __unused, char *argv[] __unused) { int res; res = efi_redirect_exceptions(); if (!res) printf("failed\n"); return (CMD_OK); } COMMAND_SET(grap_faults, "grab_faults", "grab faults", command_grab_faults); static int command_ungrab_faults(int argc __unused, char *argv[] __unused) { efi_unredirect_exceptions(); return (CMD_OK); } COMMAND_SET(ungrab_faults, "ungrab_faults", "ungrab faults", command_ungrab_faults); static int command_fault(int argc __unused, char *argv[] __unused) { __asm("ud2"); return (CMD_OK); } COMMAND_SET(fault, "fault", "generate fault", command_fault); # $FreeBSD$ SRCS+= exec.c \ start.S LOADER_FDT_SUPPORT=yes /*- * Copyright (c) 2001 Benno Rice * Copyright (c) 2007 Semihalf, Rafal Jaworowski * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "loader_efi.h" extern vm_offset_t md_load(char *, vm_offset_t *); extern int bi_load(char *, vm_offset_t *, vm_offset_t *); static int __elfN(arm_load)(char *filename, u_int64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); return (0); } static int __elfN(arm_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t modulep, kernend; Elf_Ehdr *e; int error; void (*entry)(void *); if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); e = (Elf_Ehdr *)&fmp->md_data; efi_time_fini(); if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0) { efi_time_init(); return (error); } entry = efi_translate(e->e_entry); printf("Kernel entry at 0x%x...\n", (unsigned)entry); printf("Kernel args: %s\n", fp->f_args); printf("modulep: %#x\n", modulep); printf("relocation_offset %llx\n", __elfN(relocation_offset)); dev_cleanup(); (*entry)((void *)modulep); panic("exec returned"); } static struct file_format arm_elf = { __elfN(arm_load), __elfN(arm_exec) }; struct file_format *file_formats[] = { &arm_elf, NULL }; /* $FreeBSD$ */ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0; ImageBase = .; .text : { *(.peheader) *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) } =0 _etext = .; PROVIDE (etext = .); . = ALIGN(16); .data : { *(.data *.data.*) *(.gnu.linkonce.d*) *(.rodata) *(.rodata.*) CONSTRUCTORS . = ALIGN(4); PROVIDE (__bss_start = .); *(.sbss) *(.scommon) *(.dynsbss) *(.dynbss) *(.bss) *(COMMON) . = ALIGN(4); PROVIDE (__bss_end = .); } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ .sdata : { *(.got.plt .got) *(.sdata*.sdata.* .gnu.linkonce.s.*) } set_Xcommand_set : { __start_set_Xcommand_set = .; *(set_Xcommand_set) __stop_set_Xcommand_set = .; } set_Xficl_compile_set : { __start_set_Xficl_compile_set = .; *(set_Xficl_compile_set) __stop_set_Xficl_compile_set = .; } __gp = .; .plt : { *(.plt) } .dynamic : { *(.dynamic) } .reloc : { *(.reloc) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .rel.dyn : { *(.rel.*) *(.relset_*) } _edata = .; .hash : { *(.hash) } } /*- * Copyright (c) 2014, 2015 Andrew Turner * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #include /* * We need to be a PE32 file for EFI. On some architectures we can use * objcopy to create the correct file, however on arm we need to do * it ourselves. */ #define IMAGE_FILE_MACHINE_ARM 0x01c2 #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 .section .peheader efi_start: /* The MS-DOS Stub, only used to get the offset of the COFF header */ .ascii "MZ" .short 0 .space 0x38 .long pe_sig - efi_start /* The PE32 Signature. Needs to be 8-byte aligned */ .align 3 pe_sig: .ascii "PE" .short 0 coff_head: .short IMAGE_FILE_MACHINE_ARM /* ARM file */ .short 2 /* 2 Sections */ .long 0 /* Timestamp */ .long 0 /* No symbol table */ .long 0 /* No symbols */ .short section_table - optional_header /* Optional header size */ .short 0 /* Characteristics TODO: Fill in */ optional_header: .short 0x010b /* PE32 (32-bit addressing) */ .byte 0 /* Major linker version */ .byte 0 /* Minor linker version */ .long _edata - _end_header /* Code size */ .long 0 /* No initialized data */ .long 0 /* No uninitialized data */ .long _start - efi_start /* Entry point */ .long _end_header - efi_start /* Start of code */ .long 0 /* Start of data */ optional_windows_header: .long 0 /* Image base */ .long 32 /* Section Alignment */ .long 8 /* File alignment */ .short 0 /* Major OS version */ .short 0 /* Minor OS version */ .short 0 /* Major image version */ .short 0 /* Minor image version */ .short 0 /* Major subsystem version */ .short 0 /* Minor subsystem version */ .long 0 /* Win32 version */ .long _edata - efi_start /* Image size */ .long _end_header - efi_start /* Header size */ .long 0 /* Checksum */ .short 0xa /* Subsystem (EFI app) */ .short 0 /* DLL Characteristics */ .long 0 /* Stack reserve */ .long 0 /* Stack commit */ .long 0 /* Heap reserve */ .long 0 /* Heap commit */ .long 0 /* Loader flags */ .long 6 /* Number of RVAs */ /* RVAs: */ .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 section_table: /* We need a .reloc section for EFI */ .ascii ".reloc" .byte 0 .byte 0 /* Pad to 8 bytes */ .long 0 /* Virtual size */ .long 0 /* Virtual address */ .long 0 /* Size of raw data */ .long 0 /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */ /* The contents of the loader */ .ascii ".text" .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ .long _edata - _end_header /* Virtual size */ .long _end_header - efi_start /* Virtual address */ .long _edata - _end_header /* Size of raw data */ .long _end_header - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ IMAGE_SCN_MEM_READ) /* Characteristics */ _end_header: .text _start: /* Save the boot params to the stack */ push {r0, r1} adr r0, .Lbase ldr r1, [r0] sub r5, r0, r1 ldr r0, .Limagebase add r0, r0, r5 ldr r1, .Ldynamic add r1, r1, r5 bl _C_LABEL(self_reloc) /* Zero the BSS, _reloc fixed the values for us */ ldr r0, .Lbss ldr r1, .Lbssend mov r2, #0 1: cmp r0, r1 bgt 2f str r2, [r0], #4 b 1b 2: pop {r0, r1} bl _C_LABEL(efi_main) 1: b 1b .Lbase: .word . .Limagebase: .word ImageBase .Ldynamic: .word _DYNAMIC .Lbss: .word __bss_start .Lbssend: .word __bss_end .align 3 stack: .space 512 stack_end: # $FreeBSD$ LOADER_FDT_SUPPORT=yes SRCS+= exec.c \ start.S .PATH: ${.CURDIR}/../../arm64/libarm64 CFLAGS+=-I${.CURDIR}/../../arm64/libarm64 SRCS+= cache.c CFLAGS+= -msoft-float -mgeneral-regs-only CLEANFILES+= loader.help loader.help: help.common cat ${.ALLSRC} | \ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} .if !defined(LOADER_ONLY) .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" FILES+= loader.rc .endif /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include #include #include #include #include #include #include #include #include #include "loader_efi.h" #include "cache.h" #include "platform/acfreebsd.h" #include "acconfig.h" #define ACPI_SYSTEM_XFACE #define ACPI_USE_SYSTEM_INTTYPES #include "actypes.h" #include "actbl.h" static EFI_GUID acpi_guid = ACPI_TABLE_GUID; static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); static struct file_format arm64_elf = { elf64_loadfile, elf64_exec }; struct file_format *file_formats[] = { &arm64_elf, NULL }; static int elf64_exec(struct preloaded_file *fp) { vm_offset_t modulep, kernendp; vm_offset_t clean_addr; size_t clean_size; struct file_metadata *md; ACPI_TABLE_RSDP *rsdp; Elf_Ehdr *ehdr; char buf[24]; int err, revision; void (*entry)(vm_offset_t); rsdp = efi_get_table(&acpi20_guid); if (rsdp == NULL) { rsdp = efi_get_table(&acpi_guid); } if (rsdp != NULL) { sprintf(buf, "0x%016llx", (unsigned long long)rsdp); setenv("hint.acpi.0.rsdp", buf, 1); revision = rsdp->Revision; if (revision == 0) revision = 1; sprintf(buf, "%d", revision); setenv("hint.acpi.0.revision", buf, 1); strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); buf[sizeof(rsdp->OemId)] = '\0'; setenv("hint.acpi.0.oem", buf, 1); sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); setenv("hint.acpi.0.rsdt", buf, 1); if (revision >= 2) { /* XXX extended checksum? */ sprintf(buf, "0x%016llx", (unsigned long long)rsdp->XsdtPhysicalAddress); setenv("hint.acpi.0.xsdt", buf, 1); sprintf(buf, "%d", rsdp->Length); setenv("hint.acpi.0.xsdt_length", buf, 1); } } if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); entry = efi_translate(ehdr->e_entry); efi_time_fini(); err = bi_load(fp->f_args, &modulep, &kernendp); if (err != 0) { efi_time_init(); return (err); } dev_cleanup(); /* Clean D-cache under kernel area and invalidate whole I-cache */ clean_addr = (vm_offset_t)efi_translate(fp->f_addr); clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr; cpu_flush_dcache((void *)clean_addr, clean_size); cpu_inval_icache(NULL, 0); (*entry)(modulep); panic("exec returned"); } static int elf64_obj_exec(struct preloaded_file *fp) { printf("%s called for preloaded file %p (=%s):\n", __func__, fp, fp->f_name); return (ENOSYS); } /* $FreeBSD$ */ /* OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd") */ OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0; ImageBase = .; .text : { *(.peheader) *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.plt) } =0xD4200000 . = ALIGN(16); .data : { *(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata1) *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) *(.opd) *(.data .data.* .gnu.linkonce.d.*) *(.data1) *(.plabel) . = ALIGN(16); __bss_start = .; *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) *(.dynbss) *(.bss *.bss.*) *(COMMON) . = ALIGN(16); __bss_end = .; } . = ALIGN(16); set_Xcommand_set : { __start_set_Xcommand_set = .; *(set_Xcommand_set) __stop_set_Xcommand_set = .; } set_Xficl_compile_set : { __start_set_Xficl_compile_set = .; *(set_Xficl_compile_set) __stop_set_Xficl_compile_set = .; } . = ALIGN(16); __gp = .; .sdata : { *(.got.plt .got) *(.sdata .sdata.* .gnu.linkonce.s.*) *(dynsbss) *(.scommon) } . = ALIGN(16); .dynamic : { *(.dynamic) } . = ALIGN(16); .rela.dyn : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) *(.rela.got) *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) *(.rela.plt) *(.relset_*) *(.rela.dyn .rela.dyn.*) } . = ALIGN(16); .reloc : { *(.reloc) } . = ALIGN(16); .dynsym : { *(.dynsym) } _edata = .; /* Unused sections */ .dynstr : { *(.dynstr) } .hash : { *(.hash) } } /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ /* * We need to be a PE32+ file for EFI. On some architectures we can use * objcopy to create the correct file, however on arm64 we need to do * it ourselves. */ #define IMAGE_FILE_MACHINE_ARM64 0xaa64 #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 .section .peheader efi_start: /* The MS-DOS Stub, only used to get the offset of the COFF header */ .ascii "MZ" .short 0 .space 0x38 .long pe_sig - efi_start /* The PE32 Signature. Needs to be 8-byte aligned */ .align 3 pe_sig: .ascii "PE" .short 0 coff_head: .short IMAGE_FILE_MACHINE_ARM64 /* AArch64 file */ .short 2 /* 2 Sections */ .long 0 /* Timestamp */ .long 0 /* No symbol table */ .long 0 /* No symbols */ .short section_table - optional_header /* Optional header size */ .short 0 /* Characteristics TODO: Fill in */ optional_header: .short 0x020b /* PE32+ (64-bit addressing) */ .byte 0 /* Major linker version */ .byte 0 /* Minor linker version */ .long _edata - _end_header /* Code size */ .long 0 /* No initialized data */ .long 0 /* No uninitialized data */ .long _start - efi_start /* Entry point */ .long _end_header - efi_start /* Start of code */ optional_windows_header: .quad 0 /* Image base */ .long 32 /* Section Alignment */ .long 8 /* File alignment */ .short 0 /* Major OS version */ .short 0 /* Minor OS version */ .short 0 /* Major image version */ .short 0 /* Minor image version */ .short 0 /* Major subsystem version */ .short 0 /* Minor subsystem version */ .long 0 /* Win32 version */ .long _edata - efi_start /* Image size */ .long _end_header - efi_start /* Header size */ .long 0 /* Checksum */ .short 0xa /* Subsystem (EFI app) */ .short 0 /* DLL Characteristics */ .quad 0 /* Stack reserve */ .quad 0 /* Stack commit */ .quad 0 /* Heap reserve */ .quad 0 /* Heap commit */ .long 0 /* Loader flags */ .long 6 /* Number of RVAs */ /* RVAs: */ .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 section_table: /* We need a .reloc section for EFI */ .ascii ".reloc" .byte 0 .byte 0 /* Pad to 8 bytes */ .long 0 /* Virtual size */ .long 0 /* Virtual address */ .long 0 /* Size of raw data */ .long 0 /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */ /* The contents of the loader */ .ascii ".text" .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ .long _edata - _end_header /* Virtual size */ .long _end_header - efi_start /* Virtual address */ .long _edata - _end_header /* Size of raw data */ .long _end_header - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ IMAGE_SCN_MEM_READ) /* Characteristics */ _end_header: .text .globl _start _start: /* Save the boot params to the stack */ stp x0, x1, [sp, #-16]! adr x0, __bss_start adr x1, __bss_end b 2f 1: stp xzr, xzr, [x0], #16 2: cmp x0, x1 b.lo 1b adr x0, ImageBase adr x1, _DYNAMIC bl self_reloc ldp x0, x1, [sp], #16 bl efi_main 1: b 1b /*- * Copyright (c) 2010 Rui Paulo * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include __FBSDID("$FreeBSD$"); #include "loader_efi.h" int efi_autoload(void) { return (0); } /*- * Copyright (c) 1998 Michael Smith * Copyright (c) 2004, 2006 Marcel Moolenaar * Copyright (c) 2014 The FreeBSD Foundation * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "loader_efi.h" #if defined(__amd64__) #include #include "framebuffer.h" #endif #if defined(LOADER_FDT_SUPPORT) #include #endif int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); extern EFI_SYSTEM_TABLE *ST; static const char howto_switches[] = "aCdrgDmphsv"; static int howto_masks[] = { RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE }; static int bi_getboothowto(char *kargs) { const char *sw; char *opts; char *console; int howto, i; howto = 0; /* Get the boot options from the environment first. */ for (i = 0; howto_names[i].ev != NULL; i++) { if (getenv(howto_names[i].ev) != NULL) howto |= howto_names[i].mask; } console = getenv("console"); if (console != NULL) { if (strcmp(console, "comconsole") == 0) howto |= RB_SERIAL; if (strcmp(console, "nullconsole") == 0) howto |= RB_MUTE; } /* Parse kargs */ if (kargs == NULL) return (howto); opts = strchr(kargs, '-'); while (opts != NULL) { while (*(++opts) != '\0') { sw = strchr(howto_switches, *opts); if (sw == NULL) break; howto |= howto_masks[sw - howto_switches]; } opts = strchr(opts, '-'); } return (howto); } /* * Copy the environment into the load area starting at (addr). * Each variable is formatted as =, with a single nul * separating each variable, and a double nul terminating the environment. */ vm_offset_t bi_copyenv(vm_offset_t start) { struct env_var *ep; vm_offset_t addr, last; size_t len; addr = last = start; /* Traverse the environment. */ for (ep = environ; ep != NULL; ep = ep->ev_next) { len = strlen(ep->ev_name); if ((size_t)archsw.arch_copyin(ep->ev_name, addr, len) != len) break; addr += len; if (archsw.arch_copyin("=", addr, 1) != 1) break; addr++; if (ep->ev_value != NULL) { len = strlen(ep->ev_value); if ((size_t)archsw.arch_copyin(ep->ev_value, addr, len) != len) break; addr += len; } if (archsw.arch_copyin("", addr, 1) != 1) break; last = ++addr; } if (archsw.arch_copyin("", last++, 1) != 1) last = start; return (last); } /* * Copy module-related data into the load area, where it can be * used as a directory for loaded modules. * * Module data is presented in a self-describing format. Each datum * is preceded by a 32-bit identifier and a 32-bit size field. * * Currently, the following data are saved: * * MOD_NAME (variable) module name (string) * MOD_TYPE (variable) module type (string) * MOD_ARGS (variable) module parameters (string) * MOD_ADDR sizeof(vm_offset_t) module load address * MOD_SIZE sizeof(size_t) module size * MOD_METADATA (variable) type-specific metadata */ #define COPY32(v, a, c) { \ uint32_t x = (v); \ if (c) \ archsw.arch_copyin(&x, a, sizeof (x)); \ a += sizeof (x); \ } #define MOD_STR(t, a, s, c) { \ COPY32(t, a, c); \ COPY32(strlen(s) + 1, a, c); \ if (c) \ archsw.arch_copyin(s, a, strlen(s) + 1); \ a += roundup(strlen(s) + 1, sizeof (ulong_t)); \ } #define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) #define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) #define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) #define MOD_VAR(t, a, s, c) { \ COPY32(t, a, c); \ COPY32(sizeof (s), a, c); \ if (c) \ archsw.arch_copyin(&s, a, sizeof (s)); \ a += roundup(sizeof (s), sizeof (ulong_t)); \ } #define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) #define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) #define MOD_METADATA(a, mm, c) { \ COPY32(MODINFO_METADATA | mm->md_type, a, c); \ COPY32(mm->md_size, a, c); \ if (c) \ archsw.arch_copyin(mm->md_data, a, mm->md_size); \ a += roundup(mm->md_size, sizeof (ulong_t)); \ } #define MOD_END(a, c) { \ COPY32(MODINFO_END, a, c); \ COPY32(0, a, c); \ } static vm_offset_t bi_copymodules(vm_offset_t addr) { struct preloaded_file *fp; struct file_metadata *md; int c; uint64_t v; c = addr != 0; /* Start with the first module on the list, should be the kernel. */ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { MOD_NAME(addr, fp->f_name, c); /* This must come first. */ MOD_TYPE(addr, fp->f_type, c); if (fp->f_args) MOD_ARGS(addr, fp->f_args, c); v = fp->f_addr; #if defined(__arm__) v -= __elfN(relocation_offset); #endif MOD_ADDR(addr, v, c); v = fp->f_size; MOD_SIZE(addr, v, c); for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) MOD_METADATA(addr, md, c); } MOD_END(addr, c); return (addr); } static int bi_load_efi_data(struct preloaded_file *kfp) { EFI_MEMORY_DESCRIPTOR *mm; EFI_PHYSICAL_ADDRESS addr; EFI_STATUS status; size_t efisz; UINTN efi_mapkey; UINTN mmsz, pages, retry, sz; UINT32 mmver; struct efi_map_header *efihdr; #if defined(__amd64__) struct efi_fb efifb; if (efi_find_framebuffer(&efifb) == 0) { printf("EFI framebuffer information:\n"); printf("addr, size 0x%lx, 0x%lx\n", efifb.fb_addr, efifb.fb_size); printf("dimensions %d x %d\n", efifb.fb_width, efifb.fb_height); printf("stride %d\n", efifb.fb_stride); printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, efifb.fb_mask_reserved); file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof (efifb), &efifb); } #endif efisz = (sizeof (struct efi_map_header) + 0xf) & ~0xf; /* * It is possible that the first call to ExitBootServices may change * the map key. Fetch a new map key and retry ExitBootServices in that * case. */ for (retry = 2; retry > 0; retry--) { /* * Allocate enough pages to hold the bootinfo block and the * memory map EFI will return to us. The memory map has an * unknown size, so we have to determine that first. Note that * the AllocatePages call can itself modify the memory map, so * we have to take that into account as well. The changes to * the memory map are caused by splitting a range of free * memory into two (AFAICT), so that one is marked as being * loader data. */ sz = 0; BS->GetMemoryMap(&sz, NULL, &efi_mapkey, &mmsz, &mmver); sz += mmsz; sz = (sz + 0xf) & ~0xf; pages = EFI_SIZE_TO_PAGES(sz + efisz); status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, &addr); if (EFI_ERROR(status)) { printf("%s: AllocatePages error %lu\n", __func__, DECODE_ERROR(status)); return (ENOMEM); } /* * Read the memory map and stash it after bootinfo. Align the * memory map on a 16-byte boundary (the bootinfo block is page * aligned). */ efihdr = (struct efi_map_header *)(uintptr_t)addr; mm = (void *)((uint8_t *)efihdr + efisz); sz = (EFI_PAGE_SIZE * pages) - efisz; status = BS->GetMemoryMap(&sz, mm, &efi_mapkey, &mmsz, &mmver); if (EFI_ERROR(status)) { printf("%s: GetMemoryMap error %lu\n", __func__, DECODE_ERROR(status)); return (EINVAL); } status = BS->ExitBootServices(IH, efi_mapkey); if (EFI_ERROR(status) == 0) { efihdr->memory_size = sz; efihdr->descriptor_size = mmsz; efihdr->descriptor_version = mmver; file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr); return (0); } BS->FreePages(addr, pages); } printf("ExitBootServices error %lu\n", DECODE_ERROR(status)); return (EINVAL); } /* * Load the information expected by an amd64 kernel. * * - The 'boothowto' argument is constructed. * - The 'bootdev' argument is constructed. * - The 'bootinfo' struct is constructed, and copied into the kernel space. * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) { struct preloaded_file *xp, *kfp; struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; uint64_t kernend; uint64_t envp; vm_offset_t size; char *rootdevname; int howto; #if defined(LOADER_FDT_SUPPORT) vm_offset_t dtbp; int dtb_size; #endif #if defined(__arm__) vm_offset_t vaddr; size_t i; /* * These metadata addreses must be converted for kernel after * relocation. */ uint32_t mdt[] = { MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND, MODINFOMD_ENVP, #if defined(LOADER_FDT_SUPPORT) MODINFOMD_DTBP #endif }; #endif howto = bi_getboothowto(args); /* * Allow the environment variable 'rootdev' to override the supplied * device. This should perhaps go to MI code and/or have $rootdev * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); archsw.arch_getdev((void**)(&rootdev), rootdevname, NULL); if (rootdev == NULL) { printf("Can't determine root device.\n"); return (EINVAL); } /* Try reading the /etc/fstab file to select the root device */ getrootmount(efi_fmtdev((void *)rootdev)); addr = 0; for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { if (addr < (xp->f_addr + xp->f_size)) addr = xp->f_addr + xp->f_size; } /* Pad to a page boundary. */ addr = roundup(addr, PAGE_SIZE); /* Copy our environment. */ envp = addr; addr = bi_copyenv(addr); /* Pad to a page boundary. */ addr = roundup(addr, PAGE_SIZE); #if defined(LOADER_FDT_SUPPORT) /* Handle device tree blob */ dtbp = addr; dtb_size = fdt_copy(addr); /* Pad to a page boundary */ if (dtb_size) addr += roundup(dtb_size, PAGE_SIZE); #endif kfp = file_findfile(NULL, "elf kernel"); if (kfp == NULL) kfp = file_findfile(NULL, "elf64 kernel"); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof (howto), &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof (envp), &envp); #if defined(LOADER_FDT_SUPPORT) if (dtb_size) file_addmetadata(kfp, MODINFOMD_DTBP, sizeof (dtbp), &dtbp); else pager_output("WARNING! Trying to fire up the kernel, but no " "device tree blob found!\n"); #endif file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof (kernend), &kernend); file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof (ST), &ST); bi_load_efi_data(kfp); /* Figure out the size and location of the metadata. */ *modulep = addr; size = bi_copymodules(0); kernend = roundup(addr + size, PAGE_SIZE); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ md = file_findmetadata(kfp, MODINFOMD_KERNEND); bcopy(&kernend, md->md_data, sizeof (kernend)); #if defined(__arm__) *modulep -= __elfN(relocation_offset); /* Do relocation fixup on metadata of each module. */ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { for (i = 0; i < nitems(mdt); i++) { md = file_findmetadata(xp, mdt[i]); if (md) { bcopy(md->md_data, &vaddr, sizeof (vaddr)); vaddr -= __elfN(relocation_offset); bcopy(&vaddr, md->md_data, sizeof (vaddr)); } } } #endif /* Copy module list and metadata. */ (void) bi_copymodules(addr); return (0); } /* * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * Copyright 2024 MNX Cloud, 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include #include #include #include #include #include extern struct devsw vdisk_dev; struct devsw *devsw[] = { &efipart_fddev, &efipart_cddev, &efipart_hddev, &efinet_dev, &vdisk_dev, &zfs_dev, NULL }; struct fs_ops *file_system[] = { &gzipfs_fsops, &zfs_fsops, &dosfs_fsops, &ufs_fsops, &cd9660_fsops, &dosfs_fsops, &tftp_fsops, &nfs_fsops, NULL }; struct netif_driver *netif_drivers[] = { &efinetif, NULL }; extern struct console efi_console; /* Hammerhead: nullconsole and spinconsole were in i386/libi386/ (deleted). * EFI console handles all output; these specialty consoles are not needed. */ struct console_template ct_list[] = { [0] = { .ct_dev = &efi_console, .ct_init = NULL }, [1] = { .ct_dev = NULL, .ct_init = efi_serial_ini }, [2] = { .ct_dev = NULL, .ct_init = efi_isa_ini }, [3] = { .ct_dev = NULL, .ct_init = NULL }, }; struct console **consoles; /* * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. * 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. * * 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. */ #include #include #include #include #include #include #include #include "loader_efi.h" /* * Verify the address is not in use by existing modules. */ static vm_offset_t addr_verify(multiboot_tag_module_t *module, vm_offset_t addr, size_t size) { vm_offset_t start, end; for (; module->mb_type == MULTIBOOT_TAG_TYPE_MODULE; module = (multiboot_tag_module_t *) roundup((uintptr_t)module + module->mb_size, MULTIBOOT_TAG_ALIGN)) { start = module->mb_mod_start; end = module->mb_mod_end; /* Does this module have address assigned? */ if (start == 0) continue; if ((start <= addr) && (end >= addr)) { return (0); } if ((start >= addr) && (start <= addr + size)) { return (0); } } return (addr); } /* * Find memory map entry above 1MB, able to contain size bytes from addr. */ static vm_offset_t memmap_find(EFI_MEMORY_DESCRIPTOR *map, size_t count, UINTN dsize, vm_offset_t addr, size_t size) { int i; for (i = 0; i < count; i++, map = NextMemoryDescriptor(map, dsize)) { if (map->Type != EfiConventionalMemory) continue; /* We do not want address below 1MB. */ if (map->PhysicalStart < 0x100000) continue; /* Do we fit into current entry? */ if ((map->PhysicalStart <= addr) && (map->PhysicalStart + (map->NumberOfPages << EFI_PAGE_SHIFT) >= addr + size)) { return (addr); } /* Do we fit into new entry? */ if ((map->PhysicalStart > addr) && (map->NumberOfPages >= EFI_SIZE_TO_PAGES(size))) { return (map->PhysicalStart); } } return (0); } /* * Find usable address for loading. The address for the kernel is fixed, as * it is determined by kernel linker map (dboot PT_LOAD address). * For modules, we need to consult memory map, the module address has to be * aligned to page boundary and we have to fit into map entry. */ vm_offset_t efi_physaddr(multiboot_tag_module_t *module, vm_offset_t addr, EFI_MEMORY_DESCRIPTOR *map, size_t count, UINTN dsize, vm_offset_t laddr, size_t size) { multiboot_tag_module_t *mp; vm_offset_t off; if (addr == 0) return (addr); mp = module; do { off = addr; /* Test proposed address */ off = memmap_find(map, count, dsize, off, size); if (off != 0) off = addr_verify(module, off, size); if (off != 0) break; /* The module list is exhausted */ if (mp->mb_type != MULTIBOOT_TAG_TYPE_MODULE) break; if (mp->mb_mod_start != 0) { addr = roundup2(mp->mb_mod_end + 1, MULTIBOOT_MOD_ALIGN); } mp = (multiboot_tag_module_t *) roundup((uintptr_t)mp + mp->mb_size, MULTIBOOT_TAG_ALIGN); } while (off == 0); /* * memmap_find failed to get us address, try to use load * address. */ if (off == 0 || off >= UINT32_MAX) off = addr_verify(module, laddr, size); return (off); } /* * Allocate pages for data to be loaded. As we can not expect AllocateAddress * to succeed, we allocate using AllocateMaxAddress from 4GB limit. * 4GB limit is because reportedly some 64bit systems are reported to have * issues with memory above 4GB. It should be quite enough anyhow. * Note: AllocateMaxAddress will only make sure we are below the specified * address, we can not make any assumptions about actual location or * about the order of the allocated blocks. */ vm_offset_t efi_loadaddr(uint_t type, void *data, vm_offset_t addr) { EFI_PHYSICAL_ADDRESS paddr; struct stat st; size_t size; uint64_t pages; EFI_STATUS status; if (addr == 0) return (addr); /* nothing to do */ if (type == LOAD_ELF) return (0); /* not supported */ if (type == LOAD_MEM) size = *(size_t *)data; else { stat(data, &st); size = st.st_size; } /* AllocatePages can not allocate 0 pages. */ if (size == 0) return (addr); pages = EFI_SIZE_TO_PAGES(size); /* 4GB upper limit */ paddr = UINT32_MAX; status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, pages, &paddr); if (EFI_ERROR(status)) { printf("failed to allocate %zu bytes for staging area: %lu\n", size, DECODE_ERROR(status)); return (0); } return (paddr); } void efi_free_loadaddr(vm_offset_t addr, size_t pages) { (void) BS->FreePages(addr, pages); } void * efi_translate(vm_offset_t ptr) { return ((void *)ptr); } ssize_t efi_copyin(const void *src, vm_offset_t dest, const size_t len) { if (dest + len >= dest && (uint64_t)dest + len <= UINT32_MAX) { bcopy(src, (void *)(uintptr_t)dest, len); return (len); } else { errno = EFBIG; return (-1); } } ssize_t efi_copyout(const vm_offset_t src, void *dest, const size_t len) { if (src + len >= src && (uint64_t)src + len <= UINT32_MAX) { bcopy((void *)(uintptr_t)src, dest, len); return (len); } else { errno = EFBIG; return (-1); } } ssize_t efi_readin(const int fd, vm_offset_t dest, const size_t len) { if (dest + len >= dest && (uint64_t)dest + len <= UINT32_MAX) { return (read(fd, (void *)dest, len)); } else { errno = EFBIG; return (-1); } } /* * Relocate chunks and return pointer to MBI. * This function is relocated before being called and we only have * memmove() available, as most likely moving chunks into the final * destination will destroy the rest of the loader code. * * In safe area we have relocator data, multiboot_tramp, efi_copy_finish, * memmove and stack. */ multiboot2_info_header_t * efi_copy_finish(struct relocator *relocator) { multiboot2_info_header_t *mbi; struct chunk *chunk, *c; struct chunk_head *head; bool done = false; void (*move)(void *s1, const void *s2, size_t n); move = (void *)relocator->rel_memmove; /* MBI is the last chunk in the list. */ head = &relocator->rel_chunk_head; chunk = STAILQ_LAST(head, chunk, chunk_next); mbi = (multiboot2_info_header_t *)(uintptr_t)chunk->chunk_paddr; /* * If chunk paddr == vaddr, the chunk is in place. * If all chunks are in place, we are done. */ chunk = NULL; while (!done) { /* Advance to next item in list. */ if (chunk != NULL) chunk = STAILQ_NEXT(chunk, chunk_next); /* * First check if we have anything to do. * We set chunk to NULL every time we move the data. */ done = true; STAILQ_FOREACH_FROM(chunk, head, chunk_next) { if (chunk->chunk_paddr != chunk->chunk_vaddr) { done = false; break; } } if (done) break; /* * Make sure the destination is not conflicting * with rest of the modules. */ STAILQ_FOREACH(c, head, chunk_next) { /* Moved already? */ if (c->chunk_vaddr == c->chunk_paddr) continue; /* Is it the chunk itself? */ if (c->chunk_vaddr == chunk->chunk_vaddr && c->chunk_size == chunk->chunk_size) continue; /* * Check for overlaps. */ if ((c->chunk_vaddr >= chunk->chunk_paddr && c->chunk_vaddr <= chunk->chunk_paddr + chunk->chunk_size) || (c->chunk_vaddr + c->chunk_size >= chunk->chunk_paddr && c->chunk_vaddr + c->chunk_size <= chunk->chunk_paddr + chunk->chunk_size)) { break; } } /* If there are no conflicts, move to place and restart. */ if (c == NULL) { move((void *)(uintptr_t)chunk->chunk_paddr, (void *)(uintptr_t)chunk->chunk_vaddr, chunk->chunk_size); chunk->chunk_vaddr = chunk->chunk_paddr; chunk = NULL; continue; } } return (mbi); } /* * Copyright (c) 2000 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include #include #include #include #include static EFI_PHYSICAL_ADDRESS heap; static UINTN heapsize; void efi_exit(EFI_STATUS exit_code) { if (has_boot_services) { BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); BS->Exit(IH, exit_code, 0, NULL); } else { RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); } } void exit(int status __unused) { efi_exit(EFI_LOAD_ERROR); } static CHAR16 * arg_skipsep(CHAR16 *argp) { while (*argp == ' ' || *argp == '\t' || *argp == '\n') argp++; return (argp); } static CHAR16 * arg_skipword(CHAR16 *argp) { while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n') argp++; return (argp); } EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) { EFI_LOADED_IMAGE_PROTOCOL *img; CHAR16 *argp, *args, **argv; EFI_STATUS status; int argc, addprog; IH = image_handle; ST = system_table; BS = ST->BootServices; RS = ST->RuntimeServices; heapsize = 64 * 1024 * 1024; /* 4GB upper limit, try to leave some space from 1MB */ heap = 0x0000000100000000; status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, EFI_SIZE_TO_PAGES(heapsize), &heap); if (status != EFI_SUCCESS) BS->Exit(IH, status, 0, NULL); setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize)); /* Use efi_exit() from here on... */ status = OpenProtocolByHandle(IH, &gEfiLoadedImageProtocolGuid, (void **)&img); if (status != EFI_SUCCESS) efi_exit(status); /* * Pre-process the (optional) load options. If the option string * is given as an ASCII string, we use a poor man's ASCII to * Unicode-16 translation. The size of the option string as given * to us includes the terminating null character. We assume the * string is an ASCII string if strlen() plus the terminating * '\0' is less than LoadOptionsSize. Even if all Unicode-16 * characters have the upper 8 bits non-zero, the terminating * null character will cause a one-off. * If the string is already in Unicode-16, we make a copy so that * we know we can always modify the string. */ if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { args = malloc(img->LoadOptionsSize << 1); for (argc = 0; argc < (int)img->LoadOptionsSize; argc++) args[argc] = ((char *)img->LoadOptions)[argc]; } else { args = malloc(img->LoadOptionsSize); memcpy(args, img->LoadOptions, img->LoadOptionsSize); } } else args = NULL; /* * Use a quick and dirty algorithm to build the argv vector. We * first count the number of words. Then, after allocating the * vector, we split the string up. We don't deal with quotes or * other more advanced shell features. * The EFI shell will pass the name of the image as the first * word in the argument list. This does not happen if we're * loaded by the boot manager. This is not so easy to figure * out though. The ParentHandle is not always NULL, because * there can be a function (=image) that will perform the task * for the boot manager. */ /* Part 1: Figure out if we need to add our program name. */ addprog = (args == NULL || img->ParentHandle == NULL || img->FilePath == NULL) ? 1 : 0; if (!addprog) { addprog = (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || DevicePathNodeLength(img->FilePath) <= sizeof (FILEPATH_DEVICE_PATH)) ? 1 : 0; if (!addprog) { /* XXX todo. */ } } /* Part 2: count words. */ argc = (addprog) ? 1 : 0; argp = args; while (argp != NULL && *argp != 0) { argp = arg_skipsep(argp); if (*argp == 0) break; argc++; argp = arg_skipword(argp); } /* Part 3: build vector. */ argv = malloc((argc + 1) * sizeof (CHAR16*)); argc = 0; if (addprog) argv[argc++] = (CHAR16 *)LOADER_EFI; argp = args; while (argp != NULL && *argp != 0) { argp = arg_skipsep(argp); if (*argp == 0) break; argv[argc++] = argp; argp = arg_skipword(argp); /* Terminate the words. */ if (*argp != 0) *argp++ = 0; } argv[argc] = NULL; status = main(argc, argv); efi_exit(status); return (status); } /* * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. * 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. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gfx_fb.h" #include "framebuffer.h" EFI_GUID gEfiGraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GUID gEfiPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID; EFI_GUID gEfiUgaDrawProtocolGuid = EFI_UGA_DRAW_PROTOCOL_GUID; EFI_GUID gEfiUgaIoProtocolGuid = EFI_UGA_IO_PROTOCOL_GUID; EFI_GUID gEfiEdidActiveProtocolGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID; EFI_GUID gEfiEdidDiscoveredProtocolGuid = EFI_EDID_DISCOVERED_PROTOCOL_GUID; static EFI_HANDLE gop_handle; /* Saved initial GOP mode. */ static uint32_t default_mode = UINT32_MAX; /* Cached EDID. */ struct vesa_edid_info *edid_info = NULL; static uint32_t gop_default_mode(void); static int efifb_set_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *, uint_t); static uint_t efifb_color_depth(struct efi_fb *efifb) { uint32_t mask; uint_t depth; mask = efifb->fb_mask_red | efifb->fb_mask_green | efifb->fb_mask_blue | efifb->fb_mask_reserved; if (mask == 0) return (0); for (depth = 1; mask != 1; depth++) mask >>= 1; return (depth); } static int efifb_mask_from_pixfmt(struct efi_fb *efifb, EFI_GRAPHICS_PIXEL_FORMAT pixfmt, EFI_PIXEL_BITMASK *pixinfo) { int result; result = 0; switch (pixfmt) { case PixelRedGreenBlueReserved8BitPerColor: case PixelBltOnly: efifb->fb_mask_red = 0x000000ff; efifb->fb_mask_green = 0x0000ff00; efifb->fb_mask_blue = 0x00ff0000; efifb->fb_mask_reserved = 0xff000000; break; case PixelBlueGreenRedReserved8BitPerColor: efifb->fb_mask_red = 0x00ff0000; efifb->fb_mask_green = 0x0000ff00; efifb->fb_mask_blue = 0x000000ff; efifb->fb_mask_reserved = 0xff000000; break; case PixelBitMask: efifb->fb_mask_red = pixinfo->RedMask; efifb->fb_mask_green = pixinfo->GreenMask; efifb->fb_mask_blue = pixinfo->BlueMask; efifb->fb_mask_reserved = pixinfo->ReservedMask; break; default: result = 1; break; } return (result); } static int efifb_from_gop(struct efi_fb *efifb, EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode, EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info) { int result; efifb->fb_addr = mode->FrameBufferBase; efifb->fb_size = mode->FrameBufferSize; efifb->fb_height = info->VerticalResolution; efifb->fb_width = info->HorizontalResolution; efifb->fb_stride = info->PixelsPerScanLine; result = efifb_mask_from_pixfmt(efifb, info->PixelFormat, &info->PixelInformation); if (efifb->fb_addr == 0) result = 1; return (result); } static ssize_t efifb_uga_find_pixel(EFI_UGA_DRAW_PROTOCOL *uga, uint_t line, EFI_PCI_IO_PROTOCOL *pciio, uint64_t addr, uint64_t size) { EFI_UGA_PIXEL pix0, pix1; uint8_t *data1, *data2; size_t count, maxcount = 1024; ssize_t ofs; EFI_STATUS status; uint_t idx; status = uga->Blt(uga, &pix0, EfiUgaVideoToBltBuffer, 0, line, 0, 0, 1, 1, 0); if (EFI_ERROR(status)) { printf("UGA BLT operation failed (video->buffer)"); return (-1); } pix1.Red = ~pix0.Red; pix1.Green = ~pix0.Green; pix1.Blue = ~pix0.Blue; pix1.Reserved = 0; data1 = calloc(maxcount, 2); if (data1 == NULL) { printf("Unable to allocate memory"); return (-1); } data2 = data1 + maxcount; ofs = 0; while (size > 0) { count = min(size, maxcount); status = pciio->Mem.Read(pciio, EfiPciIoWidthUint32, EFI_PCI_IO_PASS_THROUGH_BAR, addr + ofs, count >> 2, data1); if (EFI_ERROR(status)) { printf("Error reading frame buffer (before)"); goto fail; } status = uga->Blt(uga, &pix1, EfiUgaBltBufferToVideo, 0, 0, 0, line, 1, 1, 0); if (EFI_ERROR(status)) { printf("UGA BLT operation failed (modify)"); goto fail; } status = pciio->Mem.Read(pciio, EfiPciIoWidthUint32, EFI_PCI_IO_PASS_THROUGH_BAR, addr + ofs, count >> 2, data2); if (EFI_ERROR(status)) { printf("Error reading frame buffer (after)"); goto fail; } status = uga->Blt(uga, &pix0, EfiUgaBltBufferToVideo, 0, 0, 0, line, 1, 1, 0); if (EFI_ERROR(status)) { printf("UGA BLT operation failed (restore)"); goto fail; } for (idx = 0; idx < count; idx++) { if (data1[idx] != data2[idx]) { free(data1); return (ofs + (idx & ~3)); } } ofs += count; size -= count; } printf("No change detected in frame buffer"); fail: printf(" -- error %lu\n", DECODE_ERROR(status)); free(data1); return (-1); } static EFI_PCI_IO_PROTOCOL * efifb_uga_get_pciio(void) { EFI_PCI_IO_PROTOCOL *pciio; EFI_HANDLE *handles; EFI_STATUS status; uint_t i, nhandles; /* Get all handles that support the UGA protocol. */ status = efi_get_protocol_handles(&gEfiUgaDrawProtocolGuid, &nhandles, &handles); if (status != EFI_SUCCESS) { return (NULL); } /* Get the PCI I/O interface of the first handle that supports it. */ pciio = NULL; for (i = 0; i < nhandles; i++) { status = OpenProtocolByHandle(handles[i], &gEfiPciIoProtocolGuid, (void **)&pciio); if (status == EFI_SUCCESS) { free(handles); return (pciio); } } free(handles); return (NULL); } static EFI_STATUS efifb_uga_locate_framebuffer(EFI_PCI_IO_PROTOCOL *pciio, uint64_t *addrp, uint64_t *sizep) { uint8_t *resattr; uint64_t addr, size; EFI_STATUS status; uint_t bar; if (pciio == NULL) return (EFI_DEVICE_ERROR); /* Attempt to get the frame buffer address (imprecise). */ *addrp = 0; *sizep = 0; for (bar = 0; bar < 6; bar++) { status = pciio->GetBarAttributes(pciio, bar, NULL, (void **)&resattr); if (status != EFI_SUCCESS) continue; /* XXX magic offsets and constants. */ if (resattr[0] == 0x87 && resattr[3] == 0) { /* 32-bit address space descriptor (MEMIO) */ addr = le32dec(resattr + 10); size = le32dec(resattr + 22); } else if (resattr[0] == 0x8a && resattr[3] == 0) { /* 64-bit address space descriptor (MEMIO) */ addr = le64dec(resattr + 14); size = le64dec(resattr + 38); } else { addr = 0; size = 0; } BS->FreePool(resattr); if (addr == 0 || size == 0) continue; /* We assume the largest BAR is the frame buffer. */ if (size > *sizep) { *addrp = addr; *sizep = size; } } return ((*addrp == 0 || *sizep == 0) ? EFI_DEVICE_ERROR : 0); } static int efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga) { EFI_PCI_IO_PROTOCOL *pciio; char *ev, *p; EFI_STATUS status; ssize_t offset; uint64_t fbaddr; uint32_t horiz, vert, stride; uint32_t np, depth, refresh; status = uga->GetMode(uga, &horiz, &vert, &depth, &refresh); if (EFI_ERROR(status)) return (1); efifb->fb_height = vert; efifb->fb_width = horiz; /* Paranoia... */ if (efifb->fb_height == 0 || efifb->fb_width == 0) return (1); /* The color masks are fixed AFAICT. */ efifb_mask_from_pixfmt(efifb, PixelBlueGreenRedReserved8BitPerColor, NULL); /* pciio can be NULL on return! */ pciio = efifb_uga_get_pciio(); /* Try to find the frame buffer. */ status = efifb_uga_locate_framebuffer(pciio, &efifb->fb_addr, &efifb->fb_size); if (EFI_ERROR(status)) { efifb->fb_addr = 0; efifb->fb_size = 0; } /* * There's no reliable way to detect the frame buffer or the * offset within the frame buffer of the visible region, nor * the stride. Our only option is to look at the system and * fill in the blanks based on that. Luckily, UGA was mostly * only used on Apple hardware. */ offset = -1; ev = getenv("smbios.system.maker"); if (ev != NULL && strcmp(ev, "Apple Inc.") == 0) { ev = getenv("smbios.system.product"); if (ev != NULL && strcmp(ev, "iMac7,1") == 0) { /* These are the expected values we should have. */ horiz = 1680; vert = 1050; fbaddr = 0xc0000000; /* These are the missing bits. */ offset = 0x10000; stride = 1728; } else if (ev != NULL && strcmp(ev, "MacBook3,1") == 0) { /* These are the expected values we should have. */ horiz = 1280; vert = 800; fbaddr = 0xc0000000; /* These are the missing bits. */ offset = 0x0; stride = 2048; } } /* * If this is hardware we know, make sure that it looks familiar * before we accept our hardcoded values. */ if (offset >= 0 && efifb->fb_width == horiz && efifb->fb_height == vert && efifb->fb_addr == fbaddr) { efifb->fb_addr += offset; efifb->fb_size -= offset; efifb->fb_stride = stride; return (0); } else if (offset >= 0) { printf("Hardware make/model known, but graphics not " "as expected.\n"); printf("Console may not work!\n"); } /* * The stride is equal or larger to the width. Often it's the * next larger power of two. We'll start with that... */ efifb->fb_stride = efifb->fb_width; do { np = efifb->fb_stride & (efifb->fb_stride - 1); if (np) { efifb->fb_stride |= (np - 1); efifb->fb_stride++; } } while (np); ev = getenv("hw.efifb.address"); if (ev == NULL) { if (efifb->fb_addr == 0) { printf("Please set hw.efifb.address and " "hw.efifb.stride.\n"); return (1); } /* * The visible part of the frame buffer may not start at * offset 0, so try to detect it. Note that we may not * always be able to read from the frame buffer, which * means that we may not be able to detect anything. In * that case, we would take a long time scanning for a * pixel change in the frame buffer, which would have it * appear that we're hanging, so we limit the scan to * 1/256th of the frame buffer. This number is mostly * based on PR 202730 and the fact that on a MacBoook, * where we can't read from the frame buffer the offset * of the visible region is 0. In short: we want to scan * enough to handle all adapters that have an offset * larger than 0 and we want to scan as little as we can * to not appear to hang when we can't read from the * frame buffer. */ offset = efifb_uga_find_pixel(uga, 0, pciio, efifb->fb_addr, efifb->fb_size >> 8); if (offset == -1) { printf("Unable to reliably detect frame buffer.\n"); } else if (offset > 0) { efifb->fb_addr += offset; efifb->fb_size -= offset; } } else { offset = 0; efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4; efifb->fb_addr = strtoul(ev, &p, 0); if (*p != '\0') return (1); } ev = getenv("hw.efifb.stride"); if (ev == NULL) { if (pciio != NULL && offset != -1) { /* Determine the stride. */ offset = efifb_uga_find_pixel(uga, 1, pciio, efifb->fb_addr, horiz * 8); if (offset != -1) efifb->fb_stride = offset >> 2; } else { printf("Unable to reliably detect the stride.\n"); } } else { efifb->fb_stride = strtoul(ev, &p, 0); if (*p != '\0') return (1); } /* * We finalized on the stride, so recalculate the size of the * frame buffer. */ efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4; if (efifb->fb_addr == 0) return (1); return (0); } /* * Fetch EDID info. Caller must free the buffer. */ static struct vesa_edid_info * efifb_gop_get_edid(EFI_HANDLE h) { const uint8_t magic[] = EDID_MAGIC; EFI_EDID_ACTIVE_PROTOCOL *edid; struct vesa_edid_info *edid_infop; EFI_GUID *guid; EFI_STATUS status; size_t size; guid = &gEfiEdidActiveProtocolGuid; status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (status != EFI_SUCCESS || edid->SizeOfEdid == 0) { guid = &gEfiEdidDiscoveredProtocolGuid; status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (status != EFI_SUCCESS || edid->SizeOfEdid == 0) return (NULL); } size = MAX(sizeof (*edid_infop), edid->SizeOfEdid); edid_infop = calloc(1, size); if (edid_infop == NULL) return (NULL); memcpy(edid_infop, edid->Edid, edid->SizeOfEdid); /* Validate EDID */ if (memcmp(edid_infop, magic, sizeof (magic)) != 0) goto error; if (edid_infop->header.version != 1) goto error; return (edid_infop); error: free(edid_infop); return (NULL); } static bool efifb_get_edid(edid_res_list_t *res) { bool rv = false; if (edid_info == NULL) edid_info = efifb_gop_get_edid(gop_handle); if (edid_info != NULL) rv = gfx_get_edid_resolution(edid_info, res); return (rv); } int efi_find_framebuffer(struct efi_fb *efifb) { EFI_HANDLE *hlist; uint_t nhandles, i; extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; extern EFI_UGA_DRAW_PROTOCOL *uga; EFI_STATUS status; uint32_t mode; if (gop != NULL) return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); status = efi_get_protocol_handles(&gEfiGraphicsOutputProtocolGuid, &nhandles, &hlist); if (EFI_ERROR(status)) return (efi_status_to_errno(status)); /* * Search for ConOut protocol, if not found, use first handle. */ gop_handle = NULL; for (i = 0; i < nhandles; i++) { EFI_GRAPHICS_OUTPUT_PROTOCOL *tgop; void *dummy; status = OpenProtocolByHandle(hlist[i], &gEfiGraphicsOutputProtocolGuid, (void **)&tgop); if (status != EFI_SUCCESS) continue; if (tgop->Mode->Info->PixelFormat == PixelBltOnly || tgop->Mode->Info->PixelFormat >= PixelFormatMax) continue; status = OpenProtocolByHandle(hlist[i], &gEfiConsoleOutDeviceGuid, &dummy); if (status == EFI_SUCCESS) { gop_handle = hlist[i]; gop = tgop; break; } else if (gop_handle == NULL) { gop_handle = hlist[i]; gop = tgop; } } free(hlist); if (gop != NULL) { /* Save default mode. */ if (default_mode == UINT32_MAX) { default_mode = gop->Mode->Mode; } mode = gop_default_mode(); if (mode != gop->Mode->Mode) efifb_set_mode(gop, mode); return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); } if (uga != NULL) return (efifb_from_uga(efifb, uga)); status = BS->LocateProtocol(&gEfiUgaDrawProtocolGuid, NULL, (void **)&uga); if (status == EFI_SUCCESS) return (efifb_from_uga(efifb, uga)); return (1); } static void print_efifb(int mode, struct efi_fb *efifb, int verbose) { uint_t depth; edid_res_list_t res; struct resolution *rp; TAILQ_INIT(&res); if (verbose == 1) { printf("Framebuffer mode: %s\n", plat_stdout_is_framebuffer() ? "on" : "off"); if (efifb_get_edid(&res)) { printf("EDID"); while ((rp = TAILQ_FIRST(&res)) != NULL) { printf(" %dx%d", rp->width, rp->height); TAILQ_REMOVE(&res, rp, next); free(rp); } printf("\n"); } } if (mode >= 0) { if (verbose == 1) printf("GOP "); printf("mode %d: ", mode); } depth = efifb_color_depth(efifb); printf("%ux%ux%u", efifb->fb_width, efifb->fb_height, depth); if (verbose) printf(", stride=%u", efifb->fb_stride); if (verbose) { printf("\n frame buffer: address=%jx, size=%jx", (uintmax_t)efifb->fb_addr, (uintmax_t)efifb->fb_size); printf("\n color mask: R=%08x, G=%08x, B=%08x\n", efifb->fb_mask_red, efifb->fb_mask_green, efifb->fb_mask_blue); if (efifb->fb_addr == 0) { printf("Warning: this mode is not implementing the " "linear framebuffer. The illumos\n\tconsole is " "not available with this mode and will default to " "ttya\n"); } } } static int efifb_set_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, uint_t mode) { EFI_STATUS status; status = gop->SetMode(gop, mode); if (EFI_ERROR(status)) { snprintf(command_errbuf, sizeof (command_errbuf), "Unable to set mode to %u (error=%lu)", mode, DECODE_ERROR(status)); return (CMD_ERROR); } return (CMD_OK); } /* * Verify existance of mode number or find mode by * dimensions. If depth is not given, walk values 32, 24, 16, 8. * Return MaxMode if mode is not found. */ static int efifb_find_mode_xydm(UINT32 x, UINT32 y, int depth, int m) { extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; EFI_STATUS status; UINTN infosz; struct efi_fb fb; UINT32 mode; uint_t d, i; if (m != -1) i = 8; else if (depth == -1) i = 32; else i = depth; while (i > 0) { for (mode = 0; mode < gop->Mode->MaxMode; mode++) { status = gop->QueryMode(gop, mode, &infosz, &info); if (EFI_ERROR(status)) continue; if (m != -1) { if ((UINT32)m == mode) return (mode); else continue; } efifb_from_gop(&fb, gop->Mode, info); d = efifb_color_depth(&fb); if (x == fb.fb_width && y == fb.fb_height && d == i) return (mode); } if (depth != -1) break; i -= 8; } return (gop->Mode->MaxMode); } static int efifb_find_mode(char *str) { extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; int x, y, depth; if (!gfx_parse_mode_str(str, &x, &y, &depth)) return (gop->Mode->MaxMode); return (efifb_find_mode_xydm(x, y, depth, -1)); } /* * gop_default_mode(). Try to set mode based on EDID. */ static uint32_t gop_default_mode(void) { edid_res_list_t res; struct resolution *rp; extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; UINT32 mode; mode = gop->Mode->MaxMode; TAILQ_INIT(&res); if (efifb_get_edid(&res)) { while ((rp = TAILQ_FIRST(&res)) != NULL) { if (mode == gop->Mode->MaxMode) { mode = efifb_find_mode_xydm( rp->width, rp->height, -1, -1); } TAILQ_REMOVE(&res, rp, next); free(rp); } } if (mode == gop->Mode->MaxMode) mode = default_mode; return (mode); } COMMAND_SET(framebuffer, "framebuffer", "framebuffer mode management", command_gop); static int command_gop(int argc, char *argv[]) { extern struct efi_fb efifb; extern EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; struct efi_fb fb; EFI_STATUS status; char *arg, *cp; uint_t mode; if (gop == NULL) { snprintf(command_errbuf, sizeof (command_errbuf), "%s: Graphics Output Protocol not present", argv[0]); return (CMD_ERROR); } if (argc < 2) goto usage; /* * Note we can not turn the GOP itself off, but instead we instruct * tem to use text mode. */ if (strcmp(argv[1], "off") == 0) { if (argc != 2) goto usage; reset_font_flags(); plat_cons_update_mode(EfiConsoleControlScreenText); return (CMD_OK); } /* * Set GOP to use default mode, then notify tem. */ if (strcmp(argv[1], "on") == 0) { if (argc != 2) goto usage; reset_font_flags(); mode = gop_default_mode(); if (mode != gop->Mode->Mode) efifb_set_mode(gop, mode); plat_cons_update_mode(EfiConsoleControlScreenGraphics); return (CMD_OK); } if (strcmp(argv[1], "set") == 0) { int rv; if (argc != 3) goto usage; arg = argv[2]; if (strchr(arg, 'x') == NULL) { errno = 0; mode = strtoul(arg, &cp, 0); if (errno != 0 || *arg == '\0' || cp[0] != '\0') { snprintf(command_errbuf, sizeof (command_errbuf), "mode should be an integer"); return (CMD_ERROR); } mode = efifb_find_mode_xydm(0, 0, 0, mode); } else { mode = efifb_find_mode(arg); } if (mode == gop->Mode->MaxMode) mode = gop->Mode->Mode; reset_font_flags(); rv = efifb_set_mode(gop, mode); plat_cons_update_mode(EfiConsoleControlScreenGraphics); return (rv); } if (strcmp(argv[1], "get") == 0) { if (argc != 2) goto usage; print_efifb(gop->Mode->Mode, &efifb, 1); printf("\n"); return (CMD_OK); } if (strcmp(argv[1], "list") == 0) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info; UINTN infosz; int depth, d = -1; if (argc != 2 && argc != 3) goto usage; if (argc == 3) { arg = argv[2]; errno = 0; d = strtoul(arg, &cp, 0); if (errno != 0 || *arg == '\0' || cp[0] != '\0') { snprintf(command_errbuf, sizeof (command_errbuf), "depth should be an integer"); return (CMD_ERROR); } } pager_open(); for (mode = 0; mode < gop->Mode->MaxMode; mode++) { status = gop->QueryMode(gop, mode, &infosz, &info); if (EFI_ERROR(status)) continue; efifb_from_gop(&fb, gop->Mode, info); depth = efifb_color_depth(&fb); if (d != -1 && d != depth) continue; print_efifb(mode, &fb, 0); if (pager_output("\n")) break; } pager_close(); return (CMD_OK); } usage: snprintf(command_errbuf, sizeof (command_errbuf), "usage: %s on | off | get | list [depth] | " "set ", argv[0]); return (CMD_ERROR); } COMMAND_SET(uga, "uga", "universal graphics adapter", command_uga); static int command_uga(int argc, char *argv[]) { extern struct efi_fb efifb; extern EFI_UGA_DRAW_PROTOCOL *uga; if (uga == NULL) { snprintf(command_errbuf, sizeof (command_errbuf), "%s: UGA Protocol not present", argv[0]); return (CMD_ERROR); } if (argc != 1) goto usage; if (efifb.fb_addr == 0) { snprintf(command_errbuf, sizeof (command_errbuf), "%s: Unable to get UGA information", argv[0]); return (CMD_ERROR); } print_efifb(-1, &efifb, 1); printf("\n"); return (CMD_OK); usage: snprintf(command_errbuf, sizeof (command_errbuf), "usage: %s", argv[0]); return (CMD_ERROR); } /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. * 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. * * 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. * * $FreeBSD$ */ #ifndef _EFIFB_H_ #define _EFIFB_H_ int efi_find_framebuffer(struct efi_fb *efifb); #endif /* _EFIFB_H_ */ /* * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. * 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. * * 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 _LOADER_EFI_H #define _LOADER_EFI_H #include #include #include #include #include #include struct chunk { EFI_VIRTUAL_ADDRESS chunk_vaddr; EFI_PHYSICAL_ADDRESS chunk_paddr; size_t chunk_size; STAILQ_ENTRY(chunk) chunk_next; }; STAILQ_HEAD(chunk_head, chunk); struct relocator { vm_offset_t rel_stack; vm_offset_t rel_copy; vm_offset_t rel_memmove; struct chunk_head rel_chunk_head; struct chunk rel_chunklist[]; }; int efi_autoload(void); ssize_t efi_copyin(const void *, vm_offset_t, const size_t); ssize_t efi_copyout(const vm_offset_t, void *, const size_t); ssize_t efi_readin(const int, vm_offset_t, const size_t); vm_offset_t efi_loadaddr(u_int, void *, vm_offset_t); void efi_free_loadaddr(vm_offset_t, size_t); void * efi_translate(vm_offset_t); vm_offset_t efi_physaddr(multiboot_tag_module_t *, vm_offset_t, EFI_MEMORY_DESCRIPTOR *, size_t, UINTN, vm_offset_t, size_t); /* Hammerhead: bi_isadir() removed — ISADIR set inline in main.c */ multiboot2_info_header_t *efi_copy_finish(struct relocator *); void multiboot_tramp(uint32_t, struct relocator *, uint64_t); void efi_addsmapdata(struct preloaded_file *); #endif /* _LOADER_EFI_H */ /* * Copyright (c) 2008-2010 Rui Paulo * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "loader_efi.h" struct arch_switch archsw; /* MI/MD interface boundary */ EFI_GUID gEfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID gEfiSmbiosTableGuid = SMBIOS_TABLE_GUID; EFI_GUID gEfiSmbios3TableGuid = SMBIOS3_TABLE_GUID; extern void acpi_detect(void); extern void efi_getsmap(void); static EFI_LOADED_IMAGE_PROTOCOL *img; /* * Number of seconds to wait for a keystroke before exiting with failure * in the event no currdev is found. -2 means always break, -1 means * never break, 0 means poll once and then reboot, > 0 means wait for * that many seconds. "fail_timeout" can be set in the environment as * well. */ static int fail_timeout = 5; bool efi_zfs_is_preferred(EFI_HANDLE *h) { EFI_DEVICE_PATH *devpath, *dp, *node; HARDDRIVE_DEVICE_PATH *hd; bool ret; extern UINT64 start_sector; /* from mb_header.S */ /* This check is true for chainloader case. */ if (h == img->DeviceHandle) return (true); /* * Make sure the image was loaded from the hard disk. */ devpath = efi_lookup_devpath(img->DeviceHandle); if (devpath == NULL) return (false); node = efi_devpath_last_node(devpath); if (node == NULL) return (false); if (DevicePathType(node) != MEDIA_DEVICE_PATH || (DevicePathSubType(node) != MEDIA_FILEPATH_DP && DevicePathSubType(node) != MEDIA_HARDDRIVE_DP)) { return (false); } /* * XXX We ignore the MEDIA_FILEPATH_DP here for now as it is * used on arm and we do not support arm. */ ret = false; dp = efi_devpath_trim(devpath); devpath = NULL; if (dp == NULL) goto done; devpath = efi_lookup_devpath(h); if (devpath == NULL) goto done; hd = (HARDDRIVE_DEVICE_PATH *)efi_devpath_last_node(devpath); if (hd == NULL) { devpath = NULL; goto done; } devpath = efi_devpath_trim(devpath); if (devpath == NULL) goto done; if (!efi_devpath_match(dp, devpath)) goto done; /* It is the same disk, do we have partition start? */ if (start_sector == 0) ret = true; else if (start_sector == hd->PartitionStart) ret = true; done: free(dp); free(devpath); return (ret); } static bool has_keyboard(void) { EFI_STATUS status; EFI_DEVICE_PATH *path; EFI_HANDLE *hin; uint_t i, nhandles; bool retval = false; /* * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and * do the typical dance to get the right sized buffer. */ status = efi_get_protocol_handles(&gEfiSimpleTextInProtocolGuid, &nhandles, &hin); if (EFI_ERROR(status)) return (retval); /* * Look at each of the handles. If it supports the device path protocol, * use it to get the device path for this handle. Then see if that * device path matches either the USB device path for keyboards or the * legacy device path for keyboards. */ for (i = 0; i < nhandles; i++) { status = OpenProtocolByHandle(hin[i], &gEfiDevicePathProtocolGuid, (void **)&path); if (EFI_ERROR(status)) continue; while (!IsDevicePathEnd(path)) { /* * Check for the ACPI keyboard node. All PNP3xx nodes * are keyboards of different flavors. Note: It is * unclear of there's always a keyboard node when * there's a keyboard controller, or if there's only one * when a keyboard is detected at boot. */ if (DevicePathType(path) == ACPI_DEVICE_PATH && (DevicePathSubType(path) == ACPI_DP || DevicePathSubType(path) == ACPI_EXTENDED_DP)) { ACPI_HID_DEVICE_PATH *acpi; acpi = (ACPI_HID_DEVICE_PATH *)(void *)path; if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 && (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) { retval = true; goto out; } /* * Check for USB keyboard node, if present. Unlike a * PS/2 keyboard, these definitely only appear when * connected to the system. */ } else if (DevicePathType(path) == MESSAGING_DEVICE_PATH && DevicePathSubType(path) == MSG_USB_CLASS_DP) { USB_CLASS_DEVICE_PATH *usb; /* * Check for: * DeviceClass: HID * DeviceSubClass: Boot devices * DeviceProtocol: Boot keyboards */ usb = (USB_CLASS_DEVICE_PATH *)(void *)path; if (usb->DeviceClass == 3 && usb->DeviceSubClass == 1 && usb->DeviceProtocol == 1) { retval = true; goto out; } } path = NextDevicePathNode(path); } } out: free(hin); return (retval); } static void set_currdev(const char *devname) { /* * Don't execute hooks here; we may need to try setting these more than * once here if we're probing for the ZFS pool we're supposed to boot. * The currdev hook is intended to just validate user input anyways, * while the loaddev hook makes it immutable once we've determined what * the proper currdev is. */ env_setenv("currdev", EV_VOLATILE | EV_NOHOOK, devname, efi_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset, env_nounset); } static void set_currdev_devdesc(struct devdesc *currdev) { char *devname; devname = efi_fmtdev(currdev); printf("Setting currdev to %s\n", devname); set_currdev(devname); } static void set_currdev_devsw(struct devsw *dev, int unit) { struct devdesc currdev; currdev.d_dev = dev; currdev.d_unit = unit; set_currdev_devdesc(&currdev); } static void set_currdev_pdinfo(pdinfo_t *dp) { /* * Disks are special: they have partitions. if the parent * pointer is non-null, we're a partition not a full disk * and we need to adjust currdev appropriately. */ if (dp->pd_devsw->dv_type == DEVT_DISK) { struct disk_devdesc currdev; currdev.dd.d_dev = dp->pd_devsw; if (dp->pd_parent == NULL) { currdev.dd.d_unit = dp->pd_unit; currdev.d_slice = D_SLICENONE; currdev.d_partition = D_PARTNONE; } else { currdev.dd.d_unit = dp->pd_parent->pd_unit; currdev.d_slice = dp->pd_unit; currdev.d_partition = D_PARTISGPT; /* Assumes GPT */ } set_currdev_devdesc((struct devdesc *)&currdev); } else { set_currdev_devsw(dp->pd_devsw, dp->pd_unit); } } static bool sanity_check_currdev(void) { struct stat st; return (stat("/boot/defaults/loader.conf", &st) == 0); } static bool probe_zfs_currdev(uint64_t guid) { struct zfs_devdesc currdev; char *bootonce; bool rv; currdev.dd.d_dev = &zfs_dev; currdev.dd.d_unit = 0; currdev.pool_guid = guid; currdev.root_guid = 0; set_currdev_devdesc((struct devdesc *)&currdev); rv = sanity_check_currdev(); if (rv) { bootonce = malloc(VDEV_PAD_SIZE); if (bootonce != NULL) { if (zfs_get_bootonce(&currdev, OS_BOOTONCE, bootonce, VDEV_PAD_SIZE) == 0) { printf("zfs bootonce: %s\n", bootonce); set_currdev(bootonce); setenv("zfs-bootonce", bootonce, 1); } free(bootonce); (void) zfs_attach_nvstore(&currdev); } else { printf("Failed to process bootonce data: %s\n", strerror(errno)); } } return (rv); } static bool try_as_currdev(pdinfo_t *pp) { uint64_t guid; /* * If there's a zpool on this device, try it as a ZFS * filesystem, which has somewhat different setup than all * other types of fs due to imperfect loader integration. * This all stems from ZFS being both a device (zpool) and * a filesystem, plus the boot env feature. */ if (efizfs_get_guid_by_handle(pp->pd_handle, &guid)) return (probe_zfs_currdev(guid)); /* * All other filesystems just need the pdinfo * initialized in the standard way. */ set_currdev_pdinfo(pp); return (sanity_check_currdev()); } static bool find_currdev(EFI_LOADED_IMAGE_PROTOCOL *img) { pdinfo_t *dp, *pp; EFI_DEVICE_PATH *devpath, *copy; EFI_HANDLE h; CHAR16 *text; struct devsw *dev; int unit; uint64_t extra; /* * Did efi_zfs_probe() detect the boot pool? If so, use the zpool * it found, if it's sane. ZFS is the only thing that looks for * disks and pools to boot. */ if (pool_guid != 0) { printf("Trying ZFS pool\n"); if (probe_zfs_currdev(pool_guid)) return (true); } /* * Try to find the block device by its handle based on the * image we're booting. If we can't find a sane partition, * search all the other partitions of the disk. We do not * search other disks because it's a violation of the UEFI * boot protocol to do so. We fail and let UEFI go on to * the next candidate. */ dp = efiblk_get_pdinfo_by_handle(img->DeviceHandle); if (dp != NULL) { text = efi_devpath_name(dp->pd_devpath); if (text != NULL) { printf("Trying ESP: %S\n", text); efi_free_devpath_name(text); } set_currdev_pdinfo(dp); if (sanity_check_currdev()) return (true); if (dp->pd_parent != NULL) { dp = dp->pd_parent; STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { text = efi_devpath_name(pp->pd_devpath); if (text != NULL) { printf("And now the part: %S\n", text); efi_free_devpath_name(text); } /* * Roll up the ZFS special case * for those partitions that have * zpools on them */ if (try_as_currdev(pp)) return (true); } } } /* * Try the device handle from our loaded image first. If that * fails, use the device path from the loaded image and see if * any of the nodes in that path match one of the enumerated * handles. Currently, this handle list is only for netboot. */ if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) { set_currdev_devsw(dev, unit); if (sanity_check_currdev()) return (true); } copy = NULL; devpath = efi_lookup_image_devpath(IH); while (devpath != NULL) { h = efi_devpath_handle(devpath); if (h == NULL) break; free(copy); copy = NULL; if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) { set_currdev_devsw(dev, unit); if (sanity_check_currdev()) return (true); } devpath = efi_lookup_devpath(h); if (devpath != NULL) { copy = efi_devpath_trim(devpath); devpath = copy; } } free(copy); return (false); } static bool interactive_interrupt(const char *msg) { time_t now, then, last; last = 0; now = then = getsecs(); printf("%s\n", msg); if (fail_timeout == -2) /* Always break to OK */ return (true); if (fail_timeout == -1) /* Never break to OK */ return (false); do { if (last != now) { printf("press any key to interrupt reboot " "in %d seconds\r", fail_timeout - (int)(now - then)); last = now; } /* XXX no pause or timeout wait for char */ if (ischar()) return (true); now = getsecs(); } while (now - then < fail_timeout); return (false); } static void setenv_int(const char *key, int val) { char buf[20]; (void) snprintf(buf, sizeof (buf), "%d", val); (void) setenv(key, buf, 1); } /* * Parse ConOut (the list of consoles active) and see if we can find a * serial port and/or a video port. It would be nice to also walk the * ACPI name space to map the UID for the serial port to a port. The * latter is especially hard. */ static int parse_uefi_con_out(void) { int how, rv; int vid_seen = 0, com_seen = 0, seen = 0; size_t sz; char buf[4096], *ep; EFI_DEVICE_PATH *node; ACPI_HID_DEVICE_PATH *acpi; UART_DEVICE_PATH *uart; bool pci_pending = false; how = 0; sz = sizeof (buf); rv = efi_global_getenv("ConOut", buf, &sz); if (rv != EFI_SUCCESS) rv = efi_global_getenv("ConOutDev", buf, &sz); if (rv != EFI_SUCCESS) { /* * If we don't have any ConOut default to video. * non-server systems may not have serial. */ goto out; } ep = buf + sz; node = (EFI_DEVICE_PATH *)buf; while ((char *)node < ep) { if (IsDevicePathEndType(node)) { if (pci_pending && vid_seen == 0) vid_seen = ++seen; } pci_pending = false; if (DevicePathType(node) == ACPI_DEVICE_PATH && (DevicePathSubType(node) == ACPI_DP || DevicePathSubType(node) == ACPI_EXTENDED_DP)) { /* Check for Serial node */ acpi = (void *)node; if (EISA_ID_TO_NUM(acpi->HID) == 0x501) { setenv_int("efi_8250_uid", acpi->UID); com_seen = ++seen; } } else if (DevicePathType(node) == MESSAGING_DEVICE_PATH && DevicePathSubType(node) == MSG_UART_DP) { com_seen = ++seen; uart = (void *)node; setenv_int("efi_com_speed", uart->BaudRate); } else if (DevicePathType(node) == ACPI_DEVICE_PATH && DevicePathSubType(node) == ACPI_ADR_DP) { /* Check for AcpiAdr() Node for video */ vid_seen = ++seen; } else if (DevicePathType(node) == HARDWARE_DEVICE_PATH && DevicePathSubType(node) == HW_PCI_DP) { /* * Note, vmware fusion has a funky console device * PciRoot(0x0)/Pci(0xf,0x0) * which we can only detect at the end since we also * have to cope with: * PciRoot(0x0)/Pci(0x1f,0x0)/Serial(0x1) * so only match it if it's last. */ pci_pending = true; } node = NextDevicePathNode(node); /* Skip the end node */ } /* * Truth table for RB_MULTIPLE | RB_SERIAL * Value Result * 0 Use only video console * RB_SERIAL Use only serial console * RB_MULTIPLE Use both video and serial console * (but video is primary so gets rc messages) * both Use both video and serial console * (but serial is primary so gets rc messages) * * Try to honor this as best we can. If only one of serial / video * found, then use that. Otherwise, use the first one we found. * This also implies if we found nothing, default to video. */ how = 0; if (vid_seen && com_seen) { how |= RB_MULTIPLE; if (com_seen < vid_seen) how |= RB_SERIAL; } else if (com_seen) how |= RB_SERIAL; out: return (how); } caddr_t ptov(uintptr_t x) { return ((caddr_t)x); } static int efi_serial_get_uid(EFI_DEVICE_PATH *devpath) { ACPI_HID_DEVICE_PATH *acpi; while (!IsDevicePathEnd(devpath)) { if (DevicePathType(devpath) == ACPI_DEVICE_PATH && (DevicePathSubType(devpath) == ACPI_DP || DevicePathSubType(devpath) == ACPI_EXTENDED_DP)) { acpi = (ACPI_HID_DEVICE_PATH *)devpath; if (EISA_ID_TO_NUM(acpi->HID) == 0x501) { return (acpi->UID); } } devpath = NextDevicePathNode(devpath); } return (-1); } /* * Walk serialio protocol handle array and find index for serial console * device. The problem is, we check for acpi UID value, but we can not be sure, * if it will start from 0 or 1. */ static const char * uefi_serial_console(void) { EFI_STATUS status; EFI_HANDLE *handles; uint_t i, nhandles; unsigned long uid, lowest; char *env, *ep; env = getenv("efi_8250_uid"); if (env == NULL) return (NULL); (void) unsetenv("efi_8250_uid"); errno = 0; uid = strtoul(env, &ep, 10); if (errno != 0 || *ep != '\0') return (NULL); /* if uid is 0, this is first serial port */ if (uid == 0) return ("ttya"); status = efi_get_protocol_handles(&gEfiSerialIoProtocolGuid, &nhandles, &handles); if (EFI_ERROR(status)) { return (NULL); } lowest = 255; /* high enough value */ for (i = 0; i < nhandles; i++) { EFI_DEVICE_PATH *devpath; unsigned long _uid; devpath = efi_lookup_devpath(handles[i]); _uid = efi_serial_get_uid(devpath); if (_uid < lowest) lowest = _uid; } free(handles); switch (uid - lowest) { case 0: return ("ttya"); case 1: return ("ttyb"); case 2: return ("ttyc"); case 3: return ("ttyd"); } return (NULL); } EFI_STATUS main(int argc, CHAR16 *argv[]) { char var[128]; int i, j, howto; bool vargood; void *ptr; bool has_kbd; char *s; const char *serial; EFI_DEVICE_PATH *imgpath; CHAR16 *text; EFI_STATUS status; UINT16 boot_current; size_t sz; UINT16 boot_order[100]; archsw.arch_autoload = efi_autoload; archsw.arch_getdev = efi_getdev; archsw.arch_copyin = efi_copyin; archsw.arch_copyout = efi_copyout; archsw.arch_readin = efi_readin; archsw.arch_loadaddr = efi_loadaddr; archsw.arch_free_loadaddr = efi_free_loadaddr; #if defined(__amd64) || defined(__i386) archsw.arch_hypervisor = x86_hypervisor; #endif /* Note this needs to be set before ZFS init. */ archsw.arch_zfs_probe = efi_zfs_probe; /* Get our loaded image protocol interface structure. */ (void) OpenProtocolByHandle(IH, &gEfiLoadedImageProtocolGuid, (void **)&img); /* * XXX Chicken-and-egg problem; we want to have console output * early, but some console attributes may depend on reading from * eg. the boot device, which we can't do yet. We can use * printf() etc. once this is done. */ setenv("console", "text", 1); howto = parse_uefi_con_out(); serial = uefi_serial_console(); cons_probe(); efi_getsmap(); if ((s = getenv("efi_com_speed")) != NULL) { char *name; (void) snprintf(var, sizeof (var), "%s,8,n,1,-", s); if (asprintf(&name, "%s-mode", serial) > 0) { (void) setenv(name, var, 1); free(name); } if (asprintf(&name, "%s-spcr-mode", serial) > 0) { (void) setenv(name, var, 1); free(name); } (void) unsetenv("efi_com_speed"); } /* Init the time source */ efi_time_init(); /* * Initialise the block cache. Set the upper limit. */ bcache_init(32768, 512); has_kbd = has_keyboard(); /* * Parse the args to set the console settings, etc * iPXE may be setup to pass these in. Or the optional argument in the * boot environment was used to pass these arguments in (in which case * neither /boot.config nor /boot/config are consulted). * * Loop through the args, and for each one that contains an '=' that is * not the first character, add it to the environment. This allows * loader and kernel env vars to be passed on the command line. Convert * args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though * this method is flawed for non-ASCII characters). */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (j = 1; argv[i][j] != 0; j++) { int ch; ch = argv[i][j]; switch (ch) { case 'a': howto |= RB_ASKNAME; break; case 'd': howto |= RB_KDB; break; case 'D': howto |= RB_MULTIPLE; break; case 'h': howto |= RB_SERIAL; break; case 'm': howto |= RB_MUTE; break; case 'p': howto |= RB_PAUSE; break; case 'P': if (!has_kbd) { howto |= RB_SERIAL; howto |= RB_MULTIPLE; } break; case 'r': howto |= RB_DFLTROOT; break; case 's': howto |= RB_SINGLE; break; case 'S': if (argv[i][j + 1] == 0) { if (i + 1 == argc) { strncpy(var, "115200", sizeof (var)); } else { CHAR16 *ptr; ptr = &argv[i + 1][0]; cpy16to8(ptr, var, sizeof (var)); } i++; } else { cpy16to8(&argv[i][j + 1], var, sizeof (var)); } strncat(var, ",8,n,1,-", sizeof (var)); setenv("ttya-mode", var, 1); break; case 'v': howto |= RB_VERBOSE; break; } } } else { vargood = false; for (j = 0; argv[i][j] != 0; j++) { if (j == sizeof (var)) { vargood = false; break; } if (j > 0 && argv[i][j] == '=') vargood = true; var[j] = (char)argv[i][j]; } if (vargood) { var[j] = 0; putenv(var); } } } for (i = 0; howto_names[i].ev != NULL; i++) if (howto & howto_names[i].mask) setenv(howto_names[i].ev, "YES", 1); /* * XXX we need fallback to this stuff after looking at the ConIn, * ConOut and ConErr variables. */ if (howto & RB_MULTIPLE) { if (howto & RB_SERIAL) (void) snprintf(var, sizeof (var), "%s text", serial); else (void) snprintf(var, sizeof (var), "text %s", serial); } else if (howto & RB_SERIAL) { (void) snprintf(var, sizeof (var), "%s", serial); } else { (void) snprintf(var, sizeof (var), "text"); } (void) setenv("console", var, 1); if ((s = getenv("fail_timeout")) != NULL) fail_timeout = strtol(s, NULL, 10); /* * Scan the BLOCK IO MEDIA handles then * march through the device switch probing for things. */ if ((i = efipart_inithandles()) == 0) { for (i = 0; devsw[i] != NULL; i++) if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); } else printf("efipart_inithandles failed %d, expect failures", i); printf("Command line arguments:"); for (i = 0; i < argc; i++) { printf(" %S", argv[i]); } printf("\n"); printf("Image base: 0x%lx\n", (unsigned long)img->ImageBase); printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); printf("EFI Firmware: %S (rev %d.%02d)\n", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); printf("\n%s", bootprog_info); /* Determine the devpath of our image so we can prefer it. */ text = efi_devpath_name(img->FilePath); if (text != NULL) { printf(" Load Path: %S\n", text); efi_setenv_illumos_wcs("LoaderPath", text); efi_free_devpath_name(text); } status = OpenProtocolByHandle(img->DeviceHandle, &gEfiDevicePathProtocolGuid, (void **)&imgpath); if (status == EFI_SUCCESS) { text = efi_devpath_name(imgpath); if (text != NULL) { printf(" Load Device: %S\n", text); efi_setenv_illumos_wcs("LoaderDev", text); efi_free_devpath_name(text); } } boot_current = 0; sz = sizeof (boot_current); efi_global_getenv("BootCurrent", &boot_current, &sz); printf(" BootCurrent: %04x\n", boot_current); sz = sizeof (boot_order); efi_global_getenv("BootOrder", &boot_order, &sz); printf(" BootOrder:"); for (i = 0; i < sz / sizeof (boot_order[0]); i++) printf(" %04x%s", boot_order[i], boot_order[i] == boot_current ? "[*]" : ""); printf("\n"); /* * Disable the watchdog timer. By default the boot manager sets * the timer to 5 minutes before invoking a boot option. If we * want to return to the boot manager, we have to disable the * watchdog timer and since we're an interactive program, we don't * want to wait until the user types "quit". The timer may have * fired by then. We don't care if this fails. It does not prevent * normal functioning in any way... */ BS->SetWatchdogTimer(0, 0, 0, NULL); /* * Try and find a good currdev based on the image that was booted. * It might be desirable here to have a short pause to allow falling * through to the boot loader instead of returning instantly to follow * the boot protocol and also allow an escape hatch for users wishing * to try something different. */ if (!find_currdev(img)) if (!interactive_interrupt("Failed to find bootable partition")) return (EFI_NOT_FOUND); autoload_font(false); /* Set up the font list for console. */ efi_init_environment(); /* Hammerhead: bi_isadir() was in i386/libi386/ (deleted). * Set ISADIR directly — Hammerhead is amd64-only. */ setenv("ISADIR", "amd64", 1); acpi_detect(); if ((ptr = efi_get_table(&gEfiSmbios3TableGuid)) == NULL) ptr = efi_get_table(&gEfiSmbiosTableGuid); smbios_detect(ptr); interact(NULL); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ } COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); static void fw_setup(void) { uint64_t os_indications; size_t size; EFI_STATUS status; size = sizeof (os_indications); status = efi_global_getenv("OsIndicationsSupported", &os_indications, &size); if (EFI_ERROR(status) || size != sizeof (os_indications) || (os_indications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) == 0) { printf("Booting to Firmware UI is not supported in " "this system."); for (int i = 0; i < 3; i++) { delay(1000 * 1000); /* 1 second */ if (ischar()) break; } return; } os_indications = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; status = efi_global_setenv("OsIndications", &os_indications, sizeof (os_indications)); } static int command_reboot(int argc, char *argv[]) { int i, ch; bool fw = false; optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "fh")) != -1) { switch (ch) { case 'f': fw = true; break; case 'h': printf("Usage: reboot [-f]\n"); return (CMD_OK); case '?': default: return (CMD_OK); } } if (fw || getenv("BOOT_TO_FW_UI") != NULL) fw_setup(); for (i = 0; devsw[i] != NULL; ++i) if (devsw[i]->dv_cleanup != NULL) (devsw[i]->dv_cleanup)(); RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); /* NOTREACHED */ return (CMD_ERROR); } COMMAND_SET(poweroff, "poweroff", "power off the system", command_poweroff); static int command_poweroff(int argc __unused, char *argv[] __unused) { int i; for (i = 0; devsw[i] != NULL; ++i) if (devsw[i]->dv_cleanup != NULL) (devsw[i]->dv_cleanup)(); RS->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); /* NOTREACHED */ return (CMD_ERROR); } COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); static int command_memmap(int argc __unused, char *argv[] __unused) { UINTN sz; EFI_MEMORY_DESCRIPTOR *map, *p; UINTN key, dsz; UINT32 dver; EFI_STATUS status; int i, ndesc; int rv = 0; char line[80]; sz = 0; status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); if (status != EFI_BUFFER_TOO_SMALL) { printf("Can't determine memory map size\n"); return (CMD_ERROR); } map = malloc(sz); status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); if (EFI_ERROR(status)) { printf("Can't read memory map\n"); return (CMD_ERROR); } ndesc = sz / dsz; snprintf(line, 80, "%23s %12s %12s %8s %4s\n", "Type", "Physical", "Virtual", "#Pages", "Attr"); pager_open(); rv = pager_output(line); if (rv) { pager_close(); return (CMD_OK); } for (i = 0, p = map; i < ndesc; i++, p = NextMemoryDescriptor(p, dsz)) { snprintf(line, 80, "%23s %012jx %012jx %08jx ", efi_memory_type(p->Type), p->PhysicalStart, p->VirtualStart, p->NumberOfPages); rv = pager_output(line); if (rv) break; if (p->Attribute & EFI_MEMORY_UC) printf("UC "); if (p->Attribute & EFI_MEMORY_WC) printf("WC "); if (p->Attribute & EFI_MEMORY_WT) printf("WT "); if (p->Attribute & EFI_MEMORY_WB) printf("WB "); if (p->Attribute & EFI_MEMORY_UCE) printf("UCE "); if (p->Attribute & EFI_MEMORY_WP) printf("WP "); if (p->Attribute & EFI_MEMORY_RP) printf("RP "); if (p->Attribute & EFI_MEMORY_XP) printf("XP "); if (p->Attribute & EFI_MEMORY_NV) printf("NV "); if (p->Attribute & EFI_MEMORY_MORE_RELIABLE) printf("MR "); if (p->Attribute & EFI_MEMORY_RO) printf("RO "); rv = pager_output("\n"); if (rv) break; } pager_close(); return (CMD_OK); } COMMAND_SET(configuration, "configuration", "print configuration tables", command_configuration); static int command_configuration(int argc __unused, char *argv[] __unused) { UINTN i; char *name; printf("NumberOfTableEntries=%lu\n", (unsigned long)ST->NumberOfTableEntries); for (i = 0; i < ST->NumberOfTableEntries; i++) { EFI_GUID *guid; printf(" "); guid = &ST->ConfigurationTable[i].VendorGuid; if (efi_guid_to_name(guid, &name) == true) { printf(name); free(name); } else { printf("Error while translating UUID to name"); } printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); } return (CMD_OK); } COMMAND_SET(mode, "mode", "change or display EFI text modes", command_mode); static int command_mode(int argc, char *argv[]) { UINTN cols, rows; unsigned int mode; int i; char *cp; EFI_STATUS status; SIMPLE_TEXT_OUTPUT_INTERFACE *conout; EFI_CONSOLE_CONTROL_SCREEN_MODE sm; if (plat_stdout_is_framebuffer()) sm = EfiConsoleControlScreenGraphics; else sm = EfiConsoleControlScreenText; conout = ST->ConOut; if (argc > 1) { mode = strtol(argv[1], &cp, 0); if (cp[0] != '\0') { printf("Invalid mode\n"); return (CMD_ERROR); } status = conout->QueryMode(conout, mode, &cols, &rows); if (EFI_ERROR(status)) { printf("invalid mode %d\n", mode); return (CMD_ERROR); } status = conout->SetMode(conout, mode); if (EFI_ERROR(status)) { printf("couldn't set mode %d\n", mode); return (CMD_ERROR); } plat_cons_update_mode(sm); return (CMD_OK); } printf("Current mode: %d\n", conout->Mode->Mode); for (i = 0; i <= conout->Mode->MaxMode; i++) { status = conout->QueryMode(conout, i, &cols, &rows); if (EFI_ERROR(status)) continue; printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols, (unsigned)rows); } if (i != 0) printf("Select a mode with the command \"mode \"\n"); return (CMD_OK); } COMMAND_SET(lsefi, "lsefi", "list EFI handles", command_lsefi); static int command_lsefi(int argc __unused, char *argv[] __unused) { char *name; EFI_HANDLE *buffer = NULL; EFI_HANDLE handle; UINTN bufsz = 0, i, j; EFI_STATUS status; int ret = 0; status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer); if (status != EFI_BUFFER_TOO_SMALL) { snprintf(command_errbuf, sizeof (command_errbuf), "unexpected error: %lld", (long long)status); return (CMD_ERROR); } if ((buffer = malloc(bufsz)) == NULL) { sprintf(command_errbuf, "out of memory"); return (CMD_ERROR); } status = BS->LocateHandle(AllHandles, NULL, NULL, &bufsz, buffer); if (EFI_ERROR(status)) { free(buffer); snprintf(command_errbuf, sizeof (command_errbuf), "LocateHandle() error: %lld", (long long)status); return (CMD_ERROR); } pager_open(); for (i = 0; i < (bufsz / sizeof (EFI_HANDLE)); i++) { UINTN nproto = 0; EFI_GUID **protocols = NULL; EFI_DEVICE_PATH *dp; CHAR16 *text; handle = buffer[i]; printf("Handle %p", handle); if (pager_output("\n")) break; ret = 0; dp = efi_lookup_devpath(handle); if (dp != NULL) { text = efi_devpath_name(dp); if (text != NULL) { printf(" %S", text); efi_free_devpath_name(text); ret = pager_output("\n"); } efi_close_devpath(handle); } if (ret != 0) break; status = BS->ProtocolsPerHandle(handle, &protocols, &nproto); if (EFI_ERROR(status)) { snprintf(command_errbuf, sizeof (command_errbuf), "ProtocolsPerHandle() error: %lld", (long long)status); continue; } for (j = 0; j < nproto; j++) { if (efi_guid_to_name(protocols[j], &name) == true) { printf(" %s", name); free(name); } else { printf("Error while translating UUID to name"); } if ((ret = pager_output("\n")) != 0) break; } BS->FreePool(protocols); if (ret != 0) break; } pager_close(); free(buffer); return (CMD_OK); } #ifdef LOADER_FDT_SUPPORT extern int command_fdt_internal(int argc, char *argv[]); /* * Since proper fdt command handling function is defined in fdt_loader_cmd.c, * and declaring it as extern is in contradiction with COMMAND_SET() macro * (which uses static pointer), we're defining wrapper function, which * calls the proper fdt handling routine. */ static int command_fdt(int argc, char *argv[]) { return (command_fdt_internal(argc, argv)); } COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt); #endif /* * Chain load another efi loader. */ static int command_chain(int argc, char *argv[]) { EFI_HANDLE loaderhandle; EFI_LOADED_IMAGE_PROTOCOL *loaded_image; EFI_STATUS status; struct stat st; struct devdesc *dev; char *name, *path; void *buf; int fd; if (argc < 2) { command_errmsg = "wrong number of arguments"; return (CMD_ERROR); } name = argv[1]; if ((fd = open(name, O_RDONLY)) < 0) { command_errmsg = "no such file"; return (CMD_ERROR); } if (fstat(fd, &st) < -1) { command_errmsg = "stat failed"; close(fd); return (CMD_ERROR); } status = BS->AllocatePool(EfiLoaderCode, (UINTN)st.st_size, &buf); if (status != EFI_SUCCESS) { command_errmsg = "failed to allocate buffer"; close(fd); return (CMD_ERROR); } if (read(fd, buf, st.st_size) != st.st_size) { command_errmsg = "error while reading the file"; (void) BS->FreePool(buf); close(fd); return (CMD_ERROR); } close(fd); status = BS->LoadImage(FALSE, IH, NULL, buf, st.st_size, &loaderhandle); (void) BS->FreePool(buf); if (status != EFI_SUCCESS) { printf("LoadImage failed: status code: %lu\n", DECODE_ERROR(status)); return (CMD_ERROR); } status = OpenProtocolByHandle(loaderhandle, &gEfiLoadedImageProtocolGuid, (void **)&loaded_image); if (argc > 2) { int i, len = 0; CHAR16 *argp; for (i = 2; i < argc; i++) len += strlen(argv[i]) + 1; len *= sizeof (*argp); loaded_image->LoadOptions = argp = malloc(len); if (loaded_image->LoadOptions == NULL) { command_errmsg = "Adding LoadOptions: out of memory"; (void) BS->UnloadImage(loaded_image); return (CMD_ERROR); } loaded_image->LoadOptionsSize = len; for (i = 2; i < argc; i++) { char *ptr = argv[i]; while (*ptr) *(argp++) = *(ptr++); *(argp++) = ' '; } *(--argv) = 0; } if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) { struct zfs_devdesc *z_dev; struct disk_devdesc *d_dev; pdinfo_t *hd, *pd; switch (dev->d_dev->dv_type) { case DEVT_ZFS: z_dev = (struct zfs_devdesc *)dev; loaded_image->DeviceHandle = efizfs_get_handle_by_guid(z_dev->pool_guid); break; case DEVT_NET: loaded_image->DeviceHandle = efi_find_handle(dev->d_dev, dev->d_unit); break; default: hd = efiblk_get_pdinfo(dev); if (STAILQ_EMPTY(&hd->pd_part)) { loaded_image->DeviceHandle = hd->pd_handle; break; } d_dev = (struct disk_devdesc *)dev; STAILQ_FOREACH(pd, &hd->pd_part, pd_link) { /* * d_partition should be 255 */ if (pd->pd_unit == d_dev->d_slice) { loaded_image->DeviceHandle = pd->pd_handle; break; } } break; } } dev_cleanup(); status = BS->StartImage(loaderhandle, NULL, NULL); if (status != EFI_SUCCESS) { printf("StartImage failed: status code: %lu\n", DECODE_ERROR(status)); free(loaded_image->LoadOptions); loaded_image->LoadOptions = NULL; status = BS->UnloadImage(loaded_image); return (CMD_ERROR); } return (CMD_ERROR); } COMMAND_SET(chain, "chain", "chain load file", command_chain); /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2016 Toomas Soome */ /* * Build smap like memory map from efi memmap. */ #include #include #include #include #include #include #include #include #include #include #include "bootstrap.h" struct smap_buf { struct bios_smap sb_smap; STAILQ_ENTRY(smap_buf) sb_bufs; }; static struct bios_smap *smapbase; static int smaplen; /* * See "ACPI Specification Release 6.5 Errata A" * Table 15-6 (page 785), UEFI Memory Types and mapping to ACPI address * range types. */ static int smap_type(int type) { switch (type) { case EfiLoaderCode: case EfiLoaderData: case EfiBootServicesCode: case EfiBootServicesData: case EfiConventionalMemory: return (SMAP_TYPE_MEMORY); case EfiReservedMemoryType: case EfiRuntimeServicesCode: case EfiRuntimeServicesData: case EfiMemoryMappedIO: case EfiMemoryMappedIOPortSpace: case EfiPalCode: case EfiUnusableMemory: return (SMAP_TYPE_RESERVED); case EfiACPIReclaimMemory: return (SMAP_TYPE_ACPI_RECLAIM); case EfiACPIMemoryNVS: return (SMAP_TYPE_ACPI_NVS); } return (SMAP_TYPE_RESERVED); } void efi_getsmap(void) { UINTN size, desc_size, key; EFI_MEMORY_DESCRIPTOR *efi_mmap, *p; EFI_PHYSICAL_ADDRESS addr; EFI_STATUS status; STAILQ_HEAD(smap_head, smap_buf) head = STAILQ_HEAD_INITIALIZER(head); struct smap_buf *cur, *next; int i, n, ndesc; int type = -1; size = 0; efi_mmap = NULL; status = BS->GetMemoryMap(&size, efi_mmap, &key, &desc_size, NULL); efi_mmap = malloc(size); status = BS->GetMemoryMap(&size, efi_mmap, &key, &desc_size, NULL); if (EFI_ERROR(status)) { printf("GetMemoryMap: error %lu\n", DECODE_ERROR(status)); free(efi_mmap); return; } STAILQ_INIT(&head); n = 0; i = 0; p = efi_mmap; next = NULL; ndesc = size / desc_size; while (i < ndesc) { if (next == NULL) { next = malloc(sizeof (*next)); if (next == NULL) break; next->sb_smap.base = p->PhysicalStart; next->sb_smap.length = p->NumberOfPages << EFI_PAGE_SHIFT; /* * ACPI 6.1 tells the lower memory should be * reported as normal memory, so we enforce * page 0 type even as vmware maps it as * acpi reclaimable. */ if (next->sb_smap.base == 0) type = SMAP_TYPE_MEMORY; else type = smap_type(p->Type); next->sb_smap.type = type; STAILQ_INSERT_TAIL(&head, next, sb_bufs); n++; p = NextMemoryDescriptor(p, desc_size); i++; continue; } addr = next->sb_smap.base + next->sb_smap.length; if ((smap_type(p->Type) == type) && (p->PhysicalStart == addr)) { next->sb_smap.length += (p->NumberOfPages << EFI_PAGE_SHIFT); p = NextMemoryDescriptor(p, desc_size); i++; } else next = NULL; } smaplen = n; if (smaplen > 0) { smapbase = malloc(smaplen * sizeof (*smapbase)); if (smapbase != NULL) { n = 0; STAILQ_FOREACH(cur, &head, sb_bufs) smapbase[n++] = cur->sb_smap; } cur = STAILQ_FIRST(&head); while (cur != NULL) { next = STAILQ_NEXT(cur, sb_bufs); free(cur); cur = next; } } free(efi_mmap); } void efi_addsmapdata(struct preloaded_file *kfp) { size_t size; if (smapbase == NULL || smaplen == 0) return; size = smaplen * sizeof (*smapbase); file_addmetadata(kfp, MODINFOMD_SMAP, size, smapbase); } COMMAND_SET(smap, "smap", "show BIOS SMAP", command_smap); static int command_smap(int argc __unused, char *argv[] __unused) { uint_t i; if (smapbase == NULL || smaplen == 0) return (CMD_ERROR); for (i = 0; i < smaplen; i++) printf("SMAP type=%02" PRIx32 " base=%016" PRIx64 " len=%016" PRIx64 "\n", smapbase[i].type, smapbase[i].base, smapbase[i].length); return (CMD_OK); } /*- * Copyright (c) 2008-2010 Rui Paulo * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #if defined(__aarch64__) #define ElfW_Rel Elf64_Rela #define ElfW_Dyn Elf64_Dyn #define ELFW_R_TYPE ELF64_R_TYPE #define ELF_RELA #elif defined(__arm__) || defined(__i386__) #define ElfW_Rel Elf32_Rel #define ElfW_Dyn Elf32_Dyn #define ELFW_R_TYPE ELF32_R_TYPE #elif defined(__amd64__) #define ElfW_Rel Elf64_Rel #define ElfW_Dyn Elf64_Dyn #define ELFW_R_TYPE ELF64_R_TYPE #else #error architecture not supported #endif #if defined(__aarch64__) #define RELOC_TYPE_NONE R_AARCH64_NONE #define RELOC_TYPE_RELATIVE R_AARCH64_RELATIVE #elif defined(__amd64__) #define RELOC_TYPE_NONE R_X86_64_NONE #define RELOC_TYPE_RELATIVE R_X86_64_RELATIVE #elif defined(__arm__) #define RELOC_TYPE_NONE R_ARM_NONE #define RELOC_TYPE_RELATIVE R_ARM_RELATIVE #elif defined(__i386__) #define RELOC_TYPE_NONE R_386_NONE #define RELOC_TYPE_RELATIVE R_386_RELATIVE #endif /* * A simple relocator for EFI binaries. */ EFI_STATUS _reloc(unsigned long ImageBase, ElfW_Dyn *dynamic, EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) { unsigned long relsz, relent; unsigned long *newaddr; ElfW_Rel *rel; ElfW_Dyn *dynp; /* * Find the relocation address, its size and the relocation entry. */ relsz = 0; relent = 0; for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) { switch (dynp->d_tag) { case DT_REL: case DT_RELA: rel = (ElfW_Rel *) ((unsigned long) dynp->d_un.d_ptr + ImageBase); break; case DT_RELSZ: case DT_RELASZ: relsz = dynp->d_un.d_val; break; case DT_RELENT: case DT_RELAENT: relent = dynp->d_un.d_val; break; default: break; } } /* * Perform the actual relocation. */ for (; relsz > 0; relsz -= relent) { switch (ELFW_R_TYPE(rel->r_info)) { case RELOC_TYPE_NONE: /* No relocation needs be performed. */ break; case RELOC_TYPE_RELATIVE: /* Address relative to the base address. */ newaddr = (unsigned long *)(ImageBase + rel->r_offset); *newaddr += ImageBase; /* Add the addend when the ABI uses them */ #ifdef ELF_RELA *newaddr += rel->r_addend; #endif break; default: /* XXX: do we need other relocations ? */ break; } rel = (ElfW_Rel *) ((caddr_t) rel + relent); } return (EFI_SUCCESS); } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2022 Toomas Soome # include $(SRC)/Makefile.master ROOT_BOOT= $(ROOT)/boot ROOT_BOOT_DEFAULTS= $(ROOT)/boot/defaults ROOT_BOOT_FORTH= $(ROOT)/boot/forth ROOT_BOOT_CONF= $(ROOT)/boot/conf.d ROOTBOOTFILES=$(FILES:%=$(ROOT_BOOT)/%) ROOTBOOTFORTH=$(FORTH:%=$(ROOT_BOOT_FORTH)/%) ROOTBOOTDEFAULTS=$(DEFFILES:%=$(ROOT_BOOT_DEFAULTS)/%) FILEMODE=0444 FORTH = beastie.4th FORTH += beadm.4th FORTH += brand.4th FORTH += brand-hammerhead.4th FORTH += check-password.4th FORTH += color.4th FORTH += delay.4th FORTH += efi.4th FORTH += frames.4th FORTH += loader.4th DEFFILES = loader.conf FORTH += menu.4th FORTH += menu.rc FORTH += menu-commands.4th FORTH += menusets.4th FORTH += pcibios.4th FORTH += screen.4th FORTH += shortcuts.4th FORTH += support.4th FORTH += version.4th FILES += hammerhead-brand.png FILES += loader.rc all clean clobber: install: $(ROOT_BOOT_DEFAULTS) $(ROOT_BOOT_FORTH) $(ROOTBOOTFILES) \ $(ROOTBOOTDEFAULTS) $(ROOT_BOOT_CONF) $(ROOTBOOTFORTH) $(ROOT_BOOT)/%: % $(ROOT_BOOT) $(INS.file) $(ROOT_BOOT_DEFAULTS)/%: % $(ROOT_BOOT_DEFAULTS) $(INS.file) $(ROOT_BOOT_FORTH)/%: % $(ROOT_BOOT_FORTH) $(INS.file) $(ROOT_BOOT_DEFAULTS) $(ROOT_BOOT_CONF) $(ROOT_BOOT_FORTH): $(INS.dir) \ \ This file and its contents are supplied under the terms of the \ Common Development and Distribution License ("CDDL"), version 1.0. \ You may only use this file in accordance with the terms of version \ 1.0 of the CDDL. \ \ A full copy of the text of the CDDL should have accompanied this \ source. A copy of the CDDL is also available via the Internet at \ http://www.illumos.org/license/CDDL. \ Copyright 2017 Toomas Soome \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ Copyright 2019 Joyent, Inc. \ This module is implementing the beadm user command to support listing \ and switching Boot Environments (BE) from command line and \ support words to provide data for BE menu in loader menu system. \ Note: this module needs an update to provide proper BE vocabulary. only forth also support-functions also file-processing also file-processing definitions also parser also line-reading definitions also builtins definitions variable page_count variable page_remainder 0 page_count ! 0 page_remainder ! \ from menu.4th : +c! ( N C-ADDR/U K -- C-ADDR/U ) 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr ) rot + c! ( n c-addr/u k n c-addr -- n c-addr/u ) rot drop ( n c-addr/u -- c-addr/u ) ; : get_value ( -- ) eat_space line_pointer skip_to_end_of_line line_pointer over - strdup value_buffer strset ['] exit to parsing_function ; : get_name ( -- ) read_name ['] get_value to parsing_function ; : get_name_value line_buffer strget + to end_of_line line_buffer .addr @ to line_pointer ['] get_name to parsing_function begin end_of_line? 0= while parsing_function execute repeat ; \ beadm support : beadm_longest_title ( addr len -- width ) 0 to end_of_file? O_RDONLY fopen fd ! reset_line_reading fd @ -1 = if EOPEN throw then 0 >r \ length into return stack begin end_of_file? 0= while free_buffers read_line get_name_value value_buffer .len @ r@ > if r> drop value_buffer .len @ >r then free_buffers read_line repeat fd @ fclose r> 1 + \ space between columns ; \ Pretty print BE list : beadm_list ( width addr len -- ) 0 to end_of_file? O_RDONLY fopen fd ! reset_line_reading fd @ -1 = if EOPEN throw then ." BE" dup 2 - spaces ." Type Device" cr begin end_of_file? 0= while free_buffers read_line get_name_value value_buffer strget type dup value_buffer .len @ - spaces free_buffers read_line get_name_value name_buffer strget type name_buffer strget s" bootfs" compare 0= if 2 spaces then name_buffer strget s" chain" compare 0= if 3 spaces then value_buffer strget type cr free_buffers repeat fd @ fclose drop ; \ we are called with strings be_name menu_file, to simplify the stack \ management, we open the menu and free the menu_file. : beadm_bootfs ( be_addr be_len maddr mlen -- addr len taddr tlen flag | flag ) 0 to end_of_file? 2dup O_RDONLY fopen fd ! drop free-memory fd @ -1 = if EOPEN throw then reset_line_reading begin end_of_file? 0= while free_buffers read_line get_name_value 2dup value_buffer strget compare 0= if ( title == be ) 2drop \ drop be_name free_buffers read_line get_name_value value_buffer strget strdup name_buffer strget strdup -1 free_buffers 1 to end_of_file? \ mark end of file to skip the rest else read_line \ skip over next line then repeat fd @ fclose line_buffer strfree read_buffer strfree dup -1 > if ( be_addr be_len ) 2drop 0 then ; : current-dev ( -- addr len ) \ return current dev s" currdev" getenv 2dup [char] / strchr nip dup 0> if ( strchr '/' != NULL ) - else drop then \ we have now zfs:pool or diskname: ; \ chop trailing ':' : colon- ( addr len -- addr len - 1 | addr len ) 2dup 1 - + C@ [char] : = if ( string[len-1] == ':' ) 1 - then ; \ add trailing ':' : colon+ ( addr len -- addr len+1 ) 2dup + \ addr len -- addr+len [char] : swap c! \ save ':' at the end of the string 1+ \ addr len -- addr len+1 ; \ make menu.lst path : menu.lst ( addr len -- addr' len' ) colon- \ need to allocate space for len + 16 dup 16 + allocate if ENOMEM throw then swap 2dup 2>R \ copy of new addr len to return stack move 2R> s" :/boot/menu.lst" strcat ; \ list be's on device : list-dev ( addr len -- ) menu.lst 2dup 2>R beadm_longest_title line_buffer strfree read_buffer strfree R@ swap 2R> \ addr width addr len beadm_list free-memory ." Current boot device: " s" currdev" getenv type cr line_buffer strfree read_buffer strfree ; \ activate be on device. \ if be name was not given, set currdev \ otherwize, we query device:/boot/menu.lst for bootfs and \ if found, and bootfs type is chain, attempt chainload. \ set currdev to bootfs. \ if we were able to set currdev, reload the config : activate-dev ( dev.addr dev.len be.addr be.len -- ) dup 0= if 2drop colon- \ remove : at the end of the dev name dup 1+ allocate if ENOMEM throw then dup 2swap 0 -rot strcat colon+ s" currdev" setenv \ setenv currdev = device free-memory else 2swap menu.lst beadm_bootfs if ( addr len taddr tlen ) 2dup s" chain" compare 0= if drop free-memory \ free type 2dup dup 6 + allocate if ENOMEM throw then dup >R 0 s" chain " strcat 2swap strcat ['] evaluate catch drop \ We are still there? R> free-memory \ free chain command drop free-memory \ free addr exit then drop free-memory \ free type \ check last char in the name 2dup + c@ [char] : <> if \ have dataset and need to get zfs:pool/ROOT/be: dup 5 + allocate if ENOMEM throw then 0 s" zfs:" strcat 2swap strcat colon+ then 2dup s" currdev" setenv drop free-memory else ." No such BE in menu.lst or menu.lst is missing." cr exit then then \ reset BE menu 0 page_count ! \ need to do: 0 unload drop free-module-options \ unset the env variables with kernel arguments s" acpi-user-options" unsetenv s" boot-args" unsetenv s" boot_ask" unsetenv s" boot_single" unsetenv s" boot_verbose" unsetenv s" boot_kmdb" unsetenv s" boot_drop_into_kmdb" unsetenv s" boot_reconfigure" unsetenv s" boot_noncluster" unsetenv start \ load config, kernel and modules ." Current boot device: " s" currdev" getenv type cr ; \ beadm list [device] \ beadm activate BE [device] | device \ \ lists BE's from current or specified device /boot/menu.lst file \ activates specified BE by unloading modules, setting currdev and \ running start to load configuration. : beadm ( -- ) ( throws: abort ) 0= if ( interpreted ) get_arguments then dup 0= if ." Usage:" cr ." beadm activate {beName [device] | device}" cr ." beadm list [device]" cr ." Use lsdev to get device names." cr drop exit then \ First argument is 0 when we're interprated. See support.4th \ for get_arguments reading the rest of the line and parsing it \ stack: argN lenN ... arg1 len1 N \ rotate arg1 len1, dont use argv[] as we want to get arg1 out of stack -rot 2dup s" list" compare-insensitive 0= if ( list ) 2drop argc 1 = if ( list currdev ) \ add dev to list of args and switch to case 2 current-dev rot 1 + then 2 = if ( list device ) list-dev exit then ." too many arguments" cr abort then s" activate" compare-insensitive 0= if ( activate ) argc 1 = if ( missing be ) drop ." missing bName" cr abort then argc 2 = if ( activate be ) \ need to set arg list into proper order 1+ >R \ save argc+1 to return stack \ if the prefix is fd, cd, net or disk and we have : \ in the name, it is device and inject empty be name over 2 s" fd" compare 0= >R over 2 s" cd" compare 0= R> or >R over 3 s" net" compare 0= R> or >R over 4 s" disk" compare 0= R> or if ( prefix is fd or cd or net or disk ) 2dup [char] : strchr nip if ( its : in name ) true else false then else false then if ( it is device name ) 0 0 R> else \ add device, swap with be and receive argc current-dev 2swap R> then then 3 = if ( activate be device ) activate-dev exit then ." too many arguments" cr abort then ." Unknown argument" cr abort ; also forth definitions also builtins \ make beadm available as user command. builtin: beadm \ count the pages of BE list \ leave FALSE in stack in case of error : be-pages ( -- flag ) 1 local flag 0 0 2local currdev 0 0 2local title end-locals current-dev menu.lst 2dup 2>R 0 to end_of_file? O_RDONLY fopen fd ! 2R> drop free-memory reset_line_reading fd @ -1 = if FALSE else s" currdev" getenv over ( addr len addr ) 4 s" zfs:" compare 0= if 5 - \ len -= 5 swap 4 + \ addr += 4 swap to currdev then 0 begin end_of_file? 0= while read_line get_name_value s" title" name_buffer strget compare 0= if 1+ then flag if \ check for title value_buffer strget strdup to title free_buffers read_line \ get bootfs get_name_value value_buffer strget currdev compare 0= if title s" zfs_be_active" setenv 0 to flag then title drop free-memory 0 0 to title free_buffers else free_buffers read_line \ get bootfs then repeat fd @ fclose line_buffer strfree read_buffer strfree 5 /mod swap dup page_remainder ! \ save remainder if 1+ then dup page_count ! \ save count n2s s" zfs_be_pages" setenv TRUE then ; : be-set-page { | entry count n device -- } page_count @ 0= if be-pages page_count @ 0= if exit then then 0 to device 1 s" zfs_be_currpage" getenvn 5 * page_count @ 5 * page_remainder @ if 5 page_remainder @ - - then swap - dup to entry 0 < if entry 5 + to count 0 to entry else 5 to count then current-dev menu.lst 2dup 2>R 0 to end_of_file? O_RDONLY fopen fd ! 2R> drop free-memory reset_line_reading fd @ -1 = if EOPEN throw then 0 to n begin end_of_file? 0= while n entry < if read_line \ skip title read_line \ skip bootfs n 1+ to n else \ Use reverse loop to display descending order \ for BE list. 0 count 1- do read_line \ read title line get_name_value value_buffer strget 52 i + \ ascii 4 + i s" bootenvmenu_caption[4]" 20 +c! setenv value_buffer strget 52 i + \ ascii 4 + i s" bootenvansi_caption[4]" 20 +c! setenv free_buffers read_line \ read value line get_name_value \ set menu entry command name_buffer strget s" chain" compare 0= if s" set_be_chain" else s" set_bootenv" then 52 i + \ ascii 4 + i s" bootenvmenu_command[4]" 20 +c! setenv \ set device name name_buffer strget s" chain" compare 0= if \ for chain, use the value as is value_buffer strget else \ check last char in the name value_buffer strget 2dup + c@ [char] : <> if \ make zfs device name swap drop 5 + allocate if ENOMEM throw then s" zfs:" ( addr addr' len' ) 2 pick swap move ( addr ) dup to device 4 value_buffer strget strcat ( addr len ) s" :" strcat then then 52 i + \ ascii 4 + i s" bootenv_root[4]" 13 +c! setenv device free-memory 0 to device free_buffers -1 +loop 5 count do \ unset unused entries 52 i + \ ascii 4 + i dup s" bootenvmenu_caption[4]" 20 +c! unsetenv dup s" bootenvansi_caption[4]" 20 +c! unsetenv dup s" bootenvmenu_command[4]" 20 +c! unsetenv s" bootenv_root[4]" 13 +c! unsetenv loop 1 to end_of_file? \ we are done then repeat fd @ fclose line_buffer strfree read_buffer strfree ; \ Copyright (c) 2003 Scott Long \ Copyright (c) 2003 Aleksander Fafula \ Copyright (c) 2006-2015 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. marker task-beastie.4th only forth definitions variable logoX variable logoY \ Initialize logo placement to defaults 46 logoX ! 4 logoY ! \ This function draws any number of beastie logos at (loader_logo_x, \ loader_logo_y) if defined, else (46,4) (to the right of the menu). To choose \ your beastie, set the variable `loader_logo' to the respective logo name. \ \ NOTE: Each is defined as a logo function in /boot/logo-${loader_logo}.4th \ NOTE: If `/boot/logo-${loader_logo}.4th' does not exist or does not define \ a `logo' function, no beastie is drawn. \ : draw-beastie ( -- ) \ at (loader_logo_x,loader_logo_y), else (46,4) s" loader_logo_x" getenv dup -1 <> if ?number 1 = if logoX ! then else drop then s" loader_logo_y" getenv dup -1 <> if ?number 1 = if logoY ! then else drop then \ If `logo' is defined, execute it s" logo" sfind ( -- xt|0 bool ) if logoX @ logoY @ rot execute else \ Not defined; try-include desired logo file drop ( xt = 0 ) \ cruft s" loader_logo" getenv dup -1 = over 0= or if dup 0= if 2drop else drop then \ getenv result unused \ Hammerhead default: no small logo (brand PNG only). \ Leaves `logo' undefined so draw-beastie renders nothing. s" " else 2drop ( c-addr/u -- ) \ getenv result unused s" try-include /boot/forth/logo-${loader_logo}.4th" then evaluate 1 spaces \ Execute `logo' if defined now s" logo" sfind if logoX @ logoY @ rot execute else drop then then ; : draw-beastie ['] draw-beastie console-iterate ; also support-functions : beastie-start ( -- ) \ starts the menu s" beastie_disable" getenv dup -1 <> if s" YES" compare-insensitive 0= if any_conf_read? if load_xen_throw load_kernel load_modules then exit \ to autoboot (default) then else drop then s" loader_delay" getenv -1 = if s" include /boot/forth/menu.rc" evaluate else drop ." Loading Menu (Ctrl-C to Abort)" cr s" set delay_command='include /boot/forth/menu.rc'" evaluate s" set delay_showdots" evaluate delay_execute then ; only forth definitions \ Copyright 2026 Chris Tusa / Hammerhead project. \ \ Permission is hereby granted, free of charge, to any person obtaining a \ copy of this software and associated documentation files (the "Software"), \ to deal in the Software without restriction. Based on FreeBSD/illumos \ brand-illumos.4th (CDDL), retained structure and brand+ helper. 2 brandX ! 1 brandY ! \ Initialize brand placement defaults : brand+ ( x y c-addr/u -- x y' ) 2swap 2dup at-xy 2swap \ position the cursor type \ print to the screen 1+ \ increase y for next time we're called ; : brand ( x y -- ) \ "Zygaena" brand (PNG if framebuffer, ASCII fallback) framebuffer? if s" term-putimage" sfind if \ 0, 0 upper-left origin, 0, 7 lower-right \ preserves aspect ratio >r 0 0 0 0 7 s" /boot/hammerhead-brand.png" r> execute if 2drop exit then else drop then then s" _____ " brand+ s" |__ /_ _ __ _ __ _ ___ _ __ __ _ " brand+ s" / /| | | |/ _` |/ _` |/ _ \ '_ \ / _` | " brand+ s" / /_| |_| | (_| | (_| | __/ | | | (_| | " brand+ s" /____|\__, |\__, |\__,_|\___|_| |_|\__,_| " brand+ s" |___/ |___/ " brand+ 2drop ; \ Copyright (c) 2006-2015 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. marker task-brand.4th variable brandX variable brandY \ Initialize brand placement to defaults 2 brandX ! 1 brandY ! \ This function draws any number of company brands at (loader_brand_x, \ loader_brand_y) if defined, or (2,1) (top-left). To choose your brand, set \ the variable `loader_brand' to the respective brand name. \ \ NOTE: Each is defined as a brand function in /boot/brand-${loader_brand}.4th \ NOTE: If `/boot/brand-${loader_brand}.4th' does not exist or does not define \ a `brand' function, no brand is drawn. \ : draw-brand ( -- ) \ at (loader_brand_x,loader_brand_y), else (2,1) s" loader_brand_x" getenv dup -1 <> if ?number 1 = if brandX ! then else drop then s" loader_brand_y" getenv dup -1 <> if ?number 1 = if brandY ! then else drop then \ If `brand' is defined, execute it s" brand" sfind ( -- xt|0 bool ) if brandX @ brandY @ rot execute else \ Not defined; try-include desired brand file drop ( xt = 0 ) \ cruft s" loader_brand" getenv dup -1 = over 0= or if dup 0= if 2drop else drop then \ getenv result unused s" try-include /boot/forth/brand-hammerhead.4th" else 2drop ( c-addr/u -- ) \ getenv result unused s" try-include /boot/forth/brand-${loader_brand}.4th" then evaluate 1 spaces \ Execute `brand' if defined now s" brand" sfind if brandX @ brandY @ rot execute else drop then then ; : draw-brand ['] draw-brand console-iterate ; \ Copyright (c) 2006-2015 Devin Teske \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. marker task-check-password.4th include /boot/forth/screen.4th vocabulary password-processing only forth also password-processing definitions 13 constant enter_key \ The decimal ASCII value for Enter key 8 constant bs_key \ The decimal ASCII value for Backspace key 21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence 255 constant readmax \ Maximum number of characters for the password variable read-tick \ Twiddle position (used by read) variable read-start \ Starting X offset (column)(used by read) create readval readmax allot \ input obtained (up to readmax characters) variable readlen \ input length \ This function blocks program flow (loops forever) until a key is pressed. \ The key that was pressed is added to the top of the stack in the form of its \ decimal ASCII representation. Note: the stack cannot be empty when this \ function starts or an underflow exception will occur. Simplest way to prevent \ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is \ called by the read function. You need not call it directly. NOTE: arrow keys \ show as 0 on the stack \ : sgetkey ( -- ) begin \ Loop forever key? if \ Was a key pressed? (see loader(8)) drop \ Remove stack-cruft key \ Get the key that was pressed \ Check key pressed (see loader(8)) and input limit dup 0<> if ( and ) readlen @ readmax < if \ Spin the twiddle and then exit this function read-tick @ dup 1+ 4 mod read-tick ! 2 spaces dup 0 = if ( 1 ) ." /" else dup 1 = if ( 2 ) ." -" else dup 2 = if ( 3 ) ." \" else dup 3 = if ( 4 ) ." |" else 1 spaces then then then then drop read-start @ sr at-xy exit then then \ Always allow Backspace, Enter, and Ctrl-U dup bs_key = if exit then dup enter_key = if exit then dup ctrl_u = if exit then then 50 ms \ Sleep for 50 milliseconds (see loader(8)) again ; : cfill ( c c-addr/u -- ) begin dup 0> while -rot 2dup c! 1+ rot 1- repeat 2drop drop ; : read-reset ( -- ) 0 readlen ! 0 readval readmax cfill ; : read ( c-addr/u -- ) \ Expects string prompt as stack input at-bl \ Move the cursor to the bottom-left dup 1+ read-start ! \ Store X offset after the prompt 0 readlen ! \ Initialize the read length type \ Print the prompt begin \ Loop forever 0 sgetkey \ Block here, waiting for a key to be pressed \ We are not going to echo the password to the screen (for \ security reasons). If Enter is pressed, we process the \ password, otherwise augment the key to a string. dup enter_key = if drop \ Clean up stack cruft 3 spaces \ Erase the twiddle 10 emit \ Echo new line exit else dup ctrl_u = if 3 spaces read-start @ sr at-xy \ Erase the twiddle 0 readlen ! \ Reset input to NULL else dup bs_key = if readlen @ 1 - dup readlen ! \ Decrement input length dup 0< if drop 0 dup readlen ! then \ Don't go negative 0= if 3 spaces read-start @ sr at-xy then \ Twiddle else dup \ Store the character \ NB: sgetkey prevents overflow by way of blocking \ at readmax except for Backspace or Enter readlen @ 1+ dup readlen ! 1- readval + c! then then then drop \ last key pressed again \ Enter was not pressed; repeat ; only forth definitions also password-processing : check-password ( -- ) \ Do not allow the user to proceed beyond this point if a boot-lock \ password has been set (preventing even boot from proceeding) s" bootlock_password" getenv dup -1 <> if dup readmax > if drop readmax then begin s" Boot Password: " read ( prompt -- ) 2dup readval readlen @ compare 0<> while 3000 ms ." loader: incorrect password" 10 emit repeat 2drop read-reset else drop then \ Prompt for GEOM ELI (geli(8)) passphrase if enabled s" geom_eli_passphrase_prompt" getenv dup -1 <> if s" YES" compare-insensitive 0= if s" GELI Passphrase: " read ( prompt -- ) readval readlen @ s" kern.geom.eli.passphrase" setenv read-reset then else drop then \ Exit if a password was not set s" password" getenv -1 = if exit else drop then \ We should prevent the user from visiting the menu or dropping to the \ interactive loader(8) prompt, but still allow the machine to boot... 0 autoboot \ Only reached if autoboot fails for any reason (including if/when \ the user aborts/escapes the countdown sequence leading to boot). s" password" getenv dup readmax > if drop readmax then begin s" Password: " read ( prompt -- ) 2dup readval readlen @ compare 0= if \ Correct password? 2drop read-reset exit then 3000 ms ." loader: incorrect password" 10 emit again ; only forth definitions \ Copyright (c) 2011-2013 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. \ marker task-color.4th \ This function returns FALSE if the `loader_color' environment variable is set \ to NO, no, or 0. Otherwise, TRUE is returned. \ : loader_color? ( -- N ) s" loader_color" getenv dup -1 <> if \ `loader_color' is set. \ Check if it is explicitly disabled. 2dup s" NO" compare-insensitive 0= if 2drop FALSE exit then 2dup s" 0" compare 0= if 2drop FALSE exit then drop then drop \ It is enabled. TRUE ; \ Copyright (c) 2008-2015 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. \ \ $FreeBSD$ marker task-delay.4th vocabulary delay-processing only forth also delay-processing definitions 2 constant delay_default \ Default delay (in seconds) 3 constant etx_key \ End-of-Text character produced by Ctrl+C 13 constant enter_key \ Carriage-Return character produce by ENTER 27 constant esc_key \ Escape character produced by ESC or Ctrl+[ variable delay_tstart \ state variable used for delay timing variable delay_delay \ determined configurable delay duration variable delay_cancelled \ state variable for user cancellation variable delay_showdots \ whether continually print dots while waiting only forth definitions also delay-processing : delay_execute ( -- ) \ make sure that we have a command to execute s" delay_command" getenv dup -1 = if drop exit then \ read custom time-duration (if set) s" loader_delay" getenv dup -1 = if drop \ no custom duration (remove dup'd bunk -1) delay_default \ use default setting (replacing bunk -1) else \ make sure custom duration is a number ?number 0= if delay_default \ use default if otherwise then then \ initialize state variables delay_delay ! \ stored value is on the stack from above seconds delay_tstart ! \ store the time we started 0 delay_cancelled ! \ boolean flag indicating user-cancelled event false delay_showdots ! \ reset to zero and read from environment s" delay_showdots" getenv dup -1 <> if 2drop \ don't need the value, just existence true delay_showdots ! else drop then \ Loop until we have exceeded the desired time duration begin 25 ms \ sleep for 25 milliseconds (40 iterations/sec) \ throw some dots up on the screen if desired delay_showdots @ if ." ." \ dots visually aid in the perception of time then \ was a key depressed? key? if key \ obtain ASCII value for keystroke dup enter_key = if -1 delay_delay ! \ break loop then dup etx_key = swap esc_key = OR if -1 delay_delay ! \ break loop -1 delay_cancelled ! \ set cancelled flag then then \ if the time duration is set to zero, loop forever \ waiting for either ENTER or Ctrl-C/Escape to be pressed delay_delay @ 0> if \ calculate elapsed time seconds delay_tstart @ - delay_delay @ > else -1 \ break loop then until \ if we were throwing up dots, throw up a line-break delay_showdots @ if cr then \ did the user press either Ctrl-C or Escape? delay_cancelled @ if 2drop \ we don't need the command string anymore else evaluate \ evaluate/execute the command string then ; only forth definitions \ Copyright (c) 2016 Netflix, Inc \ All rights reserved. \ \ 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. \ \ 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. \ only forth definitions \ Place holder for more functions .( EFI boot environment) cr \ Copyright (c) 2003 Scott Long \ Copyright (c) 2012-2015 Devin Teske \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. \ marker task-frames.4th vocabulary frame-drawing only forth also frame-drawing definitions \ XXX Filled boxes are left as an exercise for the reader... ;-/ variable h_el variable v_el variable lt_el variable lb_el variable rt_el variable rb_el variable fill \ ASCII frames (used when serial console is detected) 45 constant ascii_dash 61 constant ascii_equal 124 constant ascii_pipe 43 constant ascii_plus \ Single frames $2500 constant sh_el $2502 constant sv_el $250c constant slt_el $2514 constant slb_el $2510 constant srt_el $2518 constant srb_el \ Double frames $2550 constant dh_el $2551 constant dv_el $2554 constant dlt_el $255a constant dlb_el $2557 constant drt_el $255d constant drb_el \ Fillings 0 constant fill_none 32 constant fill_blank $2591 constant fill_dark $2592 constant fill_med $2593 constant fill_bright only forth definitions also frame-drawing : hline ( len x y -- ) \ Draw horizontal single line at-xy \ move cursor 0 do h_el @ xemit loop ; : f_ascii ( -- ) ( -- ) \ set frames to ascii ascii_dash h_el ! ascii_pipe v_el ! ascii_plus lt_el ! ascii_plus lb_el ! ascii_plus rt_el ! ascii_plus rb_el ! ; : f_single ( -- ) \ set frames to single boot_serial? if f_ascii exit then sh_el h_el ! sv_el v_el ! slt_el lt_el ! slb_el lb_el ! srt_el rt_el ! srb_el rb_el ! ; : f_double ( -- ) \ set frames to double boot_serial? if f_ascii ascii_equal h_el ! exit then dh_el h_el ! dv_el v_el ! dlt_el lt_el ! dlb_el lb_el ! drt_el rt_el ! drb_el rb_el ! ; : vline ( len x y -- ) \ Draw vertical single line 2dup 4 pick 0 do at-xy v_el @ xemit 1+ 2dup loop 2drop 2drop drop ; : box ( w h x y -- ) \ Draw a box framebuffer? if rot ( w x y h ) over + >R ( w x y -- R: y+h ) swap rot ( y x w -- R: y+h ) over + >R ( y x -- R: y+h x+w ) swap R> R> term-drawrect exit then \ Non-framebuffer version 2dup 1+ 4 pick 1- -rot vline \ Draw left vert line 2dup 1+ swap 5 pick + swap 4 pick 1- -rot vline \ Draw right vert line 2dup swap 1+ swap 5 pick 1- -rot hline \ Draw top horiz line 2dup swap 1+ swap 4 pick + 5 pick 1- -rot hline \ Draw bottom horiz line 2dup at-xy lt_el @ xemit \ Draw left-top corner 2dup 4 pick + at-xy lb_el @ xemit \ Draw left bottom corner 2dup swap 5 pick + swap at-xy rt_el @ xemit \ Draw right top corner 2 pick + swap 3 pick + swap at-xy rb_el @ xemit 2drop ; f_single fill_none fill ! only forth definitions PNG  IHDR<,mhQPLTEݯp\)5ÿz+qd|s-_n*iIXv(VwMm_ Gg B]Mer tk7ճ&+ê?Nf7 Z%^>w\̟ wٻt7| Kշt'$=]@Z7i4Ź,̭Bzҵh_' h73lc ҁk #sG3~[:xt}ǂgyrMA\Xxw {I&o=;Mc}֊O/'(ς`MYP0oF)M3.h;_ff>- א$jZdJW&Ou'.y`26]d'_E xk!x_{+ Юmj/\( 5iUυ٘֙Q1Zl򲫿5ˎWFdxqP0F$34A^Q I07DmS0|1)k,P={iV+f4x;t C鑧I $j6cg;T)38ЀvGL \:%"O戴mrO'4o2Dy2(N'R>n$.?h#q;5/{P78WRxB -맅#OۀpO#,RX(rZVm[)e&JDU7{imUxfJȊGmA'X)kF$&@3Sx>$@gw;jk<RP+U-g$$tE׶kTPvⲨB@^eR7QN{V?8~sdsmڷ[52v,R$`L0&lxi1Ҷ%“Pe2\!2l*vŖ č"G&ת& fI ˯ܻaUxZYrVעxZr!&%6kh׀'z9TG %eڹjfGh! 70*JA{)4&mrVd-sa6EFK_~r. I%zG]ҟ2OS@[SIP>Zure>k =+I'7t/?5+~GߕO?>dVߣzQ5>:tgon<O#`|'qK~?_J NmƼczi]h;0_Z2чGKosȰdIo,o?9R[YK1nh+h!TldD[ݩTtC" #'afsB:e-'ᶦM;Ü(o% $J8b+\օ(#U&]@ w9EΜE!dg[יGS5: d*tDr e8֘9ŝ"6HTW߼cX.TA`3FN˝v> >7$CTKMZ#:͂*wz1<%:b+aEIMY"a&1LGuMWՆSsBT1yxFA] <}Pf&C,u@Ĺ]HX7DЋdoka6H!;(KG'Uܠ[݊0р'ʫժr&I^<Mۚ{2G-Hѫ $jHVDz#hx G7/Yչ|kSu3ᚣ!-MzAԷ J)T7W2i#>UJ T)$p7?“ ~5,<Mh-30Ծop[yZͣT$álA;X$> d?>+o5"u1$d9QD <&Qp"-4x 8LM<ŬWذmQ N #eMԶ.4E=m_XgRDRZYTG[aG0Ld0omΉ%~Lz,C` v ϛ1n=ާj W1'9@?↯]&":|t !ϒnec[h4<_>Vg#;4oD!r$  ZrZDʷXGj1l C3nA^L~ebH8ZM7XZb}Ѓ-V+vϷgGuP{t7FǿCAZ6)rhXfKtkO ]kW:ڕ)l%b1BcA|kV(Z@3$Wi .߶UoYr9'T[|.pcu6KL}ʉhFaOLJu@A2VkVCI#QZf4Awk$f{اr1dF"Jŭ$07 - &kDq4:ƺ8^_rRv/ʘK7n .hY7(ebI7彫Tl+TmIVyXPyՄ,0xסxz=R+ͽBg9ȉ3pF#M$'ܒwH#4ŭϖ3]i֛bS 7UB=^t!M?rask ݸˢWiscAoqhbL'.زRqSb{KIJ˨sɆΐ;խVӝ@27CKPĨ*xxdm[b uMWuT!7%w+ď K!EE6L@~KP.\c-ҭ)`G(^iBUρF){bżO\1i[ xiu:uE9(zS6g4b8dكx)=ܖT!rsQ˼Ն:j#-*<5ThSIZ3Ү;#C|XR0y/%OFOp1Uxk,i[bOCH{d5~ ΊnRzHFUf9|~LyOc0<T$ٌ9OO V34M O,Ewkq5Ynh~` <ƅzVÓk @O2F%v}ℲD'̀gr@%w#+mx2g@.h+Φ6RnANM!<,a+t%&rEb*gR^@j9ȘҨGAfX$7Z@^j32 Ngc,5(%(C4Na.'S-(OynPt7Գ{<8DnIӶnP++<('B5LJ2ز1Xnװ I-iPXiU OGi,9<1Fw"X,sAZlK 8N9ѩiۤ`_\i4q*vOj۞Xz 9*d'/Yp&1yxd@G!Xh7^s’6.\fT<9nspnfć^}mviJ uݘOۊ-ZeLa,֋&y,1-]B~)i}")qjm{r8%Gy;QDXEqF~i=@iBߐ9𹟌E7f8P4'r ;@ ?pܻ)ծxƕW_suxT|&ȫ]ND'ga$WnOvN/Oʳ #CQ N,>49;Qr! + ļR Of} /Cw+7zm_ly1E<2sDh;-8/b@- v˶C{de~[rɦq7_02u'dja׫v !%EE=~`~Zz֫lvLclO(%!YfjEs}" IE!+c"^kdZܠ,(\9ju+# qU_ yèJ rRj I(('5g˗rlMMٷ-ލ ]U3Wϼ{dB3Uo_ijs[ خJbQ>-2IlSlPdOONٳEN0}Bpէ_KQi )$oF/`'Sn71ʢ\4;Є:t5bзEN '5ŶQZ9ۄ R"S欯;V "WG ,2Z粌bU<*ݵ›Sx*+PFF p6l4xM #< =a:mDAltiKeR2YeRVd5X@VRhSOp5Uۈm+s P+Oi9b0׹3Ն'7uulqY77 ܿebӶnM< F7(ߚQ[-D4x.Dqu7RmKʣ`H!-5Xr/O}+NWG˭ذc`"yg!Dx;S Oz".1t!,<]wrx 9Ő:-nAn49TT l!]nOՎpSm_V T*5`̅'HBaIORIl0| !a:A% =Uk[eo+u);7<5Aتêu RdÐs&9|#9 KoTߴ^ERNO%&iYq_< ^囀ԙ{1[[3X%;WaO'ʮuN9NxfW8)rxTkU7GSf/xf|0ni rDBGj4$%lOu1(5ON[:DP\lUiiEZFk'W #& vu׼m)$y jbZr0ITj:+cqJ#? 2SxxZ(ے|RÕ՜oU1ӌ,6D5m`Ӫy΅'jc9"YjZE 6&m [r|:ږ<19&7*W4-YRab.56̩yZ"%+xTK! 2SyE6V(4zTJsٴ|AA0?D,aX嬿aBP5a/ TIFMi'mtN8}; !x):kR"mku<GH-? ?gdðshhdăӨRѽܳiC2ѩ@ =~,ZnϦ0󅍣Y|g6ßS+np>*-NNщ@5<1 _ٕzW$KɎ3wIFם|q @YmOhwfLq'm 7 Ӕp3Pҫn<[v 8g."Jb0T2 r-Vi{ʹLϫg12U_-X2^rXΎ.+ t.Հbr<*`{Y.xfK*$Em4|9raT*g1Vcuke8m4둍y@ˣsQlIobgdIFN3`4joA %u;WƯ?.Kw2&`N\^,hFx"E!{O92{9uYKdt'4* XnaeŠ~n3*,pIMy6)*pH|w5HYۗ̑hK5h^x<.Y6W|uY+]gtSdMa, -x Ui6} \x 6pTx8+3ş \T '(7Sو-Kk+=` q'$4w\1> #O}'sBsO0%]Qmٓ3i&E&Z >^ڑg+u턬o]j8Wj:jU `#-k v&3p{ obIU|0d4^NFږU!xi[x h,T{x\3 k^|C-kh<P yj^ ~YOouqLJ5s$ӳNYܺjrmFEe#z{ 󜯭Ġ]m˝C"{l &<LjU?MƵh~9{b.<{u%C'P ϙf0@\7 OvVH.7]-̂:C! ALӧK6,F ,CʌV˼r|]gOP#O:_3;+Aa$`sQLJG bN#tbR=՞äfS/JJ%7Sj^*-S# e4:W`eቴiURѺ-K3ɪU n{Z5nYe36$fSO O~N'#h-ft\Մ$VF8*S˖e}9[Tr xJ֪2W w;x]\͖|:4ؠopzOWݱ\^;K^e=UYiuYtxrF굤3TI eX:&A[ONpl |af#a Պ"DQAz :/i QeIj[+iHy/*YN'.e~z[lP~תb߷υ*1|]&<~[yãI~ Y۶1'sxOf3:eˠ.1$Ubgvcw95Db2&TypUw|]fQ7B5F$5,jۖwoQ?#LA|'8fmI1Ҩi[nԽ/' *ie[܇JqT`HE$kl|NjJ/ |l H+Zry )?<%E3 5kFZm2ąM%p(1.V, _IBw50 +ϋd*(Sls*x`yt~:4%m>|^]]?>QƓj%y54Uzx Np? bWmP0S;嚧[UuII/(Yx.hd-RW8]; 3F ORrVIfK,S e*F1EqC;ޅo%\gqyuÐ8U*1AvDs[rԖgQDppÉ,;)9ϬiťGz֬>?AU2i9{“];bw^F ΍z]}|}&^qw`'n*DK}CߞGtq>sSEfiO0flxMv2 VebG(;C _6O-{6Ѽ,Is[|0C|0'z~x\î#OMTYr` +$0zx~[_Y9l˙|˴ԧhNI6ȟ>\}/˖K*wz8W=H TI Y3h3y2u8r!EJ_?i ϝFu+Sk7>2%,1ŤwV\LNW^0ר3dޫ!Bx/տAHY\,УgZF62B~mhSՆYykƞfhxNY aPYk@AFk I )S1ؑD/>U+הpTG7bJFݳ+.E $.1x@`ZLUiqqp!Aa-5Xæ"=|Z_\ܣz 295p @5x<գVlnlF0:_Y}ܹ:)<;;[}8Z:v^]||}}weo2UPU(.=C7DZl ŷZ~a 5@nC7GWOkԴ|q`"=>CT 3V]`22%D5/6+9ykSJs4Jsjε->vҫِ_B676Cm1K$?_\^fx_27\ < }BY*1'E’$:ڑ# D yx:Y4eJ\*/aOxj_gD-BeWbY*txڙm3<9NǼ'{3hP?0mI&O$4󹮴8c61|}wLY!.Xx:s)^sz.³IԜ4^^1-ќ-'4_ OT• T5Ee}8DxԿh ~w4F1 ;AKSsHko LarVw%𔯏jOat,ONπ#Ohs!Ҁ-2Xq}f)VVӠa{,l6ih-'gD'im5wc_DFg+~u3ϳsgzaz[3ddz_wUyz:Ys FS #鵆F_|͂)k"UF-02mx"OP"ϞOȧmH GG4Qt=ҶNx YsYBO^<4iݪ !CmXgzS&*aᩨ[.[ Z ͢N;H3Km˹9 \B0l26j[Zul͓ *3ʓ q_^V'݈[<5u͈ȓT2exV+>SiJrr (T*OܐA2'TM>sָ6P4F˂ ƲwC\s<%-Sl65`< TIuyHWoI5譬iS.iqzV.&.RnK{N;佤b}Y2GN!}I18S6qu=>gO73 dI ҥU: ]'wūXQ /!<RȍH)Ԍcgޠ Mm&y|=ôry.YB/ kG1`K$3@'j8ZϥO7"a#OG;m 'DЀgd_ jVN(sԙٸgOe|gKqGFYŸ,B۶ OײiywB,XC򘓫m=`pa]LӬZ:[kFєOA61{jlңPV{52_)Nb Zub1ҋi[RvB!%Ʈ UŇH$S|w۷YrzU獅.})wzx.Of}a2\LJ;_ḿ'KWU,2 z&m[9XD[J4xUPթx[Sf@v`'µ ^tqvO';OCj,X?NJZIO$# ?Fk6l ?i OUԓǣ[xA*[𬟶v<9=:ӵ^aqr{VAqσzɹ䥦ϱ;E%2O m#}:z]G*[]ef#XR[U\6ΩҤ< 8[(:1<[iShJC\LIf-h9/nZlmD2 Z3GyrCx< Oʞ _m]0ONgn}UGdU]I&O5c GZ#1̨26K&Χ~k>:QPN=4Jl'$6R -/-ɄxGG=9{vv˓ׁ]y|x)[Dݐ7whyB fZE,t~Bs\_$1@ꐟt9͉t RgPsEV%2 r&BvF G}] [G7|/ "O O\2Rp'rKxFyl6$aLSȢ g,FDX}{;|Th#ԑ]=]yRv,CaU2y6~^Πwz <?3 @ 5ּ5P5a<];fγ ay}u>@xQ'=d[m}QoR I^{)|ʋ=r?MvN{9Ȁ]hWMA`[d ŷ OX@ݷuo~e7}hn|ɖu*fܲQ)iuX{Y3+5/~h-\*Vi3>` $k#8"|91x@3CB77Ǐ_ -q. }d>/1d,TlVQ soL=Jr72=PiFtaszd+BͻTj[2 K)x}ǿZXpv;I>.6 *"?Ԓay︻&`&$U|ۛSP6ef5JI`#e 7].!hUlc :4T'Pڥ&R{Tq]b5jͺ<9v\vNM5B"]{eˋ3@=̶q(ș%MϳLmge7hOLG*QnQ񦧺;Ƴ$͛H0q`k)dPb,HGӂ~c UR\[PqX7M説ˎ7Cq{Z],Z0i,NxD%QM^_RƙǍ[Z:~nF =_ (bN7J/E!dÍTr{}ߤ!e9 $G흜-|geIXi[y0b4}U9 8Y.%v QĎ2 10Vyk}+,ˉ]ߦYk珎?Da!h.~K.Dq<~g/n"`iOb/p vwHVPf$ʜ:%!h3VAt^L1vPDF.^Iw0SkSL[m>CzkpD=B0(#og48YKP+n]"4DX̗O;i`hx xˑ'F@D,dكy aC7 !xS̓moݱvwٳ~syI3/ >VIuERw<ǤmD1*ULd\_ɷB.6܊&7j8Rȓ %-%yhHZ ߬l (ź dV>۶ᩈPsQț&~$`GqmE2K%xڑu<ٽ< wfumjyHIgŝKK#*tvޗӻ#l,"it^z!:v!< Fg~bA#{x%$3NQcGc9oZ3nxi[cPaYO/3s.Z! l.< =ImMag%},)6X,ec3+;0Ζ'm=/O{o;dn*]|~sxְ!kh<%]d*%KϬ'F9U0Cr&,3Ya{j:lbF.6Juitxo<6R˾mJJ'Πp|ٺ+Wyjvl!;w!%l~aNXI/އzx@=gwxPx \Qj[y4xL;"W|][rwO>~~sC4ZERFZPcKd{BU*-Ԉ[˝]vA XkFma{ 65)<'!E+[I2%dg%gEP+\,+yU#{1w6}C<߽յq8Ivmpm:@s9g||e˥GPURyO>gϳ}`UxJj[IyWA j#>p ]|6G<[0썥 jr[UxSwVc @MԖ:4gf0$+O4ϓ ͹g^Gγ-Ӫ2/ Op@R1m; =eߧUe~f8#iOKvhp<9I)4i[z@BvФҫl M+jUc!^$?FMqt4T<%rڪP"m@j[OڲPnAO,K~6᙭|![v|US(LVf'T|Zm*JkTjZv$>,6 :qD1-ʸo"OEiZSm 7!1 EhPScgYuI'~( GVjdr<< j: M“ FV ZObLw OJYTV?usKd$a<5WB;O|䙺TymyDpjG@.љk.b롏*;BW =j& X<ۖYxK,b(9\ͬyY8ZI@XU !&Q$D#UY^A#GDG⋚2[Aom[ ™طlIMi#OLH(3M@TRPt.SchM V* Ji"`#ϘO`\rVۑAk-%עuXuKQ Mg|:V+¿jgIVMx.~< 6Mg'_] (xdv._:t>g-l:H+Nyb*|B֛5$x&[Q_ ki~H\K@ )QVb䉪?K2Sؽ"O+Mt)N7"/F֊',c݄'(T(caΌFhWFζPml߽QD\"x th"5,jUF+'s1jy_φѶHA?,wv{A<"; gλϟ^B3Х2Y˳mYxI*F5X3{ISP AL:"vj3Mc%A5W/>>O\d) F$Mü$CՒ;L8x׶;WD_itjb[ѭVV}ZJ OɺOB)tx0 BRWlnSZPro]hZ@OG憦 el߇mMq )*yB5/<<<YIjBCɁr<2lT(<AvM䇍%YHۦ_d\6d$2/pE<(`iW T m? (sTx+<6 xi[˻2fCeTxHVNҶe{2< ux3o;=ZgԶ=Pyw /^=^燇#ҹȻ>xvݞ#[{ӴBJJ8h{j[ + 49;ʿf(w6v>?+H=[v <%lD7^Yvն 0"I#?B6T`G`mؠWeJix?˿4e9q`+Nm$-x 𜗶 &`k :0YlP)g!wBw}s7, I)b!;O'R7?\zO"'}dFQ耝/zr O]Dju< 7!upi['7yնFv .'~||Na$ CRyZZmɂ֚T͌Ƿ- -蟩ZUԉ%iqeKm TT*m@珽6\Q_6 '()Fb0v$qJO1̡3sIN/J. ѷWqJkyKmASꡏQTЧ&m><0gP$tlj $%ՠ1ZHI9 ¤7ܠGښ`?-b9g6OжP11smPLU(v1|3 m?ݒ0|^8^Se Ԯǁ/qʊc4HWe7h[=d}=tnT#1y(==.ɸ ǹgwp|=TGs<'L}I:}>Y{ߩgJTY( o}pyƑ*?Ъ nON\^>>>>+x>qp[E)d#:L*gkQ ;6F>E_'6k[ A=w(6Qx^<Ϸ<~OCaN^$院ϛD ϲo0YG7S3 CN3MWJj&" Kd}lF2eݮ[Q9V-d6w jx34>Yjh v[vK8ׯ[~DŒ gh]qDbJ߇/hr$+27 L-3yT]FDI0 „O3-SS]KSoAkFTIX;z%O)=R_Q{|3? B^-[i2]G0#4G|ᑁ'x32w9!iۻ!o:0!x$CC(I2e>{ˆzȳVz³yBe+x.TkPB}gy9S53\HZE5|dx:K٦2S瓰$&,D똕T+^zr?yhIraO7 -LK~s >S1F6,hjl˻ 3s4@ȩG^ FSƏBRE@d'jVYuǸ㲶2;Uc_H ykV j !75#Hs`+)w.\VsӇ*X-4O+,(x@f^Ж55Gv)u$4Cْ O*+̷T؎Fh".@9ۗI\~4x}DI#}6cjgcOY0Ch+<;9cʶns3,3$C|˟=מ@3B3³{\@Sd U"OR J77iuNɌebgACO+wHۏ~ -{F,6<-5O]e r:3a6 z@exZr`hfۜR"Cfee̴"DMOs>'gJ2''7Syœԩ=`FTHIP'&B;:I"x*KW/J̞|Y)tlQ`Yޗ*k?~vyxbs\yZgremOX}zIP =iۛ7=kOՀz4˲[^>C790F4d08_}-WԦL\L''@IOV& E:<<QVo{Ų« `ȡvFr B9G ^莣QF":?3pOe03em߽.ï3=O>m3&yV4fT~՗P%G$I눫[Tec4DVDc?@ R)^;f7a"<ŁMe\VӶџVҶES1^ ''Zj[5Q0#FAfhex4SMigq\๢0/m;u*ݔǏwx)֪͂:x3/5"OV0w ;<<;^׼~oULp\.sܡQ?i*tmm 11)[A[Gr8'.*s*e9a4[󔜄c 5mK e Fԣ~RiSٛ'9t0;P47GMEܜy)k0_:\xkum=@= %.D)Rk@ 5rusDz *!?<%)Ƭu xol2F]V [0KGj>*<%4‰`vz>=VW_~UO@QMaA@7~qճy\ϒ."OT;o>'?*v~yKOn_yCKkUKʍ'5ϖ^k9 YiGg.A;O4!d3 64fO!}\>sMݏ. zyy2<Ə235-JÓwdo>_Ta3LKOOU-M >Oj$;.].]K碑 O@ub6_q2 zqa ߶ݗ.L{z5 J-3:.ΌYq>^w[ssf&߁﫟M$KGVo =#qWR+3 V00j;>3M6SӓԽ曒VwFTk굘QRkf W1=[燏>/_=Pe[U %O+Μ]gB"LNM"U,\Mptջ;h3B[_\žJMaM<'NgEkYQX&(U Dx4Qno}%Ƒ9V`LjtU*,q8x;`E\DOSF7.sz[f2<ȓ40կVHbNVߺ8vУO>zs ?AW[;J>W@igٷd:;gj%M^³ѫWrw}\g1ƕ~! "at1ռ^]^7z-ݫÃQJEDKt Bha`]@چ=J|S疹:2x*5,kcf)G'gSǘ/7BN?bІC-͘v|M9]KKpX'֧MQL BڶZ)¼ j- xӳ ]7>μe-ͧ+o7~[.;YoONHkN^/fHI%ѫ_:L铎6SH"Bс;|w?2;!?xs-"hPiS/FiqAUn9*YHuKzqZHcBY!P'J5Z-g{#msqoZӎm.}R !ֺi"d<\;Nshx8@쥄j^%S<jv  ڜ=F?VG?zﶷz({_ -ovC|^m ?}v}y<''ȹ8u3@ݻw?zqxǻ<PxS<txBiW cg[z~#$$ȞdRwPǤN` b*O,i.z〬wj73وfFxY@JJ,OOal^uI Oe8 }Ky<=|:>E7E׫qtwg3{Ĺ:ӧϽ{ѷjTu궏?/3ϳGCgG>wWuٳlYOgl?5~k]Ծ#)w~jh< F 4j<ٛXLKbZu M#Dx"4T=堪-mSr3rm%82-m`ώʔ._k钇rx@j K#I<s1 TƳy8m۸ Oث)7 v;7!,@aUCLH>4}^p^|nc:~nR׊'nC3kb?fo9_XÃgϟ$Y8Ux.Rt=!e#=3'2u^d&y71ozvF)i[y;#;R3)ؽEB?fЎ[Y{*jʏa|.?}W_}BI4EC>sug!+ OǫmwTlWoy|KT ytz I'F ~YZo-25m+hdMf2]}OێZm%,x+:AYr-x"?&<<g.]L5[4 O+3/]8OW9 +ɮ>v|:~qg_ (*{?heħO\1C&q^ܫN)b^˃WwwSOo}C,g|'wmXw#Od7k5)tX%R:3^ے>3i[76m< H R'H#FW!.ֽsm38dlcg7fX*{ΐdrZ04+m=øBE_!|fg ΃/Q􃤯#=cٱsMkM2=5y>|h󏣣]?H;|k{zv߅PM}ɻ(y{fKR4̑g21቗ hd}V+ev~N]Wg߶W70]qyHho}Ǟuԩmg)7UJX!MLѼکc L2~xh+>5 hFw\2\lDYR|"aGu5ʰVOs oD^mim{VV 1 ? OܰdNyԦlo[mCwwtqK tvy~Oz};:aҲ)D+eiUI ;C6.{鐩w}gG[P0xyWyEωi]yUm;w=Lٰ.gMEQ"Oa7 Vuo,Ab Q%mAu = w ̊Ozy=,F٣{xz[p<Od-84,/w"{Y:,lrgƔD[7Ҩ6W+,cmsĔ%ilCd.m'Y{bz>wg|Vؼ/6=W>Bz}CuYvLr>~g|i4[덋[o&wSJSiZmZp~~'ޠet/o7JœLDj"Y] C5fu~:<ր!9O i_Oȟ9PiFI(߆pm/x2>uR; p8S(JZp9<%Q; Gi[3sm0UwRDh[ybϫ^GzCϯ?.{+x%ʢ&SzzhSDl{MzP ?+㤈`yp}1>KC<'U3Pf竃'~5 (jX] @` l? aZЈK\bD)L-Kc5Kh^#jtB[ul ս"Z\+ʰtS z)G:}@ghfcGA0pӰBq+v;4'A?qѯjտaMX/zL [x-4O.쇨t́gҶyFu,lyv.DG1l?oR(.4<}z~=kig8GY1X&~8\2#+%e{u ;oot5˟"4=Cϟ.oJ*2PvpbVQgNA}ҡ[d'C&k,vdZ=>a(kȆ _#1怲5wxe1LBivM>!كb/UyS=&A0Ҧm>.5!;%#Ci=6]$kէ}'>"ƛW]$򢦙_8$zn=xv uy|޶[=$Sz`؇)'ˤvuJ!Q_#J+v6>Ϗ1#l)'lx>Z ҝ%lbM ~wsOU(cC;[ߜ4L9@]m佴|b;@s30CxYW\OF`AtpKVkw%v9I=f=;L>mo~|;O(FHxu:Ic:hqr>ʖ~LxCFn/:x~X_{SԇQGG7!q-3@{jh}Ok==9ILG:<ԫzP]L/<|ٳvy[N(3;xOie3O ϔeSRD2zhԜҍ9}W#A ߬O1k " O~%G^<3>q2k,Ljit= Ka-%m[q}ٳ~z_Ǭ-^ϓ CxIxZU"|P8WYf{R!Ҩ ƟmYU2DԨKE"OOV+3gI*O'3;ݒ<x򂡔(&m0>DOۖDꅭ 8+WYܻIhޑTSFEσGMdg =+T#nۗ/_v"m$j=Sf6Iᶂkgho+bƒg x2T4Ķϓ^x? L$bUa y|pԧz?:wؙi%C1`_PThS[a5{Dn<=x˄w{]vgօw%  +''o%oWh>\Mb< gg ;_Sovg[$д\ΗRfΰ׹m1;a],!jٰ[DAbcWiA'=΂:9b 82+LPM`j}y֯Z+{EVgP5O(Z~DPT=y/c66tavP?ϳ>>?Y9&K0$s(Ur64Jf2#&y"[&L[ mk'홶Uj߈f+ *ɉk5Ȅ Ux޶7s9NҸI'%KFmG9G =BnҤK`VT͞3%}Pm㣳X;Z3*3'yOMelX9iޓRl^KoC ϋ.Eৡ3}L5י_}.g_!}o{W]ΛCSɺ_1sM*՞z6`|Dg7պPB7ل3IHꋾ_3Z$mc/'Nbʀ$Rc{OOȳIi Ls ogZKY w'2G{s }P8N{y4`E}ӌAWW'y۫ݷ.oɥɊ>N2|x}f!}{:<?EpnRt a+w3smzVTIӐ9"NlS# Rـ4K a"=2Kj)6Yt8+\{ }D0E0G_,{d>w3~=D/QhwO}O/7蹻X?)kem7z`xV!u((yV=mIg?yŞ~6Jyvۉ/@C?_3ȢđF83}u{ o'|u{T6A|Rܹכu ͪy>]˞a pUN9 Mu Ϙ`jм$x<y.Ȗ1<{oɈ%oΧ/z{aPwu@̼W!DyV yOԃ(_)Xw~>!iǁ<_*x64L$Jƀ{($*>!=}&?ijH(γ;mfmυ+`ǒٹ BWqMϟu M4CfU~Ol+7wl9, <~Sa?mhT'0}ɞGygD ꆔ,efyx>{%x,7?;Z47hdV\.x7mn={ۄ^+0==K/aFn$=s7^zc{_\ex<>@UΔG{wWU4eo>7|߬TX3eP ;7^^³yx[kݞN;==;Џw/!4V1 d٦ +DILrTiڕ8oy+45[sMO|L%rR9\{>{=+qR W;*3Mо崷=ҤzI[/ږAp@K?{+fՍ/ <:j7dA~s/BVK, LUNuNVݖȩnU~̡9gx1Mv`hC.N 2X̆" M]Uӵ[A[O40C4/TGF $:?O?@@2hf9 y~ڔTj&P5- 骄gɛpxlՊ:)tJYo .eD#o([[WvG$&4G{ +X +^zU}`xA{z:lGu|Aea^v쵵BnWGǫll3foOzy9vg<:<"ݐ>>Gf<9)|aj >=nŀyQӨ6<ԦP\AYd ɋRMR@H|޲jhʗ~@_M!2i-hP=~>vB?8;Ix.*xNq}=N?.bԩbq/_]\KX<,%>}-*;cd3&O;x^yPGx~iɍ=m,SU6^z;\nGϬ:?- ΃G{;w~"SJu)h:_bvovuyI4órGp9iDf5z (o t?pr\Z`fنsl0:=wY.Dl&1~/'tlAg懎c k50^ói嫏w9$mx7kALC=гCZs???y|~ GbR=vpԌP Ş!|g?8%Du`M2"RbzuSv/'w)9q]f/᮷WgnQv.i7T^ usѸOR&[Jy_O.P;9hmSs}߈iC?C%$xYY:}O|\u|)?8<=?ai@qtmG͇o>B[]C <9d~7LHhAdx)6 b2y$,oST41/HHQ#Oqfp:Llڤ\JJ7;P㫑?{YOQɄo6ҝ ŴŽϖ \AT-=Gf=a1 Sf߻wj窃qg^gGxi7>"(R~GpK}C8o]}zuo_xWGt{R7_A_Ras5==oCvE]y_nfE]_r~2ҡy“D\YH<ӓ]::[O(u7Zv Bx*Dxޓ$ r,ҡ%ơg^nn#<%sPzy^ny 7˃2dQ۱s-vSoz®!;Orn;ABg熵_QwO)c8*/9f3NRdx:a&}Kxn_#<gUe\iDx#1XҼU0-mk̉O./H(c3FJm<'p7]0IUBQ0 m-1=L&߳83N^<3a Fz?cy=<5 {;*0'0c>x\\"*ұZ+XX[ klSnj_x|fu.GW$aO:uGl#gy\^Rjbv^Of~ JOk,^\v'mO;BqϯY- .!i9J2kPPbL:S OO+#O$ OTx0AOYS0dSY PA͓$aybVHZ-( vljj􂑢xi>pod?|jlcggAKq^"~<.cYXzU?_w9>ZBĶ>>3w#MMVg%'lKyj| A'vU{~==žyww*7#B5ퟟҾɽnzwobgxR=`<yڹᝣ;V=C?0{"Os"O$6䚧bi>.JƢ g2=SGOLjT7gc!ANY݉(2<A׾.cZU^0" j޸ =w{wa\ٻb};g`eO6g룣Ml3Co:{f=O.SCg/*0}|cKqqm_l7]]_w՛K܉|JLW7gi&5.X~+3{Gt5LXx⮃YvI"<~.P9̞9mkGÓ Ê Ϟ1%C,;UeyFX>t_TYgfst鯃'[Ntt&UEEyj@rO.<=Q궣gLK%OV(`d(v͗=}+]# 3|=esUݕkom?{ xUU&`x̳Tu䛣mF$~}Ѿ*6b+ómk V$*{ x[8W'8UgOlđdi,=ӶOG<O49f\_։OB%duTx:d<ϫݑsٷ y[%ywWƏ>}01K1ʊ!컕+>oh"*hhwy mpkΧm󪟿X ٴ7B,(`OB'Em<:1B)'CpDz8Ք\Cm.yy (ʊ"Zro=|ov{x9ח3櫹!F!E0eTQrpOvt=Φ4#wD}(Cd0MIHd aK'Dbuܹjy"4C=r͇1Q~a!;)Sӧc nۖw^N֙/W瑞ɃOR\N :^(rKu1 2gwn*ib=Q%j_)g듶 ϏD{\naO.dRi+Ggr" )H`Ÿ~Z$)-d{\9Нm=;pƎ&iudv9p'i\/.0w6+ 51obZU\x2X!Zvqrqe;!U1N 8bsT~I`_D^p *.v.䗎4A1޽5DsyչX4dkYǞo.]>{鐇oUh`7Oy0‘xfǶb'Έ Ġ|]#yfeZᪧ]lQƶdUq-bvS}hzyǾpt* k4x2jg|=v)x'Jž% WJx*N|a͓ꯘ ;)Jjo+{=SġD:xHf์m% *]Ӷ(t/ l0fh͓<!x σ+?>г;%LU88A`g?as ]nWѹ{vGɅ:5GW qSUId_qS˔i[ڧoT|`F Ш!<&'#H_j2k$^rZkY.4J0ybSFWYRм`0H9 >#ͧƗʹVnd{ܧNNӞZm+me?%\W σGcg*`uyQ6c~(<W6!mc6](${J:2?[z^ 7j铴7taϰz:IC/eIiz Jٿ5Jb_:-P h-EM/`Ag+j9tlvmADd,-R޴ OPk_| ĴraOMUM';5+m{w4eOtgޟJQ)m1}G>ٞmK;dWTzp @<;?#\zF];YKCOYRSiyn3W! ?~|fUğ_sT"Oy>-< 5yKݸ?m v!7Y%5d$hF57-ƚl p#b]%cN.g>B G"!iR֌Ox+L|yȓz| yc7yk)9#>wZ= dy'gMKc}8/]4?B%;>Z_nΛ>ih/oV'.mAAM  6^?m)͜yf9A3Զ{=`ն5sV󌳭GLV3 n'~v4 ڑM fRA[qP.5s ϣ~bp#L|y훭*ex^V /SEn9> .CcKygBo1=nvc붞'׿,9tNϸo"=Ġ~ ;>tGzf0z{mTqSlϹJ | vy4&/6:LjoFdzD=mkp3K1< Oj&T) O @4'q46|NJ b5OuAKZVمP^j?_<[Z6/?vq}:6 ;?qgC{\ڟ]zzh~^3}zw4Ů}Qt)Aljid퇢ݢg:ӛϗ2pSEm Ob;΃U Cz*xZ"!}ȭMK*EL^exex2g9Զ1tC\AEf$³sm-xž$pp|P#҃GLh9I*ΘϪb:"F&!ZfP ݌")چ-u?\Ouce3&Ev:B`Im!$l~I 1O3Qg k1.Y#3]5*o RR!D_g|&=zx_1 ~l6^9Z3Ju=yarYOOTf4R($rpL4b(MAO #~SmKdJV|hOd#Dy3O9k76_P\Eݑ'U˩$xJ%f9bٌ@O`8S?֞ O?<ZRF5LX W^p> erާm V8zBJU =q AZ4& S|_OT2 ;ƕڡmƓ FuM:BJp|e\uH񈬶ܞ-_\RS9k7nu H3Fw)lj{fyiG$x ͆X^۴$+ Te^;9@Ϥ9ç?˾vRIےB # 9xy+{tPhLr~Y+wޅ=a1'@|^k_\Bw߿?>b?]Squ5p{_U#M3_G SצGϻqV~x0w9GrKkUQ]һl\_?|sae^.Ыœ 2Н)+Wh!JfyƕU[(o^<ݡ>]\.:Cy O/R bU+М7s=}bEij#xO)txTۉCRy#d3uDŽG]is3b2"4$n@fkkg9~EyXʛc6xR~-shW7?zQfSig}{h5I7+}[}iOO\ +HO;7d"Dȩj D`}գ OQ?j8bIW-Ht~ѿJ@͵ʅ$9 GSNMe4Hyon/v[d>K{z>dx>u/#||_e|zR4 4uI^gWQ. {VD#O7L^P]zz^}EF6'%P(Ǹgӄk3 r&< xt5gDT "=,Jt1?Xxb1mV3 b]b)s]=_gm3$ yR]MxpnLlp V~>P9c A`ݢVME므wܠoeBdD>~ǞW7lF]bVHo}3fxG]v3Y$L7f#~(bՠ_pMw:KBɐ%܉:{ޮ$q|Ԛu׾DzY8.~:K9DPNv#'fsA_x?_PڳK^axf>Oo딴<^ṫ"gWkclO_PogIǏ?5'$1ԗ|?_^vAs ȓ܎C4))W6$'tUU>6@hǓoՂmQbSrǢ鵩2!&S8]M>FILӶ@.b\2<4MIW-Q{>K**6X%x&5_ 6DurM.#RSmo6<,A!]tzmGwe7 )_+(~̫yVkyr 6Ꝕ̳nRJФFXǯY0dyùXxJ ?mP.O,VƄ.D+gX݆' $| oz#O<93m*7VB{-,X)?&k t~j< 57-~CŰ0+,7<OhFhjra xz`!"oGOG3& 1ccx\^N?}uYҮW!L} MAhmO3Ior |sww}ӧ`o`<坓>PXlMH~^ \QVG2K'iߛ, lq φi`\Be)2V#cp^ < #uys$ b<3yҶ3>v^(Ich(?}"O< m[}BmˎόI[_H#ћo;ts69쌚[O{~=^|[&?_c|*s8? ei#P}|?^}qυU' 7i;ўfX2Ik0O<1XROɯUoP3e/JlX v=޽ 38;#eDԧVhN9:os6أ珯^vľ˗Cjrd?~޽ O`2"OgO1*?#hӲi[T$V S Ry.?GhhxJc'Jg'Ȭ9Fm 0a(k<ͦfZuc~ӹls+yڷ=CSc>H1@EV1Gό<'=i9==~,skE{s*mk's1? < xV<|23!I= f{-cnw'Ȗ0L\T]ZiJMUr}jTF+4˟ё'MIpGtwPl[]OZFh۲ɹ((ȁgc6ͤ_kB<_m #mqms`z"{yU* xN" Lsq-y"aqO.' p⼘G'+uE |y|ƋO(R| O34=F{v~гEF8onSԫUH|@g{|%d75lr t-/% i亠0RDAm 5Nyb!av^% wjJ:" ŚsDސ4X6TGLC!{Hƨk.MΜ73m6;'l[6 M;{SƋ5]y8`uƍGgƊϭFDTv7BN-ʕ"Wq*&AoFy;qnҴ;hb팽l}~}pn vûaSޗ^,XBuΟ,SgL~_"zۏ;Aҙ=]ÏCcH9r/`cg΋"aFb~!5xsSxm5cɮK]$ 0U3|Tix/3/Vb =QSwp}h2e~IDATŇQ[NhZwдmP(Ł0bT|YNjM̪@%·WG3X))3R#Pk}'#Tf%eEj^G1ι@d Ugރg;oateec> 8ӧĨ?gEۇr:PNdfjNskܢ&󏯑gT-+#);c.I&0~e]Ķ|ˊ Axf; ::'[Lg$?!E+9}2QZ0袐rxZ䴓Fрm.0SzgƕHk$S֜6o R&ǻ+VX469C7yGޔְ$Ş=ݿk ͡'N:]h %KFOX['M׉ bsx>07ʿ] *%WB%7 #;\"~.MEsYWjTE 둡%Jj`H*$RuMJBIaq$΂bncuO6سk|q ?UG co '_l}>' ?"#|`(>8I\=wrmt8ϻ8v$2flYVmM V-D`GOj2V8DJ}EZ vOAVGOږA"Tjql&яC=D24[y2*c|#%sdޛ7<3IFHpߪrڶTem6Fu~>j|6|zm߂v{z3%n=+Sp ?9C!*{O. +vrVi##]>_9y>?,!(8?Dk9O%?qyO]Pؑ:9wX~,{pxLOcSQ.cx;2x2I"Ҷxz"EOR)2Ņ"A &% NS$_\yFG$S v|fT$A3󲒜*ۄVچCi[i*lABSǔPƆ(0A%ɥAp*x"xfRyxJZ!920h B?"~O3<{uE45vajY wrVORg: _0vy*_ I[|y}f zv͞oSSZ@ƯAYQ#O(\KES`{Ha貴95m S<xe n_]Yo;* J~x~~j^&Eb/:ُ=߻O?BCLJۡ5PK 'M@f}ţ]v(3y:zs%zږgS l[ )ZC+ 1˶QQ*`BPNGR19;QKM!bMmyb%Py^yY)Φ|RxydsT3?H~o A5<㽃P/^.=xf?-ɇˢ?_7ԗWQG2=qg1Ok΅ӡ'a=-k;>8%]"Ä7*i)gGT+XAPM.''Mdۖ9\9w*0$g~BYfK;u!Z)ly˛5,r;xj.IP߭D [ȒdmY3og ߢTqꞟbz\ެVwk1\;chb?u-#[{, m˷G>it)ӕB+ Ş/_?=G++>[3{b}<y~yy#Zآf"$­mBWbg0QQγR֍ں $pKNe c\OӘ)-mmL!Z0i`z/gOJzeY *if"_ <% &/{eqr~ÇEϹEO"z瑱z6P8qǷEV(h6#)=>ޮ׷>vS&d=usޞ6ѯ722TO̱Be//Q'Չ! .8=gm) FsSE*x*mz ,4֒'|b֕V]p̙E6Reqt;j~A^Hrc>2@V&\aŽ܍F |:IyJ!k篩.ZXÇs+;4tVݧ g@NBNkovnyn}>تk>F~xY-ww/vMb)$|B+-,ʅ7[|q}`#Ϧ3̡́P>Ȓ~Te/ް12JޅB?O_V4aaPSTGw7#yTjo5ﱼ =k_v'էiGaXREB2mPȅiuUUQ#Y\4MNpWkM&ufG tߠ$m] xyM~^,zUa\8V ?yZM:`COkgS?=n_>-jދ뗱!g{!>гv]rˍ Uhy$ju[褵O|ne|*,&$^b܈8DAà .9ʠ BଟTBWhvf%A=cu]3aUS&T ,/į낧zK}_gd.-stD~Af>M xO+S<]hjP @enuOĥm?=g㏷vY[1ڇU\ޭ-)Ey~is鯿~NCzyX!՝bL.p+|vg>5:SS%%a_pw(+R˔؎ ]i},% ~b >E)3`+1M !T%p7^X{ [/Ծ 9`9?kix 1"xDUlmRH-Z.P -m6qVs4xI^yl\EГ!S/]wY>?u!LqYZA1.z{mh~˗J *FJ '=>mu1P6ɐc;JO/>L"G-4&j{V~Ӆ,k67!v %rUOǺ]vv_?ߐ!WJyPO+W_Pplsy !7<2xD (8*^(qDdS[za`uςޞ8#Zg W^=X WrV>vީ kUy뼃jsH"EdYh_ރO|n3K8ϡKԏKBX5gX?{.B *Z0.>?~[ߎӝJyIGJ= PZZ|bΩ &X|j15?hUz [R҄]bvw"m8H} By(|Y^O' R̓4 Y-jDYr%quǧm aIR Bvbqk#Oɣex꒓O ̚7I$܄6?]K}V:sϫ7lAh(xJZ_/1Ɠ7(wPRzB+ IVCҢcoZ80.ڣe]ϸi5XϪD.;q0??羌e)'n:/_TWTA ).XS YS _;뙊 ȳCA|jE7w;ф??<LuZi otk?'{=+~ ,/[I`aEYnc:' 㛂 H|z#XPc8]s 4#MMB!9ZDRܤ@ Cl~XA.9q `Y}|I)u3Ğ]׷bj}?~MˇN˟eQMc] hx1_u-_Q^ ԙDu+$1TLdVZjt(C"RTm [[UH̙O(oSpawݲȤz^.0&]"5f6zY5&^Qs]ӚLG|:|n#=)Yo~1?jm8v8qE5O~)ޱ|X;1kw}g`>,/.7Ǐws<$RW{-f릆wP>?EoV/%Eh~K ˛pU9 >eT b>6F^L ZAF(YIAZ! 71< Ҷ0=bҶ ^|!Ҫ r=_ڐv@%6yuf{@W{5[hpȬlV̫FXPQO,ݐyA*on1t2'C 5f<[[Sr ։L篡nip`aer/m<Ec~ڴ=,RsH@24j MʂM=٩< V𨀃Is_T|74_. 7BP 2I5׺֢B=if=g#^kiQ8 TbX _m D_zㆡёùiڃ?;'5>nb˙*KbCfPSO|7Qg.{# 5Z&6Qt-uGFٴY+mv`8 yR@KDS{ӟe(a+f"{ @58cm;(/N?{=??uD[gfibϟ߻§UU?'Rbho6T[d!wǟ;p|(wZZ\GE*ַ͘L!SX4e9/]!ץ?T_N⃩|ґˆr|>/XϬ'B@I8: 3o_?4r`o*|6sLCۙ>4K~cj|aM `]= SL9Ԁ6hYIxBt:O~|+gr(Dbe-M&OdqqX,? mU2XK6xN"QR3\W%Ji}I {U!#ktYu^gϲJxB?(EV$g}lѡO>j&'_=㏞OގkX:R"j2X}uA 2x0 <ˁ)OS90գƥPA&^O1l"aܗ\NOhtVgX4 \<5ϜW" T5m;9j3i)YT PԨoX1#Ok+UW7]Q]<௒}cu%+a9m;@mpx.]img;~.0yιkm[r~ڢ3b L{Y *d#vZ<~smed<Fk*)p+i`ќ,j~yN?>ѰIR=zw׏3-k)DQtm}Լ*D8~ ! 5k>t.q|" &Oy;4ҋY1}JMKު2w) Mm 3ys0xO1m܂ߗ#f=>uϨx&!L i[="ZO)T3vB(EЧ? qcGx6эڶ V#%?0D?W 4] @` 4#["'wmrn2abagl?t j(x:Ώ6yv_>?,O!v' 4XOE {zGN+M0|#! 7pK&6MC$v'tc4 ]XH3t[rR䶚x r1KؼlAU&+kz 8Mü{U >6W@WyRGo/N_RlR0:ƸnM5rƸ)_GVK]vӈ"yi&y:Pzy]*,MZpel};wq>sPew'wssOn'ċO<:&P+g|x{&=׬XYy#kZRjjF6 ]@T!5T3o:Ku͌8|Q77\˶VI~pfئoJ{'E{S C#Lo? ;8m;l+s!:ugs ozper :Iu6(=nTfOf4;V(/iRw?wi{駧r) j&o?G]9hi.j|I;H3웟x~VֈTukpg"ԹõY/p[|I z4+#K"m+ǂ'r/ ?Uey.ωTP>.\vrLL,*CG ?]EmY޽{! 3L6_ZՌwR -ީ8 6C&To p Uj"R{AhUpy4nU|1Im؇2xVw"Y סE;6M=$d;['c6C+0`>MZɼuԳ D3lmtgvٌϬ[Q>S l6&׍<&R;ʐ攂Cb, ""OO7"O/a@p-ٝAyV(Ҷ0@ ozJxEOH(|dm.'ei uҶᕐQ0cSSxƼn}2c"Ov>ZHo|sX~Hly(cKzBpO,RCA%G&PiQ Ĺ9)@MJ8t,lmPd)7B[O=ѱ=&GoPy^ƶk)\]Lۂ|W ˶9ҾuT3#OQ# CDW4rŚ'ɃgpXRe?ݛLb [Vy̩_ƶmyNLΪYYU8& U[foSMOoًfpw0'l8`v88F 2y*epL\4D2hbVA_MlsO%/bXȏR6c` x,H3.,~lu9 * \[i.*& Ro >ɑ'JAm+0I$!3pC+x Eٶ3Ggs)ayZږyY<,KlBNPy"­NPO&'xWT o_LVS>m9jw- ?< g]v@mɠgf36u @sԐU+L#m5L˅Sq̭ bZLe=ah5K"O5=K+G$5ZH~%,C-Qk1Ƃezq֚{gADvVL ǻJn;d+'ǃ2h%`9 X i*?glV2I\T8D[BE*Bx Ʊ:2# U!6 T" {Md,8<ҶuxTMV OUOyQ^WoIrFC?%M eyhȄh&PCG(cp&Ato*ᦵz hdq`q})i\ Lyzoإbc]yF"B%/.fҶxu]ۤmQRCZU'gq Kc cﬨ:2myUtvaS]XRSH>8EXhH7"D1-ɩN<%dmń! <}mm `A 5O2WZ97w:ɫҫQ$wK5:#@P& oIl|X͓J)a#+Ifyߪmg'Mk3YZ}Q@UsɽQ aH\ˏ]E3fUdҶ%ꬡY72K' |*c(OO5+ʋr(@B/J=5 GodE\0#*\z;7(ו)9C`L,#g]`{Z@Mk6΍z 5vvk3ZFw`7x?jhښirat ݙ5Je+SX dJoόoeY5n4:ۿ3VcQu~$^EP=D dk[y&{`1~+o3B X#o4$pt@{Uҍ+!h Z{N'n]E '|V`z2UT9R˜װ8Yݳd6`UCq# iS%Cϸdi>ՀL4{W{{lSVVU`$unkS[uwsfv .R[c;Qo6\YU>qD;YG^\Z(׊T03 DHf(U4sEE9q-Cf6P#7"FjAgE v4kFDUey9Rnk2A-\49*XD >OC80 #D,UXe8M>ͫe" r`C:AO`Ϋ%je^% ĮPQgIGHCcqVILV4u(Sٔ͘3S?`7ȷ< < b^qrrG6@.50y6ä-%T"xR}#SmR cL,]Hj6Q p|{1J ͥ9YJȓŘ <#)jse<0 12e4l䩋MAiIAqp1s^¨40T SjEgWJ *mH1BRIT`xr&jO͋!s{Sq(] m5ٶD<ˤ0l[S)jE(]CP`DLiBwdێ|At HwN6~.+E :] )-8YASN)Ir*]ddA?mĤZp]3m^'\+ ']J=,m;s^<}5pf*JV&9m[Ly߆y" [$Va2X1|,]BBX /^uU@x彜BmK* 3 5m[V"o(jԪH++85V1ݯQSc)KWoJB{3 Hg'U>ʹ;YtY%_~ ?my*px{Xj"Mzd8@ǒpGM4X힭j,U&%y0缨m;ζ™r:rp(̒o @q'u 0՟fwHۚQ'L aԇ8Vn x$2$L-ROu^g CQjU||;Gت"'YmlMT( WzdҶ|#̽,m籬9 C0*m;<2* US# E^xUC+Sm[V2@kv-%*dZK mk S=> RodYO@Q .(V$)H4QȤE9 <{M;' 67Sd. ƂMTX77 Ɗ 9X& 2}P0LQv"OҹYWt4O:7TpM40Z7K@Tosgsq/O;sփ:yUF4$現^p8aڄ2)wfŗGǤu]Տnޮ降> ej0/ yMemrpaH@3a26h rT>T' ;e/<@jFZKzY@f''St' a;U$O|lj}nIoI*~.'%Ŋ^Ҟ-PnӃrhHD6`Pbb?Me2:'v>B-OMh~x:·p[?m~lfO ^zv I&V!)6cqMI 5Hm& 䒞 I^Ae0c@3S%8$St)술2Tp9X&3ӟr{7}/O>D3BCѤA~O2-$IWgnQeR$-z0*}Y)6fupY"q8Ђp>;&/?v|X ǏF(0n{_> uA%rP.g̻EvmTjڡQҝ#v?Q$`G;QL!#3I[/kô<$D^ObojYE4Elj;'ajZdAHʽEyb35cƅg<}v)xٕu F-[!dBy˿WZ/c,,SC)zJC) ]S2  ԨRs =M^Jkʺ5R+'K$ ureV(ה \=!"[eٲFH%i9r{|Ɨ7!8ϊ oڪ o<Jvxr()˫Ծva_%,M@KFoɀw%C~&ߠYē,}=} < xjW2J[څ<9XU)4P%c‹ɂg '8K@!BlMv_,UO:U(-< UOgj:etL!Ds0xi „PIRajOG9w9<1O8.ȓ Syi[SrT#gsl[ m;BcxΈ|H4hiPӪRQE#a+K۾&/'52K'hr2xvʏ.ጨ_Ԥi[`ZUtqyQQVeۀ'k?rhOS_+mK !IQ*{'ۖ&_Z'EN+;7;7.{:ĵgY,T1>k-r _ Ŵm 7~Or؋v0A`j S\mIif"3}yPi1mEF*p;5U2jr.urVKT`TH󒥻cڭ2%or1UzqQj@^I7]#4 5K.+f(1RGa~fTX?<_FlcC&qK\f_[$ Ѱ5DY+ aU$xbWBp `I"z>l:3Z>=pLa^~>>>m-6]5ZR-vvÉaiӛXCaCҙJ$z!8("Tꇟ&/qvk%A`4yBug*}2Iٔ,s lq0!/v8V?E] n>c~ee87$^ݘ硋3F!shorFZ_QY27FG)D>ܭ$P*Eqbfyk_7)_t"Nx|l6vm6/-;bd!z/ v.(nt# k@K%iŹ Ğ;9t<+e133Sn0=3*(3cx4|@@L aN)b \t֭6a8\^eW z"М\,AU= )`J̳ŨlYؽ\C 8KVr|o}=ՃE3̪B*vj~ect8R7탈x wJeyH@|CgsK'\1zTYSqй@ ,Rx~E0ٜBFߖfdOpO5Ur_"Fz-P1+:r .y>4 ;W%7gw}t4^*Fu6& jyy|8Rx*x{SUKiIWtA| u<:6,;ZD;,0Ʈ"bx xep D\.=ܭ׷nYV7˅m7x"-VS7m,ǎgbzGh](*V+</%\SM<t jpS^P[udڡ߅ ozz- IM-#ͭ4gFmv:Zy84-ϝ|᯿Ӹ}ǀ=w~\`}<%9dj,l1өB$áw(!yʫܡ%!˛.Yv9C { s+XGZ-E5QCo8R/y 2_7#ʱc<'N#O?/ЅqwI^Pj&2;j۪mf(rdK-w5e5> ="j?dCMnkqwtw8;|P>O"F/c.yvT^iqU2?oOp^+'/\6婐6MyZp]aBcq(}{ql|LDfSKL&)sTďE<6Grx3R!D԰;(iw. xV#3@jz2LNvhz.xCxpָàK@߀5[Ͽnn cHN \t֮_w4 ;LEuLr< /j<$-'+Oyg10Xhl^razx̓^zkHq7q4tOrtnŝΝӉSJKxK<`PķŦ<Ę;7GTdҙY~k*]L\"ޞVE (Ptw-U+2q: -OL.B8zG`Lֆ+jn>/UiaV:A_I֔ M +b|CYkڿ - .lK=yte5koߛCn*ۡz>bG:J؉ y}NݪE|bN_Y=#udM1QĒA ^KuaPVۉ )%UjYaiI,v%0F/6O.HIơbR} 9Y4mRy.fCJ\-R-%bYUVt5Do,^1kYN+*)㛁40# (㶮's# Q€|J*u 9Nҭ#G7װyzQ#8:-Z2U N>Eb^@tܡ=TBTUT]Ak4 [.ucWl˭vNLj,ZPY\a^tdkct 7 rμF/NLRm 0ن\9 kކVLlK܂wh4 T,/kQJdIloo-EҶj԰.}{D-U-5QQ(l5 -ƀ)TMAx$ nZ `LB =̦ Ӷ1)+LvUùwZ'-FI%u+c5O 檶=fs Yoꎍbmwd+V2QH?nnV7K'3YY?sk`Bv&'"nCۻw0nitp"ߎ3*O8{r>o}/6X/_j/9^ \ؗ#h7جmf9iHMs.<%i ]!Hi[?"+ j<hn5"`Ҷmy->Dg=02~A95 3)VjO- *3: Ŭ/fb*A,z5O,و݂S`ecL=糅հT5C7\γϣ@x}4.$Y${ycef4:MA(Z]RI'ap|y[dziS "۹.r}rWlgV3Ȩc -ȽҶj@Ys^O>O e+M~2]b SSW7&bi[Syr;ԟq<24C8- U6 ͺĶmrΛ\x9qW`3d#O͛:#tu>ȬY)cȜj32`33u?/힂gǶuqBeDžyYM\_J!)bV-xI35l oB hg! )C&>z-{,Q}ak|ⓛW3 oS0ϳ%2ӞS7V KZ3G{El9+l6 HρVX Py^ <=bhY<x6c ЈmS|i[7̜՚(BPqD)ޔ ß, WK߻L]:Cj/ Kd'b /3l莤Y89LY:!vٚc5´IBij]7;v*xqk]{uA"-6\VWL?.0瓍ك'=m4|< [+Kow;΅`텶f4xz|H20 NP#2uaaN),J$~]<$)qyƔ+hW>x&K ܖG =@Ư/36CU@tBo-г H:xWEW"Od=Z Q&Z1 *v캞h05zHwpf fw N3W8ɕ=k) ސweل?25U<]Oۻ]u7H ߛtD~ڶ.4gc.lxs8yM vݬ۵qĸn[)EN羋-@҂goS+Q#:rCl؄ȋ'(MC%g{l;ujiRnou›J3NIް)2' %QOBgfф :pQ %ޚt\ڶ36r9 :qw*+6_;aUѲS増e݇Ⳍuvc;1cs{ź:#6QIs>O)D!ez1tV.uÀjSk`彫/tPvY3 |r5Wqq?qܡgO<;?䝍\n;;ۗn8xrJ9lhܨPԥ^&m+CaOSWM[N ulB1=ey@' 1ZKxDG ICAVC&EEy0{&E ӶjЎdNwvޮj0OM<\LZ#w@emPFJ=.uxvמY!D6| K5eds` U<ilOI"]~;Ry Le-<r,@E.%@ - -NVc{F Û-iv!&lj@*&V.X~%g-m :I,x ;(A<%gZIԔxy0uxrǁReyTdS!JLںD tqKɘFZrCSa\ڶ3*S)<<`og}-CP| uT)'hEfN]G+][7ȃN<td%c@]2G8~<Y%i[ tVd Yw[<yj'5y:w#xr'2A. _ϛl`nZ1Bǿ摖]mNP&aNOr˗^hXHHM߲ySr=-/^gls({l3;-WA;khvut8E_yy%F)<,Ka窢x< #EG-x'DYmCT׃'UkR),`%a x.@_zg3/"a81oV=LEE_%E%ȓ|>:jg)7>PusIy ݠ_<ĂWC}X/{Mn?ܢ+_|td5 '9o2G3-M.3 #It[&;ş;X ;}gc; Aee&P!K˸.vꚡHٝZ,6*Lw^9c(<K+LxL 滪L4aєj7;'6VTq,WLmZm]8đX[[6 x"3l;wW0fٝ6qIHhce]s`F%9# tk8s I't02 $`޽3ª%@Bf֭XU\PkrՆU/;EHRR.K՘>T):wKD͟eWvl#ЫcWU:omInZο.ʚU.r,2aܹqRM`"Wg9\G1*q#3U:UGp<ϝӢQApicUp]CpĊ(jнOfmτm{h3fu=W]^~doRtA0w~Zt 7 IC統3%e>;EgЃ|oUn=$7&dMcC_|ܩ)* XC59O>ӶSx@^?V%Y'x\v^rGz~a*\gpf'R7v=ޭSc+ϱ2*q;[j2?9IhIa lV#$Cb ̛ʁDb~ n0 u8T{!HeNl.I <},}DŽ5Ɩ=m{I P҂f6*Pn0p͹8(a7/y?yPJZ列e*vejF/w\'1oӫՎM۪. ߘ/5g+Ãx%ҶehdA lk1Xr 9y6&KCJ/Y]a~Ӱ[}Rnz P314ɚS  D@\S.1u!m5PRz'Wϔ10W4`;c4Ir( 4:jDMȴJ9x: GP.9sCC)F5XkcX$ZrH*[\,IFh\t R_,ͅA~Uy[z-_LqP q=8Oyy6oNTuݥK73z" T` g|V6Yx%Q6m YNu1CH'*P@C9m[<|tPb/ FvhCF x6 nnwƞ݆&l\7p{ߋ>9Bwp"myqPy";sg-3s'*4TX"9xքTgN N mIB[I>M!x~3 4qQ.kn3G0& E YD0!b Pz.-a ٠ؚ') 2<)ΰUi\0=ֻo aUFFu<Ή§uo;bVm}J&ԁsYo;QT٥h\Z9Hu*S{bm/*3K1}wj%ErsOǁl.ct.g4 CK:: {PB; zQi 4ٽj:N#uic7jƜI"Ok]ϫtz@f>Yj`S _xdTmC9*;RϞ䂛(!9p aٶPG % 1e,_6闿z2)\M]SB" 1보J IUo:m/m;'ıy%l-#AÁgI]g.X"%u]܃'yhc1ӃK>``]Qx.# [i㭽RPǶ=LHvſ"uL3$b5鋉,RX9{&8=wXD (3~9:W$l`ʡdi#M<ݰYbZ7+egˇey# )T1mR.BI.4.%kՃ_:9V<ۣgvs|YC-e g3{˞p3H3U4d;3k3 AP=Q ΎLIvٮJH^\wNWM=+-۸^ݸ :_{۩Lc67ÖB^>>/'-Zڿ~ )Stx"7(]hY=> Ⱉφr}ܝ0(tJع ,>2B1[v=Ii YzG:F[.gDRo_at|yXOvY 7_;cLۚz8)E^Y4ԭjd^uis&]bO:(2 RKg!pMC:yT)רfHӬ4WOwNm鞎Z~t)xƷoOMCk-9|i$afg9ov9/ t< yc|ʇc~/, :áP5C3L ­*<;ax ۆ ;7b&?O )<ɧ Mmx|[o6/kzn`û.IY)<2F .x>&V~ʥgp~XbRree` Lm٬J YF5i4N%poLD-xlv΀'TSc9<L<Fc* tSЌRc cCJk%XExn+j* [Ld7&'xRZ8*Wlr;es0+ n| ž?҉GTtx&x)'xf$k! f $TU=Lq:m[}d.rU%㼹W1lԁ(  N]? F Wv2-xb{K9i3O\oOQ&SZ!NQ|v xo^r^&'DRSiLo&P-K Dpl6S*iHhY 5<}'"N ފ[)bi<nEPBπ- Hi| !<mAw*- KuGǡĭύ.v^~k Zp ElOwfuϻE'V$'W(ذDmFMQau.ۗ]a qo^fʋf,\i\PzbfdOZ|TT9C$=~i&tU(IHς' N$O#>SY\[(PɳII}x MϠpl[T3d\*j]lo&iXm 76~*1f$&s_y#OSZZP.V3<{PB6;Zi߾,0 %Ύр˒Xm)qǂ\-3Uk۪y>S6]d9{"; #xQa 0ڮq1prݟӿ?;MHt~AM-]%˻LC+s 337 A]*}8LH<pzJj]͛VmcN{mE% ENN ^hyos 4GpE1aqi#ۡM[H=#4d9q˻rm+] MlwDQɽw`czC49ƛ̏{(@]}J <Ը3\ҡ'_o>-H@ӡhD(:G>}zJL&jI+̨pTMOۮTI(ӶcсH_=pʲx{suy8 B ǐzUZU*O<}\<Ӡ@q^R*[L!ec{tl[ϊ嬼"]TM'E^!E5O`bgwF=[<ðAbn^ -Swrq;bm?KB·͉rB:Hj(aBU<P\#M'ϸ:ʐ]ܥ!ŝIw]ݿss%3k ϗE&'J$`@a6S e*VO=`o "x6d+wsy}:z6}}%)aPs t`EyFF*I{+gv0vkU֭YUƶ@ƪ(a|>P7Q҇Lw; JfBD ЈOʜ0<<,'>5 '7ډ]*gصzq8p5όfzT&m#x-&hj" %yV8/4jC='NUe^ϑQ )gߕؤ%=SLOZAהI\ ' D2&~f6 ojXVb=jޞRC;7;t'uZ]OR>>) %ؗa"ABnn׫iOa$qkFB 6rЉ6Vve{Nu d!m"pf0T Γ[4o6Ly`sgnfpY=fPt?+Nl*V+943+|þ4j1:鼄egjA(N6TXoW r V(BߌX@r۵HJVwP9гCm8/U·Q(\0?k|5]S=\^T pixGm?wwly%v< ޒ,XMJx*>1OMޢm/.Ժ;ٌ3 TDTh 2-OX5):x8#4ɁgR"p)rZ[dF / ہKT[x>bc]>1n  7-llC->HeH7B ˰<0vy'Saxpki\ueV>?=-|P,Q1qxxek# wɝ;HT\KO̢Dl:ǀQZ'\ʀ`ԋ3&jvP| Hz}t$؀oUy ]i[k{ p1Ocps-նbFV,\O B9@EB164,m*py 4:*q]h"Z_J8!;Z΍tI^xOI7\ +BX}r稡 arxgdrv>'~'°6=z5fmőz>_F\eD@(ӈn?qP Ry?ZmS g+*hMlRSTטjRX\;6{GTF@O2)L'fw=84m LI`2XM l$Tɮ.wV|ν*wS*xƻ6o_$\8u=SAyQ ʊ)tJ-yVZ7x}8@vʆrI!xCXMyoܗOI 5OS~&<.+@Ff*UQzJi):H!Sz HMBN 0<+JfGD~.dgSݺ,P<*0JGӶSvZZO3-vnOWxqh 9yai&h ˭YFyרr,}c:>)+]4N^4U.3'ʅׁtkG"0*ztWRt9ݏH| ]"rc_>p s eQB4W=r@wR֑Ǣ?n5As %ov ȨQ%$Cc^"|aylhٵ@&'m$goFE5wn JV)sF4oF,pcZB ,ɸygNrkyVE~eUЗ_DK{F!Em+:EC4EX@|=]!MkZ캐խg&g&~B8QnځB4R(Z)B`Ft^tps׆}x g$EΎ[K%25aB|'=H-H@<=rTSdq`5ɂϜBd$ҢsUxLGXd1ucMOρ plBC +D:>$>x7Kr|fz6BYrrSӶy+T yWS=Sv Uf(jepB1JSNlN>t"}pAЪמerk E[;Zm=c"x8s2m9YHW*@ &dIn Y7 ;`(xRdo#BqMҀy#kLO(|xBU6E.VQ5(9<<. CH5}y f5>\(h!"YlLXݚ<.b %R}lbgj~ۓ??:k%3lcе jBm۵нZGOϣ\z%2-ynjS!ûHƃ(D&h7!SEҞߪscph#6AqM QBReIj`䩇g?һ`ݿbv(x4ǭsHVn@fh,y pyE\DG!BP} x<.f*$ L% 13Tx8]ͺDHTX,ﶏO{0\:9ܟZ|Y-) k,eRN$"Ohg#9^ͯ\S,i[,a#6OK}]7ġajHOd`[i[-2$u13s<5Rj+YfvգIҕqgےi[`Ҷȳ)Eo4(m;8<=wpݒˢ̼*NxCt#@E=p;g{1iB t|)#'-85)'xRϔ@< BCi/]IHƵSIScUMPq"qmaaq<3ժ8,hbq} ʺ)LG؅3-H:W&Av-2TCbHx 1]J{*g8D-+!Fm9D"⚢'>g^6 7"B*N(0}xiwȠϋh(0a'y* U͑$)UbSOF͢anٽ Rl3*;؍;ǞPq.t. xt` O^525gULIJX\|ג@?x< "dӶ gr{ZpTtpl a-,pC9mD PjEì[S]ⱓNu]Xm(dF C󮌛?6 _c'Ę99{or?dӶ䧇]59gyjT@wJੲz) uMr24<)@hW _SBO<\;,=bqbm[;/O9w/ks_$7"CL˽;]z;]bQދBgia6Vz-BĒ9J !2\$ExUwY|'o7IMc%o vw>i|,VM^D|Q *ͯM榰dZҺPK*|ʺ, //%snyksn*Wݪ֡9{sL]̙QLDѼ8@#f(. Db ~FdILfJ%ݸ$she >ƒ!J*v%#/}o eC&cOj4(7A%gqN\ySvugnzJqKT-7q#o-|[gL4gvaLG4Ȳ]Bp40$<RYF,"HNMW<͑Q@EF{OV3%.3L]e8(M =xO(l4w'П`K_\!kl'zɨ©.r=pf|X @ڇR.a`Vؽv钻5 9A޻ZRBo/$ߋ~; 9`[/e-H־ʅOaMviՒ%f(F^,Fḏ/6.}yY߭nPЩ r.R%YPGj0N x_j'$ $=PC:I8 $:*׏TcDv{/3 DisRQ &uȅ{[^ըV2{ ‹X"7씳s㡳N9˭\Ą uhMbYp*Ah16cƝs&=϶.kfbKC6]=ܭ׷/oQW-l2& A$EъeZ%0 4r hI? T2 o9Qف^_'ft>׬J=Ҹm"TsL0DX(Oxsl^F^l%QS2Ȅ`܋jp8 "@H_xP314D6R~" B3R !JR Skiv\Wk5OYJzi[>#]R0_Vg[DC›JQpԲdD9fܔ)Қkyඥen'ق@'H9K0)tpQU.hnX& hѸ[^|m"FP7%@':*lmMDQy'q>m~8 ܿfPy+fwy1ʵ&H&qXjӍ»]2xr @q[s'%sEh֤ r<0Ca3us:~=ic +_wg51r<xΖL+98;b"oVNUmHPyT\8fx҃oy2X5/_ZazܰS-,\ Y#k_,@ݘTX"&dlsIrOG22gj[(]1b؂ (+x>nG' Xtx$Ab7ݤG,%s4VHbbvW8;@~z%[ݎ;@czx>~*Ԥ\ʦGZET\yC0+eQ9*#Sѫ-8YDG#S{=<ծ'>s/ﳣ8j /dSxꖎ\,?kY UO4'Z[+b.(]%F̏CSOng= ԕ= ͫWMYv-1XðM[/ۃmC NAUʧ 4] R4:VZwp]Ztj" >jk&ެÁ:&0j/Ɠ: =Υ-~f3:< 2[mw) *."1>]SlT D9L,* ^N !7˝݂@HU/$%kF'tA:r'ӿgg|4x. nһEӅvn$Ĺ+{#i^_j"Ҹ}iLN9{%F+ۉk`Q uǫ,!LhDq3dko Onަ8wv݅$Wy;"ɤzA[\312Rc<i(JotHO(O վ?t lA6XdwY[+\~kWܴ v-QLmGW 'a{k7FΟ,tUbIDATaod+OadR;(0Xy1wE-x9Z/nVt HntjNc4ɓXYYxḶ*O;r[t=c}agV/MhߥׂC`BTG&lmޕ۲+@0d$'? "_V R}'Sb.hdd?/<1qh؉=hӡ:NYb65}H)Q9 2XY0m{#B٢x"~neֿeOa2߀-\䂖%NZ[w5C̟0sZ^<9 ˧irC 3CK]BD;CLOb`l퀅+OO=J6[~gLRDrZ=|n.N[7ڜ@bt*3euuӶEa7}X Ǡ .mڹ6(|T_'ŕg & Ystǹg| 7BK2V7O&7_LK$C{9:Q>u B %Ԡ^O{1qx5#Cv#* wlD@OXj硶(gWMKV#*%~y0Gbe 1JZxѫ)hxU3f9dZ]t= GR#2xfӕҼ9zZA;VQuJ"pL, :h XQ-q N)0rzVEI֨04a:ƦZ%#8€-o9^~x(腆PRk W>Qb=<O ܳ3J3xfk{9i t_-sSyy7x? X%Ml8^lpv[wysО U֚PZDלw}9iT4xWVS{' ~ɯ'XOqRmIݮ<9Ov@=*޵#bb&,'2Ѐ?q딇2{g+^gGltr}bG-iM1r_gm1h[ui-{bD -ps x^UYg*xJ!TGj]~اYUXSb7sZ''WsUϽ "x`h;ڥm7@_歞'A=-xQP.œ'*\ )lu C)&)m6yI 3՞guRp OK:50s'I?g7b*m]n0C^RJ۞)›kkg-\m>7Q$sWΡTkǁh[@{ עT"xKAoǡpS)!W5@iwِ ݺZ)'!D<9z7ng0&[P)-xzi}u|9=&x!9+x\m{kZV;8~.` j_i=>FȜs93k W:stɋ'x+[ؓ KIENDB`\ Copyright (c) 1999 Daniel C. Sobral \ Copyright (c) 2011-2015 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. \ \ $FreeBSD$ only forth definitions include /boot/forth/support.4th include /boot/forth/color.4th include /boot/forth/delay.4th include /boot/forth/check-password.4th efi? [if] include /boot/forth/efi.4th [then] only forth definitions : bootmsg ( -- ) loader_color? dup ( -- bool bool ) if 7 fg 4 bg then ." Booting..." if me then cr ; : try-menu-unset \ menu-unset may not be present s" beastie_disable" getenv dup -1 <> if s" YES" compare-insensitive 0= if exit then else drop then s" menu-unset" sfind if execute else drop then s" menusets-unset" sfind if execute else drop then ; only forth also support-functions also builtins definitions \ the boot-args was parsed to individual options while loaded \ now compose boot-args, so the boot can set kernel arguments \ note the command line switched for boot command will cause \ environment variable boot-args to be ignored \ There are 2 larger strings, acpi-user-options and existing boot-args \ other switches are 1 byte each, so allocate boot-args+acpi + extra bytes \ for rest. Be sure to review this, if more options are to be added into \ environment. : set-boot-args { | addr len baddr blen aaddr alen -- } s" boot-args" getenv dup -1 <> if to blen to baddr else drop then s" acpi-user-options" getenv dup -1 <> if to alen to aaddr else drop then \ allocate temporary space. max is: \ 8 kernel switches \ 26 for acpi, so use 40 for safety blen alen 40 + + allocate abort" out of memory" to addr \ boot-addr may have file name before options, copy it to addr baddr 0<> if baddr c@ [char] - <> if baddr blen [char] - strchr ( addr len ) dup 0= if \ no options, copy all 2drop baddr addr blen move blen to len 0 to blen 0 to baddr else ( addr len ) dup blen swap - to len ( addr len ) to blen ( addr ) baddr addr len move ( addr ) to baddr \ baddr points now to first option then then then \ now add kernel switches len 0<> if bl addr len + c! len 1+ to len then [char] - addr len + c! len 1+ to len s" boot_single" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] s addr len + c! len 1+ to len then else drop then s" boot_verbose" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] v addr len + c! len 1+ to len then else drop then s" boot_kmdb" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] k addr len + c! len 1+ to len then else drop then s" boot_drop_into_kmdb" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] d addr len + c! len 1+ to len then else drop then s" boot_reconfigure" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] r addr len + c! len 1+ to len then else drop then s" boot_ask" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] a addr len + c! len 1+ to len then else drop then s" boot_noncluster" getenv dup -1 <> if s" YES" compare-insensitive 0= if [char] x addr len + c! len 1+ to len then else drop then \ now add remining boot args if blen != 0. \ baddr[0] is '-', if baddr[1] != 'B' append to addr, \ otherwise add space then copy blen 0<> if baddr 1+ c@ [char] B = if addr len + 1- c@ [char] - = if \ if addr[len -1] == '-' baddr 1+ to baddr blen 1- to blen else bl addr len + c! len 1+ to len then else baddr 1+ to baddr blen 1- to blen then baddr addr len + blen move len blen + to len 0 to baddr 0 to blen then \ last part - add acpi. alen 0<> if addr len + 1- c@ [char] - <> if bl addr len + c! len 1+ to len [char] - addr len + c! len 1+ to len then s" B acpi-user-options=" dup -rot ( len addr len ) addr len + swap move ( len ) len + to len aaddr addr len + alen move len alen + to len then \ check for left over '-' addr len 1- + c@ [char] - = if len 1- to len \ but now we may also have left over ' ' len if ( len <> 0 ) addr len 1- + c@ bl = if len 1- to len then then then \ if len != 0, set boot-args len 0<> if addr len s" boot-args" setenv then addr free drop ; : boot 0= if ( interpreted ) get_arguments then set-boot-args \ Unload only if a path was passed. Paths start with / dup if >r over r> swap c@ [char] / = if 0 1 unload drop else s" kernelname" getenv? if ( a kernel has been loaded ) try-menu-unset bootmsg 1 boot exit then load_kernel_and_modules ?dup if exit then try-menu-unset bootmsg 0 1 boot exit then else s" kernelname" getenv? if ( a kernel has been loaded ) try-menu-unset bootmsg 1 boot exit then load_kernel_and_modules ?dup if exit then try-menu-unset bootmsg 0 1 boot exit then load_kernel_and_modules ?dup 0= if bootmsg 0 1 boot then ; \ ***** boot-conf \ \ Prepares to boot as specified by loaded configuration files. : boot-conf 0= if ( interpreted ) get_arguments then 0 1 unload drop load_kernel_and_modules ?dup 0= if 0 1 autoboot then ; also forth definitions previous builtin: boot builtin: boot-conf only forth definitions also support-functions \ \ in case the boot-args is set, parse it and extract following options: \ -a to boot_ask=YES \ -s to boot_single=YES \ -v to boot_verbose=YES \ -k to boot_kmdb=YES \ -d to boot_drop_into_kmdb=YES \ -r to boot_reconfigure=YES \ -x to boot_noncluster=YES \ -B acpi-user-options=X to acpi-user-options=X \ \ This is needed so that the menu can manage these options. Unfortunately, this \ also means that boot-args will override previously set options, but we have no \ way to control the processing order here. boot-args will be rebuilt at boot. \ \ NOTE: The best way to address the order is to *not* set any above options \ in boot-args. : parse-boot-args { | baddr blen -- } s" boot-args" getenv dup -1 = if drop exit then to blen to baddr baddr blen \ loop over all instances of switch blocks, starting with '-' begin [char] - strchr 2dup to blen to baddr dup 0<> while ( addr len ) \ points to - \ block for switch B. keep it on top of the stack for case \ the property list will get empty. over 1+ c@ [char] B = if 2dup \ save "-B ...." in case options is empty 2 - swap 2 + ( addr len len-2 addr+2 ) \ skip -B begin \ skip spaces dup c@ bl = while 1+ swap 1- swap repeat ( addr len len' addr' ) \ its 3 cases now: end of string, -switch, or option list over 0= if \ end of string, remove trailing -B 2drop ( addr len ) swap 0 swap c! \ store 0 at -B blen swap ( blen len ) - ( rem ) baddr swap ( addr rem ) dup 0= if s" boot-args" unsetenv 2drop exit then \ trailing space(s) begin over ( addr rem addr ) over + 1- ( addr rem addr+rem-1 ) c@ bl = while 1- swap ( rem-1 addr ) over ( rem-1 addr rem-1 ) over + ( rem-1 addr addr+rem-1 ) 0 swap c! swap repeat s" boot-args" setenv recurse \ restart exit then ( addr len len' addr' ) dup c@ [char] - = if \ it is switch. set to boot-args swap s" boot-args" setenv 2drop recurse \ restart exit then ( addr len len' addr' ) \ its options string "option1,option2,... -..." \ cut acpi-user-options=xxx and restart the parser \ or skip to next option block begin dup c@ dup 0<> swap bl <> and \ stop if space or 0 while dup 18 s" acpi-user-options=" compare 0= if \ matched ( addr len len' addr' ) \ addr' points to acpi options, find its end [',' or ' ' or 0 ] \ set it as acpi-user-options and move remaining to addr' 2dup ( addr len len' addr' len' addr' ) \ skip to next option in list \ loop to first , or bl or 0 begin dup c@ [char] , <> >r dup c@ bl <> >r dup c@ 0<> r> r> and and while 1+ swap 1- swap repeat ( addr len len' addr' len" addr" ) >r >r ( addr len len' addr' R: addr" len" ) over r@ - ( addr len len' addr' proplen R: addr" len" ) dup 5 + ( addr len len' addr' proplen proplen+5 ) allocate abort" out of memory" 0 s" set " strcat ( addr len len' addr' proplen caddr clen ) >r >r 2dup r> r> 2swap strcat ( addr len len' addr' proplen caddr clen ) 2dup + 0 swap c! \ terminate with 0 2dup evaluate drop free drop ( addr len len' addr' proplen R: addr" len" ) \ acpi-user-options is set, now move remaining string to its place. \ addr: -B, addr': acpi... addr": reminder swap ( addr len len' proplen addr' ) r> r> ( addr len len' proplen addr' len" addr" ) dup c@ [char] , = if \ skip , and move addr" to addr' 1+ swap 1- ( addr len len' proplen addr' addr" len" ) rot swap 1+ move ( addr len len' proplen ) else \ its bl or 0 ( addr len len' proplen addr' len" addr" ) \ for both bl and 0 we need to copy to addr'-1 to remove \ comma, then reset boot-args, and recurse will clear -B \ if there are no properties left. dup c@ 0= if 2drop ( addr len len' proplen addr' ) 1- 0 swap c! ( addr len len' proplen ) else >r >r ( addr len len' proplen addr' R: addr" len" ) 1- swap 1+ swap r> r> ( addr len len' proplen addr' len" addr" ) rot rot move ( addr len len' proplen ) then then 2swap 2drop ( len' proplen ) nip ( proplen ) baddr blen rot - s" boot-args" setenv recurse exit else ( addr len len' addr' ) \ not acpi option, skip to next option in list \ loop to first , or bl or 0 begin dup c@ [char] , <> >r dup c@ bl <> >r dup c@ 0<> r> r> and and while 1+ swap 1- swap repeat \ if its ',', skip over dup c@ [char] , = if 1+ swap 1- swap then then repeat ( addr len len' addr' ) \ this block is done, remove addr and len from stack 2swap 2drop swap then over c@ [char] - = if ( addr len ) 2dup 1- swap 1+ ( addr len len' addr' ) begin \ loop till ' ' or 0 dup c@ dup 0<> swap bl <> and while dup c@ [char] s = if s" set boot_single=YES" evaluate TRUE else dup c@ [char] v = if s" set boot_verbose=YES" evaluate TRUE else dup c@ [char] k = if s" set boot_kmdb=YES" evaluate TRUE else dup c@ [char] d = if s" set boot_drop_into_kmdb=YES" evaluate TRUE else dup c@ [char] r = if s" set boot_reconfigure=YES" evaluate TRUE else dup c@ [char] a = if s" set boot_ask=YES" evaluate TRUE else dup c@ [char] x = if s" set boot_noncluster=YES" evaluate TRUE then then then then then then then dup TRUE = if drop dup >r ( addr len len' addr' R: addr' ) 1+ swap 1- ( addr len addr'+1 len'-1 R: addr' ) r> swap move ( addr len ) 2drop baddr blen 1- \ check if we have space after '-', if so, drop '- ' swap dup 1+ c@ bl = if 2 + swap 2 - else swap then dup dup 0= swap 1 = or if \ empty or only '-' is left. 2drop s" boot-args" unsetenv exit else s" boot-args" setenv then recurse exit then 1+ swap 1- swap repeat 2swap 2drop dup c@ 0= if \ end of string 2drop exit else swap then then repeat 2drop ; \ ***** start \ \ Initializes support.4th global variables, sets loader_conf_files, \ processes conf files, and, if any one such file was successfully \ read to the end, loads kernel and modules. : start ( -- ) ( throws: abort & user-defined ) s" /boot/defaults/loader.conf" initialize include_bootenv include_conf_files include_transient \ If the user defined a post-initialize hook, call it now s" post-initialize" sfind if execute else drop then parse-boot-args \ Will *NOT* try to load kernel and modules if no configuration file \ was successfully loaded! any_conf_read? if s" loader_delay" getenv -1 = if load_xen_throw load_kernel load_modules else drop ." Loading Kernel and Modules (Ctrl-C to Abort)" cr s" also support-functions" evaluate s" set delay_command='load_xen_throw load_kernel load_modules'" evaluate s" set delay_showdots" evaluate delay_execute then then ; \ ***** initialize \ \ Overrides support.4th initialization word with one that does \ everything start one does, short of loading the kernel and \ modules. Returns a flag. : initialize ( -- flag ) s" /boot/defaults/loader.conf" initialize include_bootenv include_conf_files include_transient \ If the user defined a post-initialize hook, call it now s" post-initialize" sfind if execute else drop then parse-boot-args any_conf_read? ; \ ***** read-conf \ \ Read a configuration file, whose name was specified on the command \ line, if interpreted, or given on the stack, if compiled in. : (read-conf) ( addr len -- ) conf_files string= include_conf_files \ Will recurse on new loader_conf_files definitions ; : read-conf ( | addr len -- ) ( throws: abort & user-defined ) state @ if \ Compiling postpone (read-conf) else \ Interpreting bl parse (read-conf) then ; immediate \ show, enable, disable, toggle module loading. They all take module from \ the next word : set-module-flag ( module_addr val -- ) \ set and print flag over module.flag ! dup module.name strtype module.flag @ if ." will be loaded" else ." will not be loaded" then cr ; : enable-module find-module ?dup if true set-module-flag then ; : disable-module find-module ?dup if false set-module-flag then ; : toggle-module find-module ?dup if dup module.flag @ 0= set-module-flag then ; \ ***** show-module \ \ Show loading information about a module. : show-module ( -- ) find-module ?dup if show-one-module then ; : set-module-path ( addr len -- ) find-module ?dup if module.loadname string= then ; \ Words to be used inside configuration files : retry false ; \ For use in load error commands : ignore true ; \ For use in load error commands \ Return to strict forth vocabulary : #type over - >r type r> spaces ; : .? 2 spaces 2swap 15 #type 2 spaces type cr ; : ? ['] ? execute s" boot-conf" s" load kernel and modules, then autoboot" .? s" read-conf" s" read a configuration file" .? s" enable-module" s" enable loading of a module" .? s" disable-module" s" disable loading of a module" .? s" toggle-module" s" toggle loading of a module" .? s" show-module" s" show module load data" .? s" try-include" s" try to load/interpret files" .? s" beadm" s" list or activate Boot Environments" .? ; : try-include ( -- ) \ see loader.4th(8) ['] include ( -- xt ) \ get the execution token of `include' catch ( xt -- exception# | 0 ) if \ failed LF parse ( c -- s-addr/u ) 2drop \ advance >in to EOL (drop data) \ ... prevents words unused by `include' from being interpreted then ; immediate \ interpret immediately for access to `source' (aka tib) include /boot/forth/beadm.4th only forth definitions # This is loader.conf - a file full of useful variables that you can # set to change the default load behavior of your system. You should # not edit this file! Put any overrides into one of the # loader_conf_files instead and you will be able to update these # defaults later without spamming your local configuration information. # # All arguments must be in double quotes. # ############################################################## ### Basic configuration options ############################ ############################################################## exec=".( Loading /boot/defaults/loader.conf ) cr" bootfile="/kernel/unix" # Kernel binary (absolute path) # boot-args="" # Flags to be passed to the kernel # default list of explicit config files. # the load order for config files is: # /boot/defaults/loader.conf, files listed in loader_conf_files, # config snippets in /boot/conf.d in lexicographical order # last is /boot/transient.conf # note the transient.conf is for automatic temporary options # managed by bootadm # /boot/conf.d is managed by bootadm and preferred directory for # custom options. loader_conf_files="/boot/loader.conf /boot/loader.conf.local" verbose_loading="NO" # Set to YES for verbose loader output ############################################################## ### Splash screen configuration ############################ ############################################################## # splash_bmp_load="NO" # Set this to YES for bmp splash screen! # splash_pcx_load="NO" # Set this to YES for pcx splash screen! # splash_txt_load="NO" # Set this to YES for TheDraw splash screen! # vesa_load="NO" # Set this to YES to load the vesa module # bitmap_load="NO" # Set this to YES if you want splash screen! # bitmap_name="splash.bmp" # Set this to the name of the file # bitmap_type="splash_image_data" # and place it on the module_path ############################################################## ### Loader settings ######################################## ############################################################## #loader_delay="3" # Delay in seconds before loading anything. # Default is unset and disabled (no delay). autoboot_delay="10" # Delay in seconds before autobooting, # set to -1 if you don't want user to be # allowed to interrupt autoboot process and # escape to the loader prompt, set to # "NO" to disable autobooting beastie_disable="NO" # Turn the beastie boot menu on and off loader_logo="none" # No small logo (Hammerhead uses brand PNG only) loader_brand="hammerhead" # Hammerhead/Zygaena brand console="text,ttya,ttyb,ttyc,ttyd" # A comma separated list of console(s) #currdev="disk1s1a" # Set the current device module_path="/kernel/" # Set the module search path #prompt="\\${interpret}" # Set the command prompt #root_disk_unit="0" # Force the root disk unit number #rootdev="disk1s1a" # Set the root filesystem #tftp.blksize="1428" # Set the RFC 2348 TFTP block size. # If the TFTP server does not support RFC 2348, # the block size is set to 512. If the value # is out of range ( < 8 || > 9008 ) an error is # returned. #twiddle_divisor="16" # >16 slows down the progress indicator; # <16 speeds up the progress indicator. ############################################################## ### boot archive ########################################### ############################################################## boot_archive_load="YES" # illumos will not boot without rootfs boot_archive_type="rootfs" boot_archive_name="/boot/boot_archive" boot_archive.hash_load="YES" boot_archive.hash_type="hash" boot_archive.hash_name="/boot/boot_archive.hash" ############################################################## ### Module loading syntax example ########################## ############################################################## #module_load="YES" # loads module "module" #module_name="realname" # uses "realname" instead of "module" #module_type="type" # passes "-t type" to load #module_flags="flags" # passes "flags" to the module #module_before="cmd" # executes "cmd" before loading the module #module_after="cmd" # executes "cmd" after loading the module #module_error="cmd" # executes "cmd" if load fails \ Loader.rc \ \ Includes additional commands include /boot/forth/loader.4th try-include /boot/loader.rc.local \ Reads and processes loader.conf variables \ NOTE: Change to `start' if you disable the below boot menu \ also note that initialize will leave flag in stack from any_conf_read? \ start initialize drop \ Tests for password -- executes autoboot first if a password was defined check-password \ Load in the boot menu include /boot/forth/beastie.4th \ Start the boot menu beastie-start \ Copyright (c) 2006-2015 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. \ \ Copyright 2015 Toomas Soome \ Copyright 2019 Joyent, Inc. \ Copyright 2020 OmniOS Community Edition (OmniOSce) Association. marker task-menu-commands.4th include /boot/forth/menusets.4th only forth definitions variable osconsole_state variable acpi_state variable kmdb_state 0 osconsole_state ! 0 acpi_state ! 0 kmdb_state ! also menu-namespace also menu-command-helpers \ \ Boot \ : init_boot ( N -- N ) dup s" smartos" getenv? if s" set menu_keycode[N]=98" \ base command to execute else s" boot_single" getenv -1 <> if drop ( n n c-addr -- n n ) \ unused toggle_menuitem ( n n -- n n ) s" set menu_keycode[N]=115" \ base command to execute else s" set menu_keycode[N]=98" \ base command to execute then then 17 +c! \ replace 'N' with ASCII numeral evaluate ; \ \ Alternate Boot \ : init_altboot ( N -- N ) dup s" smartos" getenv? if s" set menu_keycode[N]=114" \ base command to execute else s" boot_single" getenv -1 <> if drop ( n c-addr -- n ) \ unused toggle_menuitem ( n -- n ) s" set menu_keycode[N]=109" \ base command to execute else s" set menu_keycode[N]=115" \ base command to execute then then 17 +c! \ replace 'N' with ASCII numeral evaluate ; : altboot ( N -- NOTREACHED ) s" smartos" getenv? if s" alt-boot-args" getenv dup -1 <> if s" boot-args" setenv ( c-addr/u -- ) then ." NoInstall/Recovery mode boot. login/pw: root/root" cr else s" boot_single" 2dup getenv -1 <> if drop ( c-addr/u c-addr -- c-addr/u ) \ unused unsetenv ( c-addr/u -- ) else 2drop ( c-addr/u -- ) \ unused s" set boot_single=YES" evaluate then then 0 boot ( state -- ) ; \ \ Single User Mode \ : singleuser_enabled? ( -- flag ) s" boot_single" getenv -1 <> dup if swap drop ( c-addr flag -- flag ) then ; : singleuser_enable ( -- ) s" set boot_single=YES" evaluate ; : singleuser_disable ( -- ) s" boot_single" unsetenv ; : init_singleuser ( N -- N ) singleuser_enabled? if toggle_menuitem ( n -- n ) then ; : toggle_singleuser ( N -- N TRUE ) toggle_menuitem menu-redraw \ Now we're going to make the change effective dup toggle_stateN @ 0= if singleuser_disable else singleuser_enable then TRUE \ loop menu again ; \ \ Verbose Boot \ : verbose_enabled? ( -- flag ) s" boot_verbose" getenv -1 <> dup if swap drop ( c-addr flag -- flag ) then ; : verbose_enable ( -- ) s" set boot_verbose=YES" evaluate ; : verbose_disable ( -- ) s" boot_verbose" unsetenv ; : init_verbose ( N -- N ) verbose_enabled? if toggle_menuitem ( n -- n ) then ; : toggle_verbose ( N -- N TRUE ) toggle_menuitem menu-redraw \ Now we're going to make the change effective dup toggle_stateN @ 0= if verbose_disable else verbose_enable then TRUE \ loop menu again ; \ \ Reconfiguration boot \ : reconfigure_enabled? ( -- flag ) s" boot_reconfigure" getenv -1 <> dup if swap drop ( c-addr flag -- flag ) then ; : reconfigure_enable ( -- ) s" set boot_reconfigure=YES" evaluate ; : reconfigure_disable ( -- ) s" boot_reconfigure" unsetenv ; : init_reconfigure ( N -- N ) reconfigure_enabled? if toggle_menuitem ( n -- n ) then ; : toggle_reconfigure ( N -- N TRUE ) toggle_menuitem menu-redraw \ Now we're going to make the change effective dup toggle_stateN @ 0= if reconfigure_disable else reconfigure_enable then TRUE \ loop menu again ; \ \ Framebuffer \ : init_framebuffer ( N -- N ) framebuffer? if toggle_menuitem ( n -- n ) then ; : toggle_framebuffer ( N -- N TRUE ) toggle_menuitem dup toggle_stateN @ 0= if s" off" else s" on" then 1 framebuffer draw-beastie draw-brand menu-init \ needed to reset menu position menu-redraw TRUE \ loop menu again ; \ \ Escape to Prompt \ : goto_prompt ( N -- N FALSE ) s" set autoboot_delay=NO" evaluate cr ." To get back to the menu, type `menu' and press ENTER" cr ." or type `boot' and press ENTER to start illumos." cr cr FALSE \ exit the menu ; \ \ Cyclestate (used by osconsole/acpi/kmdb below) \ : init_cyclestate ( N K -- N ) over cycle_stateN ( n k -- n k addr ) begin tuck @ ( n k addr -- n addr k c ) over <> ( n addr k c -- n addr k 0|-1 ) while rot ( n addr k -- addr k n ) cycle_menuitem swap rot ( addr k n -- n k addr ) repeat 2drop ( n k addr -- n ) ; \ \ OS Console \ getenv os_console, if not set getenv console, if not set, default to "text" \ allowed serial consoles: ttya .. ttyd \ if new console will be added (graphics?), this section needs to be updated \ : init_osconsole ( N -- N ) s" os_console" getenv dup -1 = if drop s" console" getenv dup -1 = if drop 0 \ default to text then then ( n c-addr/u | n 0 ) dup 0<> if ( n c-addr/u ) \ because all usable console names have 4 chars, \ we can only compare first 4 chars. drop 4 2dup s" ttyd" compare 0= if 2drop 4 else 2dup s" ttyc" compare 0= if 2drop 3 else 2dup s" ttyb" compare 0= if 2drop 2 else 2dup s" ttya" compare 0= if 2drop 1 else 2drop 0 \ anything else defaults to text then then then then then osconsole_state ! ; : activate_osconsole ( N -- N ) dup cycle_stateN @ ( n -- n n2 ) dup osconsole_state ! ( n n2 -- n n2 ) \ copy for re-initialization case 0 of s" text" endof 1 of s" ttya" endof 2 of s" ttyb" endof 3 of s" ttyc" endof 4 of s" ttyd" endof dup s" unknown state: " type . cr endcase s" os_console" setenv ; : cycle_osconsole ( N -- N TRUE ) cycle_menuitem \ cycle cycle_stateN to next value activate_osconsole \ apply current cycle_stateN menu-redraw \ redraw menu TRUE \ loop menu again ; \ \ ACPI \ : init_acpi ( N -- N ) s" acpi-user-options" getenv dup -1 <> if evaluate \ use ?number parse step \ translate option to cycle state case 1 of 1 acpi_state ! endof 2 of 2 acpi_state ! endof 4 of 3 acpi_state ! endof 8 of 4 acpi_state ! endof 0 acpi_state ! endcase else drop then ; : activate_acpi ( N -- N ) dup cycle_stateN @ ( n -- n n2 ) dup acpi_state ! ( n n2 -- n n2 ) \ copy for re-initialization \ if N == 0, it's default, just unset env. dup 0= if drop s" acpi-user-options" unsetenv else case 1 of s" 1" endof 2 of s" 2" endof 3 of s" 4" endof 4 of s" 8" endof endcase s" acpi-user-options" setenv then ; : cycle_acpi ( N -- N TRUE ) cycle_menuitem \ cycle cycle_stateN to next value activate_acpi \ apply current cycle_stateN menu-redraw \ redraw menu TRUE \ loop menu again ; \ \ kmdb \ : kmdb_disable s" boot_kmdb" unsetenv s" boot_drop_into_kmdb" unsetenv ; : init_kmdb ( N -- N ) \ Retrieve the contents of "nmi" or default to "panic" ( N -- N c-addr/u ) s" nmi" getenv dup -1 <> if else drop s" panic" then \ Store the string in "nmi_initial" if not already set \ (to support re-entering the menu from the loader prompt) s" nmi_initial" getenv? if else 2dup s" nmi_initial" setenv then ( N caddr/u -- N flag ) s" kmdb" compare if false else true then s" boot_kmdb" getenv -1 <> if drop s" boot_drop_into_kmdb" getenv -1 <> if drop if 4 else 3 then else if 2 else 1 then then else drop \ drop flag 0 then kmdb_state ! ; : activate_kmdb ( N -- N ) dup cycle_stateN @ ( n -- n n2 ) dup kmdb_state ! ( n n2 -- n n2 ) \ Reset "nmi" to its initial value s" nmi_initial" getenv s" nmi" setenv case 4 of \ drop + nmi=kmdb s" set boot_kmdb=YES" evaluate s" set boot_drop_into_kmdb=YES" evaluate s" set nmi=kmdb" evaluate endof 3 of \ drop s" set boot_kmdb=YES" evaluate s" set boot_drop_into_kmdb=YES" evaluate endof 2 of \ load + nmi=kmdb s" set boot_kmdb=YES" evaluate s" boot_drop_into_kmdb" unsetenv s" set nmi=kmdb" evaluate endof 1 of \ load s" set boot_kmdb=YES" evaluate s" boot_drop_into_kmdb" unsetenv endof kmdb_disable endcase ; : cycle_kmdb ( N -- N TRUE ) cycle_menuitem \ cycle cycle_stateN to next value activate_kmdb \ apply current cycle_stateN menu-redraw \ redraw menu TRUE \ loop menu again ; \ \ Menusets \ : goto_menu ( N M -- N TRUE ) menu-unset menuset-loadsetnum ( n m -- n ) menu-redraw TRUE \ Loop menu again ; \ \ Defaults \ : unset_boot_options 0 acpi_state ! s" acpi-user-options" unsetenv s" boot-args" unsetenv s" boot_ask" unsetenv singleuser_disable verbose_disable kmdb_disable \ disables drop_into_kmdb as well reconfigure_disable ; : set_default_boot_options ( N -- N TRUE ) unset_boot_options 2 goto_menu ; \ \ Set boot environment defaults \ : init_bootenv ( -- ) s" set menu_caption[1]=${bemenu_current}${zfs_be_active}" evaluate s" set ansi_caption[1]=${beansi_current}${zfs_be_active}" evaluate s" set menu_caption[2]=${bemenu_bootfs}${currdev}" evaluate s" set ansi_caption[2]=${beansi_bootfs}${currdev}" evaluate s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate ; \ \ Redraw the entire screen. A long BE name can corrupt the menu \ : be_draw_screen clear \ Clear the screen (in screen.4th) print_version \ print version string (bottom-right; see version.4th) draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) draw-brand \ Draw brand.4th logo at top (in brand.4th) menu-init \ Initialize menu and draw bounding box (in menu.4th) ; \ \ Select a boot environment \ : set_bootenv ( N -- N TRUE ) dup s" bootenv_root[E]" 13 +c! getenv s" currdev" getenv compare 0= if s" zfs_be_active" getenv type ." is already active" else dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate dup s" bootenvmenu_caption[E]" 20 +c! getenv s" zfs_be_active" setenv ." Activating " s" currdev" getenv type cr s" unload" evaluate free-module-options unset_boot_options s" /boot/defaults/loader.conf" read-conf s" /boot/loader.conf" read-conf s" /boot/loader.conf.local" read-conf init_bootenv s" 1" s" zfs_be_currpage" setenv s" be-set-page" evaluate then 500 ms \ sleep so user can see the message be_draw_screen menu-redraw TRUE ; \ \ Chainload this entry. Normally we do not return, in case of error \ from chain load, we continue with normal menu code. \ : set_be_chain ( N -- no return | N TRUE ) dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop menu-redraw TRUE ; \ \ Switch to the next page of boot environments \ : set_be_page ( N -- N TRUE ) s" zfs_be_currpage" getenv dup -1 = if drop s" 1" else s2n 1+ \ increment the page number dup s" zfs_be_pages" getenv s2n > if drop 1 then n2s then s" zfs_be_currpage" setenv s" be-set-page" evaluate 3 goto_menu ; only forth definitions \ Copyright (c) 2003 Scott Long \ Copyright (c) 2003 Aleksander Fafula \ Copyright (c) 2006-2015 Devin Teske \ Copyright 2020 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. marker task-menu.4th \ Frame drawing include /boot/forth/frames.4th vocabulary menu-infrastructure vocabulary menu-namespace vocabulary menu-command-helpers only forth also menu-infrastructure definitions f_double \ Set frames to double (see frames.4th). Replace with \ f_single if you want single frames. 46 constant dot \ ASCII definition of a period (in decimal) 5 constant menu_default_x \ default column position of timeout 10 constant menu_default_y \ default row position of timeout msg 4 constant menu_timeout_default_x \ default column position of timeout 23 constant menu_timeout_default_y \ default row position of timeout msg 10 constant menu_timeout_default \ default timeout (in seconds) \ Customize the following values with care 1 constant menu_start \ Numerical prefix of first menu item dot constant bullet \ Menu bullet (appears after numerical prefix) 5 constant menu_x \ Row position of the menu (from the top) 10 constant menu_y \ Column position of the menu (from left side) \ Menu Appearance variable menuidx \ Menu item stack for number prefixes variable menurow \ Menu item stack for positioning variable menubllt \ Menu item bullet \ Menu Positioning variable menuX \ Menu X offset (columns) variable menuY \ Menu Y offset (rows) \ Menu-item elements variable menurebootadded \ Menu timer [count-down] variables variable menu_timeout_enabled \ timeout state (internal use only) variable menu_time \ variable for tracking the passage of time variable menu_timeout \ determined configurable delay duration variable menu_timeout_x \ column position of timeout message variable menu_timeout_y \ row position of timeout message only forth also menu-namespace definitions \ Menu-item key association/detection variable menukey1 variable menukey2 variable menukey3 variable menukey4 variable menukey5 variable menukey6 variable menukey7 variable menukey8 variable menureboot variable menuacpi variable menuosconsole variable menukmdb variable menuoptions \ Menu initialization status variables variable init_state1 variable init_state2 variable init_state3 variable init_state4 variable init_state5 variable init_state6 variable init_state7 variable init_state8 \ Boolean option status variables variable toggle_state1 variable toggle_state2 variable toggle_state3 variable toggle_state4 variable toggle_state5 variable toggle_state6 variable toggle_state7 variable toggle_state8 \ Array option status variables variable cycle_state1 variable cycle_state2 variable cycle_state3 variable cycle_state4 variable cycle_state5 variable cycle_state6 variable cycle_state7 variable cycle_state8 \ Containers for storing the initial caption text create init_text1 64 allot create init_text2 64 allot create init_text3 64 allot create init_text4 64 allot create init_text5 64 allot create init_text6 64 allot create init_text7 64 allot create init_text8 64 allot only forth definitions : arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise. \ FICL_PLATFORM_ARCHITECTURE is always defined, drop flag s" FICL_PLATFORM_ARCHITECTURE" environment? drop s" i386" compare 0<> if true else false then ; : acpipresent? ( -- flag ) \ Returns TRUE if ACPI is present, FALSE otherwise s" hint.acpi.0.rsdp" getenv dup -1 = if drop false exit then 2drop true ; : acpienabled? ( -- flag ) \ Returns TRUE if ACPI is enabled, FALSE otherwise s" hint.acpi.0.disabled" getenv dup -1 <> if s" 0" compare 0<> if false exit then else drop then true ; : +c! ( N C-ADDR/U K -- C-ADDR/U ) 3 pick 3 pick ( n c-addr/u k -- n c-addr/u k n c-addr ) rot + c! ( n c-addr/u k n c-addr -- n c-addr/u ) rot drop ( n c-addr/u -- c-addr/u ) ; only forth also menu-namespace definitions \ Forth variables : namespace ( C-ADDR/U N -- ) also menu-namespace +c! evaluate previous ; : menukeyN ( N -- ADDR ) s" menukeyN" 7 namespace ; : init_stateN ( N -- ADDR ) s" init_stateN" 10 namespace ; : toggle_stateN ( N -- ADDR ) s" toggle_stateN" 12 namespace ; : cycle_stateN ( N -- ADDR ) s" cycle_stateN" 11 namespace ; : init_textN ( N -- C-ADDR ) s" init_textN" 9 namespace ; \ Environment variables : menu_init[x] ( N -- C-ADDR/U ) s" menu_init[x]" 10 +c! ; : menu_command[x] ( N -- C-ADDR/U ) s" menu_command[x]" 13 +c! ; : menu_caption[x] ( N -- C-ADDR/U ) s" menu_caption[x]" 13 +c! ; : ansi_caption[x] ( N -- C-ADDR/U ) s" ansi_caption[x]" 13 +c! ; : menu_keycode[x] ( N -- C-ADDR/U ) s" menu_keycode[x]" 13 +c! ; : toggled_text[x] ( N -- C-ADDR/U ) s" toggled_text[x]" 13 +c! ; : toggled_ansi[x] ( N -- C-ADDR/U ) s" toggled_ansi[x]" 13 +c! ; : menu_caption[x][y] ( N M -- C-ADDR/U ) s" menu_caption[x][y]" 16 +c! 13 +c! ; : ansi_caption[x][y] ( N M -- C-ADDR/U ) s" ansi_caption[x][y]" 16 +c! 13 +c! ; also menu-infrastructure definitions \ This function prints a menu item at menuX (row) and menuY (column), returns \ the incremental decimal ASCII value associated with the menu item, and \ increments the cursor position to the next row for the creation of the next \ menu item. This function is called by the menu-create function. You need not \ call it directly. \ : printmenuitem ( menu_item_str -- ascii_keycode ) loader_color? if [char] ^ escc! then menurow dup @ 1+ swap ! ( increment menurow ) menuidx dup @ 1+ swap ! ( increment menuidx ) \ Calculate the menuitem row position menurow @ menuY @ + \ Position the cursor at the menuitem position dup menuX @ swap at-xy \ Print the value of menuidx loader_color? dup ( -- bool bool ) if b then menuidx @ . if me then \ Move the cursor forward 1 column dup menuX @ 1+ swap at-xy menubllt @ emit \ Print the menu bullet using the emit function \ Move the cursor to the 3rd column from the current position \ to allow for a space between the numerical prefix and the \ text caption menuX @ 3 + swap at-xy \ Print the menu caption (we expect a string to be on the stack \ prior to invoking this function) type \ Here we will add the ASCII decimal of the numerical prefix \ to the stack (decimal ASCII for `1' is 49) as a "return value" menuidx @ 48 + ; : delim? ( C -- BOOL ) dup 32 = ( c -- c bool ) \ [sp] space over 9 = or ( c bool -- c bool ) \ [ht] horizontal tab over 10 = or ( c bool -- c bool ) \ [nl] newline over 13 = or ( c bool -- c bool ) \ [cr] carriage return over [char] , = or ( c bool -- c bool ) \ comma swap drop ( c bool -- bool ) \ return boolean ; \ illumos kernel acpi-user-options has following values: \ default: 0 - system will enable acpi based on bios date \ on: 1 - acpi is set on \ off: 2 - acpi is set off \ madt: 4 - use only MADT \ legacy: 8 - use legacy mode : acpi-captions ( N -- ) \ first entry dup s" [A]CPI................ default" rot 48 menu_caption[x][y] setenv dup s" ^[1mA^[mCPI.............. ^[32;7mdefault^[m" rot 48 ansi_caption[x][y] setenv dup s" [A]CPI................ On" rot 49 menu_caption[x][y] setenv dup s" ^[1mA^[mCPI.............. ^[34;1mOn^[m" rot 49 ansi_caption[x][y] setenv dup s" [A]CPI................ Off" rot 50 menu_caption[x][y] setenv dup s" ^[1mA^[mCPI.............. ^[34;1mOff^[m" rot 50 ansi_caption[x][y] setenv dup s" [A]CPI................ MADT" rot 51 menu_caption[x][y] setenv dup s" ^[1mA^[mCPI.............. ^[34;1mMADT^[m" rot 51 ansi_caption[x][y] setenv dup s" [A]CPI................ Legacy" rot 52 menu_caption[x][y] setenv s" ^[1mA^[mCPI.............. ^[34;1mLegacy^[m" rot 52 ansi_caption[x][y] setenv ; \ illumos console has following values: \ text, ttya, ttyb, ttyc, ttyd : osconsole-captions ( N -- ) \ first entry dup s" Os[C]onsole........... text" rot 48 menu_caption[x][y] setenv dup s" Os^[1mC^[monsole............ ^[32;7mtext^[m" rot 48 ansi_caption[x][y] setenv dup s" Os[C]onsole........... ttya" rot 49 menu_caption[x][y] setenv dup s" Os^[1mC^[monsole............ ^[34;1mttya^[m" rot 49 ansi_caption[x][y] setenv dup s" Os[C]onsole........... ttyb" rot 50 menu_caption[x][y] setenv dup s" Os^[1mC^[monsole............ ^[34;1mttyb^[m" rot 50 ansi_caption[x][y] setenv dup s" Os[C]onsole........... ttyc" rot 51 menu_caption[x][y] setenv dup s" Os^[1mC^[monsole............ ^[34;1mttyc^[m" rot 51 ansi_caption[x][y] setenv dup s" Os[C]onsole........... ttyd" rot 52 menu_caption[x][y] setenv s" Os^[1mC^[monsole............ ^[34;1mttyd^[m" rot 52 ansi_caption[x][y] setenv ; \ kmdb options are as follows \ default: 0 - disabled \ 1 - boot with -k option \ 2 - as 1 + configure NMI to drop to kmdb \ 3 - boot with -k and -d options \ 4 - as 3 + configure NMI to drop to kmdb : kmdb-captions ( N -- ) \ first entry dup s" [k]mdb Mode........... Off" rot 48 menu_caption[x][y] setenv dup s" ^[1mk^[mmdb Mode............. ^[34;1mOff^[m" rot 48 ansi_caption[x][y] setenv dup s" [k]mdb Mode........... Loaded" rot 49 menu_caption[x][y] setenv dup s" ^[1mk^[mmdb Mode............. ^[32;7mLoaded^[m" rot 49 ansi_caption[x][y] setenv dup s" [k]mdb Mode........... On NMI" rot 50 menu_caption[x][y] setenv dup s" ^[1mk^[mmdb Mode............. ^[32;7mOn NMI^[m" rot 50 ansi_caption[x][y] setenv dup s" [k]mdb Mode........... On Boot" rot 51 menu_caption[x][y] setenv dup s" ^[1mk^[mmdb Mode............. ^[32;7mOn Boot^[m" rot 51 ansi_caption[x][y] setenv dup s" [k]mdb Mode........... On Boot/NMI" rot 52 menu_caption[x][y] setenv s" ^[1mk^[mmdb Mode............. ^[32;7mOn Boot/NMI^[m" rot 52 ansi_caption[x][y] setenv ; : set-captions ( x y - x y ) \ Set the current non-ANSI caption 2dup swap dup ( x y -- x y y x x ) s" set menu_caption[x]=$menu_caption[x][y]" 17 +c! 34 +c! 37 +c! evaluate ( x y y x x c-addr/u -- x y ) \ Set the current ANSI caption 2dup swap dup ( x y -- x y y x x ) s" set ansi_caption[x]=$ansi_caption[x][y]" 17 +c! 34 +c! 37 +c! evaluate ( x y y x x c-addr/u -- x y ) ; \ This function creates the list of menu items. This function is called by the \ menu-display function. You need not call it directly. \ : menu-create ( -- ) \ Print the frame caption at (x,y) s" loader_menu_title" getenv dup -1 = if drop s" Welcome to illumos" then TRUE ( use default alignment ) s" loader_menu_title_align" getenv dup -1 <> if 2dup s" left" compare-insensitive 0= if ( 1 ) 2drop ( c-addr/u ) drop ( bool ) menuX @ menuY @ 1- FALSE ( don't use default alignment ) else ( 1 ) 2dup s" right" compare-insensitive 0= if ( 2 ) 2drop ( c-addr/u ) drop ( bool ) menuX @ 42 + 4 - over - menuY @ 1- FALSE ( don't use default alignment ) else ( 2 ) 2drop ( c-addr/u ) then ( 1 ) then else drop ( getenv cruft ) then if ( use default center alignement? ) menuX @ 19 + over 2 / - menuY @ 1- then at-xy type \ If $menu_init is set, evaluate it (allowing for whole menus to be \ constructed dynamically -- as this function could conceivably set \ the remaining environment variables to construct the menu entirely). \ s" menu_init" getenv dup -1 <> if evaluate else drop then \ Print our menu options with respective key/variable associations. \ `printmenuitem' ends by adding the decimal ASCII value for the \ numerical prefix to the stack. We store the value left on the stack \ to the key binding variable for later testing against a character \ captured by the `getkey' function. \ Note that any menu item beyond 9 will have a numerical prefix on the \ screen consisting of the first digit (ie. 1 for the tenth menu item) \ and the key required to activate that menu item will be the decimal \ ASCII of 48 plus the menu item (ie. 58 for the tenth item, aka. `:') \ which is misleading and not desirable. \ \ Thus, we do not allow more than 8 configurable items on the menu \ (with "Reboot" as the optional ninth and highest numbered item). \ \ Initialize the OsConsole option status. \ 0 menuosconsole ! s" menu_osconsole" getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) dup menuosconsole ! dup osconsole-captions s" init_osconsole" evaluate \ Get the current cycle state (entry to use) s" osconsole_state" evaluate @ 48 + ( n -- n y ) set-captions \ Initialize cycle state from stored value 48 - ( n y -- n k ) s" init_cyclestate" evaluate ( n k -- n ) \ Set $os_console s" activate_osconsole" evaluate ( n -- n ) then drop then \ \ Initialize the ACPI option status. \ 0 menuacpi ! s" menu_acpi" getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) dup menuacpi ! dup acpi-captions s" init_acpi" evaluate \ Get the current cycle state (entry to use) s" acpi_state" evaluate @ 48 + ( n -- n y ) set-captions \ Initialize cycle state from stored value 48 - ( n y -- n k ) s" init_cyclestate" evaluate ( n k -- n ) \ Set $acpi-user-options s" activate_acpi" evaluate ( n -- n ) then drop then \ \ Initialize the kmdb option status. \ 0 menukmdb ! s" menu_kmdb" getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) dup menukmdb ! dup kmdb-captions s" init_kmdb" evaluate \ Get the current cycle state (entry to use) s" kmdb_state" evaluate @ 48 + ( n -- n y ) set-captions \ Initialize cycle state from stored value 48 - ( n y -- n k ) s" init_cyclestate" evaluate ( n k -- n ) \ Activate the current option s" activate_kmdb" evaluate ( n -- n ) then drop then \ \ Initialize the menu_options visual separator. \ 0 menuoptions ! s" menu_options" getenv -1 <> if c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' ) menuoptions ! else drop then then \ Initialize "Reboot" menu state variable (prevents double-entry) false menurebootadded ! menu_start 1- menuidx ! \ Initialize the starting index for the menu 0 menurow ! \ Initialize the starting position for the menu 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin \ If the "Options:" separator, print it. dup menuoptions @ = if \ Optionally add a reboot option to the menu s" menu_reboot" getenv -1 <> if drop s" Reboot" printmenuitem menureboot ! true menurebootadded ! then menuX @ menurow @ 2 + menurow ! menurow @ menuY @ + at-xy s" menu_optionstext" getenv dup -1 <> if type else drop ." Options:" then then \ make sure we have not already initialized this item dup init_stateN dup @ 0= if 1 swap ! \ If this menuitem has an initializer, run it dup menu_init[x] getenv dup -1 <> if evaluate else drop then else drop then dup loader_color? if ansi_caption[x] else menu_caption[x] then dup -1 <> if \ test for environment variable getenv dup -1 <> if printmenuitem ( c-addr/u -- n ) dup menukeyN ! else drop then else drop then 1+ dup 56 > \ add 1 to iterator, continue if less than 57 until drop \ iterator \ Optionally add a reboot option to the menu menurebootadded @ true <> if s" menu_reboot" getenv -1 <> if drop \ no need for the value s" Reboot" \ menu caption (required by printmenuitem) printmenuitem menureboot ! else 0 menureboot ! then then ; \ Takes an integer on the stack and updates the timeout display. \ : menu-timeout-update ( N -- ) \ Enforce minimum dup 0 < if drop 0 then menu_timeout_x @ menu_timeout_y @ at-xy \ position cursor dup 0> if s" Autoboot in " type dup . s" second" type 1 > if [char] s emit then s" . [Space] to pause " type else drop 40 spaces \ erase message then at-bl ; \ This function blocks program flow (loops forever) until a key is pressed. \ The key that was pressed is added to the top of the stack in the form of its \ decimal ASCII representation. This function is called by the menu-display \ function. You need not call it directly. \ note, the esc sequences will be dropped, this needs to be changed if \ menu is built based on arrow keys. \ : getkey ( -- ascii_keycode ) begin \ loop forever menu_timeout_enabled @ 1 = if ( -- ) seconds ( get current time: -- N ) dup menu_time @ <> if ( has time elapsed?: N N N -- N ) \ At least 1 second has elapsed since last loop \ so we will decrement our "timeout" (really a \ counter, insuring that we do not proceed too \ fast) and update our timeout display. menu_time ! ( update time record: N -- ) menu_timeout @ ( "time" remaining: -- N ) dup 0> if ( greater than 0?: N N 0 -- N ) 1- ( decrement counter: N -- N ) dup menu_timeout ! ( re-assign: N N Addr -- N ) then ( -- N ) dup 0= swap 0< or if ( N <= 0?: N N -- ) \ halt the timer 0 menu_timeout ! ( 0 Addr -- ) 0 menu_timeout_enabled ! ( 0 Addr -- ) then \ update the timer display ( N -- ) menu_timeout @ menu-timeout-update menu_timeout @ 0= if \ We've reached the end of the timeout \ (user did not cancel by pressing ANY \ key) s" menu_timeout_command" getenv dup -1 = if drop \ clean-up else evaluate then then else ( -- N ) \ No [detectable] time has elapsed (in seconds) drop ( N -- ) then ( -- ) then key? if \ Was a key pressed? (see loader(8)) \ An actual key was pressed (if the timeout is running, \ kill it regardless of which key was pressed) menu_timeout @ 0<> if 0 menu_timeout ! 0 menu_timeout_enabled ! \ clear screen of timeout message 0 menu-timeout-update then \ get the key that was pressed and exit (if we \ get a non-zero ASCII code) key dup 0<> if dup 0x1b = if key? if ( is it sequence? ) drop begin key? while key drop repeat else exit then else exit then else drop then then 50 ms \ sleep for 50 milliseconds (see loader(8)) again ; : menu-erase ( -- ) \ Erases menu and resets positioning variable to position 1. \ Clear the screen area associated with the interactive menu menuX @ menuY @ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 1+ 2dup at-xy 38 spaces 2drop \ Reset the starting index and position for the menu menu_start 1- menuidx ! 0 menurow ! ; only forth also menu-infrastructure also menu-namespace also menu-command-helpers definitions : toggle_menuitem ( N -- N ) \ toggles caption text and internal menuitem state \ ASCII numeral equal to user-selected menu item must be on the stack. \ We do not modify the stack, so the ASCII numeral is left on top. dup init_textN c@ 0= if \ NOTE: no need to check toggle_stateN since the first time we \ are called, we will populate init_textN. Further, we don't \ need to test whether menu_caption[x] (ansi_caption[x] when \ loader_color?=1) is available since we would not have been \ called if the caption was NULL. \ base name of environment variable dup ( n -- n n ) \ key pressed loader_color? if ansi_caption[x] else menu_caption[x] then getenv dup -1 <> if 2 pick ( n c-addr/u -- n c-addr/u n ) init_textN ( n c-addr/u n -- n c-addr/u c-addr ) \ now we have the buffer c-addr on top \ ( followed by c-addr/u of current caption ) \ Copy the current caption into our buffer 2dup c! -rot \ store strlen at first byte begin rot 1+ \ bring alt addr to top and increment -rot -rot \ bring buffer addr to top 2dup c@ swap c! \ copy current character 1+ \ increment buffer addr rot 1- \ bring buffer len to top and decrement dup 0= \ exit loop if buffer len is zero until 2drop \ buffer len/addr drop \ alt addr else drop then then \ Now we are certain to have init_textN populated with the initial \ value of menu_caption[x] (ansi_caption[x] with loader_color enabled). \ We can now use init_textN as the untoggled caption and \ toggled_text[x] (toggled_ansi[x] with loader_color enabled) as the \ toggled caption and store the appropriate value into menu_caption[x] \ (again, ansi_caption[x] with loader_color enabled). Last, we'll \ negate the toggled state so that we reverse the flow on subsequent \ calls. dup toggle_stateN @ 0= if \ state is OFF, toggle to ON dup ( n -- n n ) \ key pressed loader_color? if toggled_ansi[x] else toggled_text[x] then getenv dup -1 <> if \ Assign toggled text to menu caption 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed loader_color? if ansi_caption[x] else menu_caption[x] then setenv else \ No toggled text, keep the same caption drop ( n -1 -- n ) \ getenv cruft then true \ new value of toggle state var (to be stored later) else \ state is ON, toggle to OFF dup init_textN count ( n -- n c-addr/u ) \ Assign init_textN text to menu caption 2 pick ( n c-addr/u -- n c-addr/u n ) \ key pressed loader_color? if ansi_caption[x] else menu_caption[x] then setenv false \ new value of toggle state var (to be stored below) then \ now we'll store the new toggle state (on top of stack) over toggle_stateN ! ; : cycle_menuitem ( N -- N ) \ cycles through array of choices for a menuitem \ ASCII numeral equal to user-selected menu item must be on the stack. \ We do not modify the stack, so the ASCII numeral is left on top. dup cycle_stateN dup @ 1+ \ get value and increment \ Before assigning the (incremented) value back to the pointer, \ let's test for the existence of this particular array element. \ If the element exists, we'll store index value and move on. \ Otherwise, we'll loop around to zero and store that. dup 48 + ( n addr k -- n addr k k' ) \ duplicate array index and convert to ASCII numeral 3 pick swap ( n addr k k' -- n addr k n k' ) \ (n,k') as (x,y) loader_color? if ansi_caption[x][y] else menu_caption[x][y] then ( n addr k n k' -- n addr k c-addr/u ) \ Now test for the existence of our incremented array index in the \ form of $menu_caption[x][y] ($ansi_caption[x][y] with loader_color \ enabled) as set in loader.rc(5), et. al. getenv dup -1 = if \ No caption set for this array index. Loop back to zero. drop ( n addr k -1 -- n addr k ) \ getenv cruft drop 0 ( n addr k -- n addr 0 ) \ new value to store later 2 pick [char] 0 ( n addr 0 -- n addr 0 n 48 ) \ (n,48) as (x,y) loader_color? if ansi_caption[x][y] else menu_caption[x][y] then ( n addr 0 n 48 -- n addr 0 c-addr/u ) getenv dup -1 = if \ Highly unlikely to occur, but to ensure things move \ along smoothly, allocate a temporary NULL string drop ( cruft ) s" " then then \ At this point, we should have the following on the stack (in order, \ from bottom to top): \ \ n - Ascii numeral representing the menu choice (inherited) \ addr - address of our internal cycle_stateN variable \ k - zero-based number we intend to store to the above \ c-addr/u - string value we intend to store to menu_caption[x] \ (or ansi_caption[x] with loader_color enabled) \ \ Let's perform what we need to with the above. \ Assign array value text to menu caption 4 pick ( n addr k c-addr/u -- n addr k c-addr/u n ) loader_color? if ansi_caption[x] else menu_caption[x] then setenv swap ! ( n addr k -- n ) \ update array state variable ; only forth definitions also menu-infrastructure \ Erase and redraw the menu. Useful if you change a caption and want to \ update the menu to reflect the new value. \ : menu-redraw ( -- ) menu-erase menu-create ; : menu-box ( -- ) \ Interpret a custom frame type for the menu TRUE ( draw a box? default yes, but might be altered below ) s" loader_menu_frame" getenv dup -1 = if ( 1 ) drop \ no custom frame type else ( 1 ) 2dup s" single" compare-insensitive 0= if ( 2 ) f_single ( see frames.4th ) else ( 2 ) 2dup s" double" compare-insensitive 0= if ( 3 ) f_double ( see frames.4th ) else ( 3 ) s" none" compare-insensitive 0= if ( 4 ) drop FALSE \ don't draw a box ( 4 ) then ( 3 ) then ( 2 ) then ( 1 ) then if 42 13 menuX @ 3 - menuY @ 1- box \ Draw frame (w,h,x,y) then ; \ This function initializes the menu. Call this from your `loader.rc' file \ before calling any other menu-related functions. \ : menu-init ( -- ) menu_start 1- menuidx ! \ Initialize the starting index for the menu 0 menurow ! \ Initialize the starting position for the menu \ Assign configuration values s" loader_menu_y" getenv dup -1 = if drop \ no custom row position menu_default_y else \ make sure custom position is a number ?number 0= if menu_default_y \ or use default then then menuY ! s" loader_menu_x" getenv dup -1 = if drop \ no custom column position menu_default_x else \ make sure custom position is a number ?number 0= if menu_default_x \ or use default then then menuX ! ['] menu-box console-iterate at-bl ; also menu-namespace \ Main function. Call this from your `loader.rc' file. \ : menu-display ( -- ) 0 menu_timeout_enabled ! \ start with automatic timeout disabled \ check indication that automatic execution after delay is requested s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr ) drop ( just testing existence right now: Addr -- ) \ initialize state variables seconds menu_time ! ( store the time we started ) 1 menu_timeout_enabled ! ( enable automatic timeout ) \ read custom time-duration (if set) s" autoboot_delay" getenv dup -1 = if drop \ no custom duration (remove dup'd bunk -1) menu_timeout_default \ use default setting else 2dup ?number 0= if ( if not a number ) \ disable timeout if "NO", else use default s" NO" compare-insensitive 0= if 0 menu_timeout_enabled ! 0 ( assigned to menu_timeout below ) else menu_timeout_default then else -rot 2drop \ boot immediately if less than zero dup 0< if drop menu-create at-bl 0 boot then then then menu_timeout ! ( store value on stack from above ) menu_timeout_enabled @ 1 = if \ read custom column position (if set) s" loader_menu_timeout_x" getenv dup -1 = if drop \ no custom column position menu_timeout_default_x \ use default setting else \ make sure custom position is a number ?number 0= if menu_timeout_default_x \ or use default then then menu_timeout_x ! ( store value on stack from above ) \ read custom row position (if set) s" loader_menu_timeout_y" getenv dup -1 = if drop \ no custom row position menu_timeout_default_y \ use default setting else \ make sure custom position is a number ?number 0= if menu_timeout_default_y \ or use default then then menu_timeout_y ! ( store value on stack from above ) then then cursor-invisible cursor-set menu-create begin \ Loop forever at-bl \ restore cursor for case the getkey ends up in \ booting the kernel. This does restore cursor for \ serial terminals. cursor-normal cursor-set getkey \ Block here, waiting for a key to be pressed cursor-invisible cursor-set dup -1 = if cursor-normal cursor-set drop exit \ Caught abort (abnormal return) then \ Boot if the user pressed Enter/Ctrl-M (13) or \ Ctrl-Enter/Ctrl-J (10) dup over 13 = swap 10 = or if drop ( no longer needed ) cursor-normal cursor-set s" boot" evaluate exit ( pedantic; never reached ) then dup menureboot @ = if 0 reboot then \ Evaluate the decimal ASCII value against known menu item \ key associations and act accordingly 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin dup menukeyN @ rot tuck = if \ Adjust for missing ACPI menuitem on non-i386 \ arch-i386? true <> menuacpi @ 0<> and if \ menuacpi @ over 2dup < -rot = or \ over 58 < and if \ ( key >= menuacpi && key < 58: N -- N ) \ 1+ \ then \ then \ Test for the environment variable dup menu_command[x] getenv dup -1 <> if \ Execute the stored procedure cursor-normal cursor-set evaluate \ We expect there to be a non-zero \ value left on the stack after \ executing the stored procedure. \ If so, continue to run, else exit. 0= if drop \ key pressed drop \ loop iterator exit else swap \ need iterator on top then cursor-invisible cursor-set then \ Re-adjust for missing ACPI menuitem \ arch-i386? true <> menuacpi @ 0<> and if \ swap \ menuacpi @ 1+ over 2dup < -rot = or \ over 59 < and if \ 1- \ then \ swap \ then else swap \ need iterator on top then \ \ Check for menu keycode shortcut(s) \ dup menu_keycode[x] getenv dup -1 = if drop else ?number 0<> if rot tuck = if swap dup menu_command[x] getenv dup -1 <> if cursor-normal cursor-set evaluate 0= if 2drop exit then cursor-invisible cursor-set else drop then else swap then then then 1+ dup 56 > \ increment iterator \ continue if less than 57 until drop \ loop iterator drop \ key pressed again \ Non-operational key was pressed; repeat ; \ This function unsets all the possible environment variables associated with \ creating the interactive menu. \ : menu-unset ( -- ) 49 \ Iterator start (loop range 49 to 56; ASCII '1' to '8') begin dup menu_init[x] unsetenv \ menu initializer dup menu_command[x] unsetenv \ menu command dup menu_caption[x] unsetenv \ menu caption dup ansi_caption[x] unsetenv \ ANSI caption dup menu_keycode[x] unsetenv \ menu keycode dup toggled_text[x] unsetenv \ toggle_menuitem caption dup toggled_ansi[x] unsetenv \ toggle_menuitem ANSI caption 48 \ Iterator start (inner range 48 to 57; ASCII '0' to '9') begin \ cycle_menuitem caption and ANSI caption 2dup menu_caption[x][y] unsetenv 2dup ansi_caption[x][y] unsetenv 1+ dup 57 > until drop \ inner iterator 0 over menukeyN ! \ used by menu-create, menu-display 0 over init_stateN ! \ used by menu-create 0 over toggle_stateN ! \ used by toggle_menuitem 0 over init_textN c! \ used by toggle_menuitem 0 over cycle_stateN ! \ used by cycle_menuitem 1+ dup 56 > \ increment, continue if less than 57 until drop \ iterator s" menu_timeout_command" unsetenv \ menu timeout command s" menu_reboot" unsetenv \ Reboot menu option flag s" menu_acpi" unsetenv \ ACPI menu option flag s" menu_kmdb" unsetenv \ kmdb menu option flag s" menu_osconsole" unsetenv \ osconsole menu option flag s" menu_options" unsetenv \ Options separator flag s" menu_optionstext" unsetenv \ separator display text s" menu_init" unsetenv \ menu initializer 0 menureboot ! 0 menuacpi ! 0 menukmdb ! 0 menuosconsole ! 0 menuoptions ! ; only forth definitions also menu-infrastructure \ This function both unsets menu variables and visually erases the menu area \ in-preparation for another menu. \ : menu-clear ( -- ) menu-unset menu-erase ; bullet menubllt ! also menu-namespace \ Initialize our menu initialization state variables 0 init_state1 ! 0 init_state2 ! 0 init_state3 ! 0 init_state4 ! 0 init_state5 ! 0 init_state6 ! 0 init_state7 ! 0 init_state8 ! \ Initialize our boolean state variables 0 toggle_state1 ! 0 toggle_state2 ! 0 toggle_state3 ! 0 toggle_state4 ! 0 toggle_state5 ! 0 toggle_state6 ! 0 toggle_state7 ! 0 toggle_state8 ! \ Initialize our array state variables 0 cycle_state1 ! 0 cycle_state2 ! 0 cycle_state3 ! 0 cycle_state4 ! 0 cycle_state5 ! 0 cycle_state6 ! 0 cycle_state7 ! 0 cycle_state8 ! \ Initialize string containers 0 init_text1 c! 0 init_text2 c! 0 init_text3 c! 0 init_text4 c! 0 init_text5 c! 0 init_text6 c! 0 init_text7 c! 0 init_text8 c! only forth definitions \ Menu.rc \ \ Load required Forth modules include /boot/forth/version.4th include /boot/forth/brand.4th include /boot/forth/menu.4th include /boot/forth/menu-commands.4th include /boot/forth/shortcuts.4th \ Screen prep clear \ clear the screen (see `screen.4th') print_version \ print version string (bottom-right; see `version.4th') draw-beastie \ draw freebsd mascot (on right; see `beastie.4th') draw-brand \ draw the FreeBSD title (top-left; see `brand.4th') menu-init \ initialize the menu area (see `menu.4th') \ Initialize main menu constructs (see `menu.4th') \ NOTE: To use `non-ansi' variants, add `loader_color=0' to loader.conf(5) \ NOTE: ANSI variants can use `^' in place of literal `Esc' (ASCII 27) \ \ MAIN MENU \ set menuset_name1="main" set mainmenu_init[1]="init_boot" s" smartos" getenv? [if] set mainmenu_caption[1]="Boot SmartOS [Enter]" set maintoggled_text[1]="R[e]covery (root/root) [Enter]" set mainansi_caption[1]="^[1mB^[moot SmartOS ^[1m[Enter]^[m" set maintoggled_ansi[1]="R^[1me^[mcovery (root/root) ^[1m[Enter]^[m" [else] set mainmenu_caption[1]="Boot Multi User [Enter]" set maintoggled_text[1]="Boot [S]ingle User [Enter]" set mainansi_caption[1]="^[1mB^[moot Multi User ^[1m[Enter]^[m" set maintoggled_ansi[1]="Boot ^[1mS^[mingle User ^[1m[Enter]^[m" [then] set mainmenu_command[1]="boot" \ keycode set by init_boot set mainmenu_init[2]="init_altboot" s" smartos" getenv? [if] set mainmenu_caption[2]="[R]ecovery (root/root)" set maintoggled_text[2]="[B]oot SmartOS" set mainansi_caption[2]="^[1mR^[mecovery (root/root)" set maintoggled_ansi[2]="^[1mB^[oot SmartOS" [else] set mainmenu_caption[2]="Boot [S]ingle User" set maintoggled_text[2]="Boot [M]ulti User" set mainansi_caption[2]="Boot ^[1mS^[mingle User" set maintoggled_ansi[2]="Boot ^[1mM^[multi User" [then] set mainmenu_command[2]="altboot" \ keycode set by init_altboot set mainmenu_caption[3]="[Esc]ape to loader prompt" set mainmenu_command[3]="goto_prompt" set mainmenu_keycode[3]=27 set mainansi_caption[3]="^[1mEsc^[mape to loader prompt" \ Enable built-in "Reboot" trailing menuitem \ NOTE: appears before menu_options if configured \ set mainmenu_reboot \ Enable "Options:" separator. When set to a numerical value (1-8), a visual \ separator is inserted before that menuitem number. \ set mainmenu_options=5 set mainmenu_caption[5]="Configure Boot [O]ptions..." set mainmenu_command[5]="2 goto_menu" set mainmenu_keycode[5]=111 set mainansi_caption[5]="Configure Boot ^[1mO^[mptions..." \ Boot Environments are (supported) only on ZFS s" currdev" getenv drop 4 s" zfs:" compare 0= be-pages and [if] set mainmenu_caption[6]="Select Boot [E]nvironment..." set mainmenu_command[6]="3 goto_menu" set mainmenu_keycode[6]=101 set mainansi_caption[6]="Select Boot ^[1mE^[mnvironment..." s" chain_disk" getenv? [if] set mainmenu_caption[7]="Chain[L]oad ${chain_disk}" set mainmenu_command[7]="chain ${chain_disk}" set mainmenu_keycode[7]=108 set mainansi_caption[7]="Chain^[1mL^[moad ${chain_disk}" [then] [else] s" chain_disk" getenv? [if] set mainmenu_caption[6]="Chain[L]oad ${chain_disk}" set mainmenu_command[6]="chain ${chain_disk}" set mainmenu_keycode[6]=108 set mainansi_caption[6]="Chain^[1mL^[moad ${chain_disk}" [then] [then] \ \ BOOT OPTIONS MENU \ set menuset_name2="options" set optionsmenu_caption[1]="Back to Main Menu [Backspace]" set optionsmenu_command[1]="1 goto_menu" set optionsmenu_keycode[1]=8 set optionsansi_caption[1]="Back to Main Menu ^[1m[Backspace]^[m" \ set optionsmenu_caption[2]="Load System [D]efaults" \ set optionsmenu_command[2]="set_default_boot_options" \ set optionsmenu_keycode[2]=100 \ set optionsansi_caption[2]="Load System ^[1mD^[mefaults" set optionsmenu_options=2 set optionsmenu_optionstext="Boot Options:" set optionsmenu_osconsole=2 set optionsmenu_command[2]="cycle_osconsole" set optionsmenu_keycode[2]=99 set optionsmenu_acpi=3 set optionsmenu_command[3]="cycle_acpi" set optionsmenu_keycode[3]=97 set optionsmenu_init[4]="init_singleuser" set optionsmenu_caption[4]="[S]ingle User......... Off" set optionstoggled_text[4]="[S]ingle User......... On" set optionsmenu_command[4]="toggle_singleuser" set optionsmenu_keycode[4]=115 set optionsansi_caption[4]="^[1mS^[mingle User........... ^[34;1mOff^[m" set optionstoggled_ansi[4]="^[1mS^[mingle User........... ^[32;7mOn^[m" set optionsmenu_init[5]="init_verbose" set optionsmenu_caption[5]="[V]erbose............. Off" set optionstoggled_text[5]="[V]erbose............. On" set optionsmenu_command[5]="toggle_verbose" set optionsmenu_keycode[5]=118 set optionsansi_caption[5]="^[1mV^[merbose............... ^[34;1mOff^[m" set optionstoggled_ansi[5]="^[1mV^[merbose............... ^[32;7mOn^[m" set optionsmenu_init[6]="init_reconfigure" set optionsmenu_caption[6]="[R]econfigure......... Off" set optionstoggled_text[6]="[R]econfigure......... On" set optionsmenu_command[6]="toggle_reconfigure" set optionsmenu_keycode[6]=114 set optionsansi_caption[6]="^[1mR^[meconfigure........... ^[34;1mOff^[m" set optionstoggled_ansi[6]="^[1mR^[meconfigure........... ^[32;7mOn^[m" set optionsmenu_kmdb=7 set optionsmenu_command[7]="cycle_kmdb" set optionsmenu_keycode[7]=107 \ \ In EFI mode the framebuffer cannot be disabled. Although "framebuffer off" \ does switch to a simple text protocol, it doesn't affect the kernel which \ still ends up with a framebuffer console. This option is therefore only \ exposed in a non-EFI environment. \ efi? invert [if] set optionsmenu_init[8]="init_framebuffer" set optionsmenu_caption[8]="[G]raphical Console... Off" set optionstoggled_text[8]="[G]raphical Console... On" set optionsmenu_command[8]="toggle_framebuffer" set optionsmenu_keycode[8]=103 set optionsansi_caption[8]="^[1mG^[mraphical Console..... ^[34;1mOff^[m" set optionstoggled_ansi[8]="^[1mG^[mraphical Console..... ^[32;7mOn^[m" [then] \ \ BOOT ENVIRONMENT MENU \ \ the BE list is read from [pool]/boot/menu.lst, the list in file \ is ordered from oldest to most recent. \ the BE menu will list entries from most recent to oldest, \ so the first page in menu is last page in menu.lst be-pages [if] set zfs_be_currpage=1 be-set-page \ set page data set menuset_name3="bootenv" set bootenvmenu_command[1]="be_draw_screen 1 goto_menu" set bootenvmenu_keycode[1]=8 set bootenvmenu_keycode[2]=8 set bootenvmenu_command[2]="be_draw_screen 1 goto_menu" set bemenu_current="Active: " set beansi_current="^[1m${bemenu_current}^[m" set bemenu_bootfs="bootfs: " set beansi_bootfs="^[1m${bemenu_bootfs}^[m" set bemenu_page="[P]age: " set beansi_page="^[1mP^[mage: " set bemenu_pageof=" of " set beansi_pageof="${bemenu_pageof}" set bootenvmenu_init="init_bootenv" set bootenvmenu_keycode[3]=112 set bootenvmenu_command[3]="set_be_page" set bootenvmenu_options=4 set bootenvmenu_optionstext="Boot Environments:" [then] \ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to \ customize the timeout; default is 10-seconds) \ set menu_timeout_command="boot" \ Include optional elements defined in a local file \ try-include /boot/menu.rc.local \ Display the main menu (see `menu.4th') set menuset_initial=1 menuset-loadinitial menu-display \ Copyright (c) 2012 Devin Teske \ Copyright 2020 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. \ marker task-menusets.4th vocabulary menusets-infrastructure only forth also menusets-infrastructure definitions variable menuset_use_name create menuset_affixbuf 255 allot create menuset_x 1 allot create menuset_y 1 allot : menuset-loadvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) s" set cmdbuf='set ${type}_${var}=\$'" evaluate s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length menuset_use_name @ true = if s" set cmdbuf=${cmdbuf}${affix}${type}_${var}" ( u1 -- u1 c-addr2 u2 ) else s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}" ( u1 -- u1 c-addr2 u2 ) then evaluate ( u1 c-addr2 u2 -- u1 ) s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) rot 2 pick 2 pick over + -rot + tuck - ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) \ Generate a string representing rvalue inheritance var getenv dup -1 = if ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) \ NOT set -- clean up the stack drop ( c-addr2 u2 -1 -- c-addr2 u2 ) 2drop ( c-addr2 u2 -- ) else ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) \ SET -- execute cmdbuf (c-addr2/u2) to inherit value 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) evaluate ( c-addr2 u2 -- ) then s" cmdbuf" unsetenv ; : menuset-unloadvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) menuset_use_name @ true = if s" set buf=${affix}${type}_${var}" else s" set buf=${type}set${affix}_${var}" then evaluate s" buf" getenv unsetenv s" buf" unsetenv ; : menuset-loadmenuvar ( -- ) s" set type=menu" evaluate menuset-loadvar ; : menuset-unloadmenuvar ( -- ) s" set type=menu" evaluate menuset-unloadvar ; : menuset-loadxvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $x is "1" through "8" \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) s" set cmdbuf='set ${type}_${var}[${x}]=\$'" evaluate s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length menuset_use_name @ true = if s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}]" ( u1 -- u1 c-addr2 u2 ) else s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}]" ( u1 -- u1 c-addr2 u2 ) then evaluate ( u1 c-addr2 u2 -- u1 ) s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) rot 2 pick 2 pick over + -rot + tuck - ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) \ Generate a string representing rvalue inheritance var getenv dup -1 = if ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) \ NOT set -- clean up the stack drop ( c-addr2 u2 -1 -- c-addr2 u2 ) 2drop ( c-addr2 u2 -- ) else ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) \ SET -- execute cmdbuf (c-addr2/u2) to inherit value 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) evaluate ( c-addr2 u2 -- ) then s" cmdbuf" unsetenv ; : menuset-unloadxvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $x is "1" through "8" \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) menuset_use_name @ true = if s" set buf=${affix}${type}_${var}[${x}]" else s" set buf=${type}set${affix}_${var}[${x}]" then evaluate s" buf" getenv unsetenv s" buf" unsetenv ; : menuset-loadansixvar ( -- ) s" set type=ansi" evaluate menuset-loadxvar ; : menuset-unloadansixvar ( -- ) s" set type=ansi" evaluate menuset-unloadxvar ; : menuset-loadmenuxvar ( -- ) s" set type=menu" evaluate menuset-loadxvar ; : menuset-unloadmenuxvar ( -- ) s" set type=menu" evaluate menuset-unloadxvar ; : menuset-unloadtypelessxvar ( -- ) s" set type=" evaluate menuset-unloadxvar ; : menuset-loadtoggledxvar ( -- ) s" set type=toggled" evaluate menuset-loadxvar ; : menuset-unloadtoggledxvar ( -- ) s" set type=toggled" evaluate menuset-unloadxvar ; : menuset-loadxyvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $x is "1" through "8" \ $y is "0" through "9" \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) s" set cmdbuf='set ${type}_${var}[${x}][${y}]=\$'" evaluate s" cmdbuf" getenv swap drop ( -- u1 ) \ get string length menuset_use_name @ true = if s" set cmdbuf=${cmdbuf}${affix}${type}_${var}[${x}][${y}]" ( u1 -- u1 c-addr2 u2 ) else s" set cmdbuf=${cmdbuf}${type}set${affix}_${var}[${x}][${y}]" ( u1 -- u1 c-addr2 u2 ) then evaluate ( u1 c-addr2 u2 -- u1 ) s" cmdbuf" getenv ( u1 -- u1 c-addr2 u2 ) rot 2 pick 2 pick over + -rot + tuck - ( u1 c-addr2 u2 -- c-addr2 u2 c-addr1 u1 ) \ Generate a string representing rvalue inheritance var getenv dup -1 = if ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 -1 ) \ NOT set -- clean up the stack drop ( c-addr2 u2 -1 -- c-addr2 u2 ) 2drop ( c-addr2 u2 -- ) else ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 c-addr1 u1 ) \ SET -- execute cmdbuf (c-addr2/u2) to inherit value 2drop ( c-addr2 u2 c-addr1 u1 -- c-addr2 u2 ) evaluate ( c-addr2 u2 -- ) then s" cmdbuf" unsetenv ; : menuset-unloadxyvar ( -- ) \ menuset_use_name is true or false \ $type should be set to one of: \ menu toggled ansi \ $var should be set to one of: \ caption command keycode text ... \ $x is "1" through "8" \ $y is "0" through "9" \ $affix is either prefix (menuset_use_name is true) \ or infix (menuset_use_name is false) menuset_use_name @ true = if s" set buf=${affix}${type}_${var}[${x}][${y}]" else s" set buf=${type}set${affix}_${var}[${x}][${y}]" then evaluate s" buf" getenv unsetenv s" buf" unsetenv ; : menuset-loadansixyvar ( -- ) s" set type=ansi" evaluate menuset-loadxyvar ; : menuset-unloadansixyvar ( -- ) s" set type=ansi" evaluate menuset-unloadxyvar ; : menuset-loadmenuxyvar ( -- ) s" set type=menu" evaluate menuset-loadxyvar ; : menuset-unloadmenuxyvar ( -- ) s" set type=menu" evaluate menuset-unloadxyvar ; : menuset-setnum-namevar ( N -- C-Addr/U ) s" menuset_nameNNNNN" ( n -- n c-addr1 u1 ) \ variable basename drop 12 ( n c-addr1 u1 -- n c-addr1 12 ) \ remove "NNNNN" rot ( n c-addr1 12 -- c-addr1 12 n ) \ move number on top \ convert to string n2s ( c-addr1 12 n -- c-addr1 12 c-addr2 u2 ) \ Combine strings begin ( using u2 in c-addr2/u2 pair as countdown to zero ) over ( c-addr1 u1 c-addr2 u2 -- continued below ) ( c-addr1 u1 c-addr2 u2 c-addr2 ) \ copy src-addr c@ ( c-addr1 u1 c-addr2 u2 c-addr2 -- continued below ) ( c-addr1 u1 c-addr2 u2 c ) \ get next src-addr byte 4 pick 4 pick ( c-addr1 u1 c-addr2 u2 c -- continued below ) ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 ) \ get destination c-addr1/u1 pair + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- cont. below ) ( c-addr1 u1 c-addr2 u2 c c-addr3 ) \ combine dest-c-addr to get dest-addr for byte c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below ) ( c-addr1 u1 c-addr2 u2 ) \ store the current src-addr byte into dest-addr 2swap 1+ 2swap \ increment u1 in destination c-addr1/u1 pair swap 1+ swap \ increment c-addr2 in source c-addr2/u2 pair 1- \ decrement u2 in the source c-addr2/u2 pair dup 0= \ time to break? until 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) \ drop temporary number-format conversion c-addr2/u2 ; : menuset-checksetnum ( N -- ) \ \ adjust input to be both positive and no-higher than 65535 \ abs dup 65535 > if drop 65535 then ( n -- n ) \ \ The next few blocks will determine if we should use the default \ methodology (referencing the original numeric stack-input), or if- \ instead $menuset_name{N} has been defined wherein we would then \ use the value thereof as the prefix to every menu variable. \ false menuset_use_name ! \ assume name is not set menuset-setnum-namevar \ \ We now have a string that is the assembled variable name to check \ for... $menuset_name{N}. Let's check for it. \ 2dup ( c-addr1 u1 -- c-addr1 u1 c-addr1 u1 ) \ save a copy getenv dup -1 <> if ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 c-addr2 u2 ) \ The variable is set. Let's clean up the stack leaving only \ its value for later use. true menuset_use_name ! 2swap 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr2 u2 ) \ drop assembled variable name, leave the value else ( c-addr1 u1 c-addr1 u1 -- c-addr1 u1 -1 ) \ no such variable \ The variable is not set. Let's clean up the stack leaving the \ string [portion] representing the original numeric input. drop ( c-addr1 u1 -1 -- c-addr1 u1 ) \ drop -1 result 12 - swap 12 + swap ( c-addr1 u1 -- c-addr2 u2 ) \ truncate to original numeric stack-input then \ \ Now, depending on whether $menuset_name{N} has been set, we have \ either the value thereof to be used as a prefix to all menu_* \ variables or we have a string representing the numeric stack-input \ to be used as a "set{N}" infix to the same menu_* variables. \ \ For example, if the stack-input is 1 and menuset_name1 is NOT set \ the following variables will be referenced: \ ansiset1_caption[x] -> ansi_caption[x] \ ansiset1_caption[x][y] -> ansi_caption[x][y] \ menuset1_acpi -> menu_acpi \ menuset1_osconsole -> menu_osconsole \ menuset1_caption[x] -> menu_caption[x] \ menuset1_caption[x][y] -> menu_caption[x][y] \ menuset1_command[x] -> menu_command[x] \ menuset1_init -> ``evaluated'' \ menuset1_init[x] -> menu_init[x] \ menuset1_kernel -> menu_kernel \ menuset1_keycode[x] -> menu_keycode[x] \ menuset1_options -> menu_options \ menuset1_optionstext -> menu_optionstext \ menuset1_reboot -> menu_reboot \ toggledset1_ansi[x] -> toggled_ansi[x] \ toggledset1_text[x] -> toggled_text[x] \ otherwise, the following variables are referenced (where {name} \ represents the value of $menuset_name1 (given 1 as stack-input): \ {name}ansi_caption[x] -> ansi_caption[x] \ {name}ansi_caption[x][y] -> ansi_caption[x][y] \ {name}menu_acpi -> menu_acpi \ {name}menu_caption[x] -> menu_caption[x] \ {name}menu_caption[x][y] -> menu_caption[x][y] \ {name}menu_command[x] -> menu_command[x] \ {name}menu_init -> ``evaluated'' \ {name}menu_init[x] -> menu_init[x] \ {name}menu_kernel -> menu_kernel \ {name}menu_keycode[x] -> menu_keycode[x] \ {name}menu_options -> menu_options \ {name}menu_optionstext -> menu_optionstext \ {name}menu_reboot -> menu_reboot \ {name}toggled_ansi[x] -> toggled_ansi[x] \ {name}toggled_text[x] -> toggled_text[x] \ \ Note that menuset{N}_init and {name}menu_init are the initializers \ for the entire menu (for wholly dynamic menus) opposed to the per- \ menuitem initializers (with [x] afterward). The whole-menu init \ routine is evaluated and not passed down to $menu_init (which \ would result in double evaluation). By doing this, the initializer \ can initialize the menuset before we transfer it to active-duty. \ \ \ Copy our affixation (prefix or infix depending on menuset_use_name) \ to our buffer so that we can safely use the s-quote (s") buf again. \ menuset_affixbuf 0 2swap ( c-addr2 u2 -- c-addr1 0 c-addr2 u2 ) begin ( using u2 in c-addr2/u2 pair as countdown to zero ) over ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c-addr2 ) c@ ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 c-addr2 u2 c ) 4 pick 4 pick ( c-addr1 u1 c-addr2 u2 c -- continued below ) ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 ) + ( c-addr1 u1 c-addr2 u2 c c-addr1 u1 -- continued below ) ( c-addr1 u1 c-addr2 u2 c c-addr3 ) c! ( c-addr1 u1 c-addr2 u2 c c-addr3 -- continued below ) ( c-addr1 u1 c-addr2 u2 ) 2swap 1+ 2swap \ increment affixbuf byte position/count swap 1+ swap \ increment strbuf pointer (source c-addr2) 1- \ decrement strbuf byte count (source u2) dup 0= \ time to break? until 2drop ( c-addr1 u1 c-addr2 u2 -- c-addr1 u1 ) \ drop strbuf c-addr2/u2 \ \ Create a variable for referencing our affix data (prefix or infix \ depending on menuset_use_name as described above). This variable will \ be temporary and only used to simplify cmdbuf assembly. \ s" affix" setenv ( c-addr1 u1 -- ) ; : menuset-cleanup ( -- ) s" type" unsetenv s" var" unsetenv s" x" unsetenv s" y" unsetenv s" affix" unsetenv ; only forth definitions also menusets-infrastructure : menuset-loadsetnum ( N -- ) menuset-checksetnum ( n -- ) \ \ From here out, we use temporary environment variables to make \ dealing with variable-length strings easier. \ \ menuset_use_name is true or false \ $affix should be used appropriately w/respect to menuset_use_name \ \ ... menu_init ... s" set var=init" evaluate menuset-loadmenuvar \ If menu_init was set by the above, evaluate it here-and-now \ so that the remaining variables are influenced by its actions s" menu_init" 2dup getenv dup -1 <> if 2swap unsetenv \ don't want later menu-create to re-call this evaluate else drop 2drop ( n c-addr u -1 -- n ) then [char] 1 ( -- x ) \ Loop range ASCII '1' (49) to '8' (56) begin dup menuset_x tuck c! 1 s" x" setenv \ set loop iterator and $x s" set var=caption" evaluate \ ... menu_caption[x] ... menuset-loadmenuxvar \ ... ansi_caption[x] ... menuset-loadansixvar [char] 0 ( x -- x y ) \ Inner Loop ASCII '1' (48) to '9' (57) begin dup menuset_y tuck c! 1 s" y" setenv \ set inner loop iterator and $y \ ... menu_caption[x][y] ... menuset-loadmenuxyvar \ ... ansi_caption[x][y] ... menuset-loadansixyvar 1+ dup 57 > ( x y -- y' 0|-1 ) \ increment and test until drop ( x y -- x ) \ ... menu_command[x] ... s" set var=command" evaluate menuset-loadmenuxvar \ ... menu_init[x] ... s" set var=init" evaluate menuset-loadmenuxvar \ ... menu_keycode[x] ... s" set var=keycode" evaluate menuset-loadmenuxvar \ ... toggled_text[x] ... s" set var=text" evaluate menuset-loadtoggledxvar \ ... toggled_ansi[x] ... s" set var=ansi" evaluate menuset-loadtoggledxvar 1+ dup 56 > ( x -- x' 0|-1 ) \ increment iterator \ continue if less than 57 until drop ( x -- ) \ loop iterator \ ... menu_reboot ... s" set var=reboot" evaluate menuset-loadmenuvar \ ... menu_acpi ... s" set var=acpi" evaluate menuset-loadmenuvar \ ... menu_osconsole ... s" set var=osconsole" evaluate menuset-loadmenuvar \ ... menu_kmdb ... s" set var=kmdb" evaluate menuset-loadmenuvar \ ... menu_options ... s" set var=options" evaluate menuset-loadmenuvar \ ... menu_optionstext ... s" set var=optionstext" evaluate menuset-loadmenuvar menuset-cleanup ; : menusets-unset ( -- ) \ clean up BE menu internal variables s" beansi_bootfs" unsetenv s" beansi_current" unsetenv s" beansi_page" unsetenv s" beansi_pageof" unsetenv s" bemenu_bootfs" unsetenv s" bemenu_current" unsetenv s" bemenu_page" unsetenv s" bemenu_pageof" unsetenv s" zfs_be_active" unsetenv s" zfs_be_currpage" unsetenv s" zfs_be_pages" unsetenv s" menuset_initial" unsetenv 1 begin dup menuset-checksetnum ( n n -- n ) dup menuset-setnum-namevar ( n n -- n ) unsetenv \ If the current menuset does not populate the first menuitem, \ we stop completely. menuset_use_name @ true = if s" set buf=${affix}menu_command[1]" else s" set buf=menuset${affix}_command[1]" then evaluate s" buf" getenv getenv -1 = if drop ( n -- ) s" buf" unsetenv menuset-cleanup exit else drop ( n c-addr2 -- n ) \ unused then [char] 1 ( n -- n x ) \ Loop range ASCII '1' (49) to '8' (56) begin dup menuset_x tuck c! 1 s" x" setenv \ set $x to x s" set var=caption" evaluate menuset-unloadmenuxvar menuset-unloadmenuxvar menuset-unloadansixvar [char] 0 ( n x -- n x y ) \ Inner loop '0' to '9' begin dup menuset_y tuck c! 1 s" y" setenv \ sets $y to y menuset-unloadmenuxyvar menuset-unloadansixyvar 1+ dup 57 > ( n x y -- n x y' 0|-1 ) until drop ( n x y -- n x ) s" set var=command" evaluate menuset-unloadmenuxvar s" set var=init" evaluate menuset-unloadmenuxvar s" set var=keycode" evaluate menuset-unloadmenuxvar s" set var=root" evaluate menuset-unloadtypelessxvar s" set var=text" evaluate menuset-unloadtoggledxvar s" set var=ansi" evaluate menuset-unloadtoggledxvar 1+ dup 56 > ( x -- x' 0|-1 ) \ increment and test until drop ( n x -- n ) \ loop iterator s" set var=acpi" evaluate menuset-unloadmenuvar s" set var=osconsole" evaluate menuset-unloadmenuvar s" set var=kmdb" evaluate menuset-unloadmenuvar s" set var=init" evaluate menuset-unloadmenuvar s" set var=options" evaluate menuset-unloadmenuvar s" set var=optionstext" evaluate menuset-unloadmenuvar s" set var=reboot" evaluate menuset-unloadmenuvar 1+ dup 65535 > ( n -- n' 0|-1 ) \ increment and test until drop ( n' -- ) \ loop iterator s" buf" unsetenv menuset-cleanup ; only forth definitions : menuset-loadinitial ( -- ) s" menuset_initial" getenv dup -1 <> if ?number 0<> if menuset-loadsetnum then else drop \ cruft then ; \ Copyright (c) 2014 M. Warner Losh \ All rights reserved. \ \ 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. \ \ 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. \ \ $FreeBSD$ only forth also support-functions also builtins definitions \ pci-device-count pci-id \ \ Counts the number of instances of pci-id in the system and reports \ it to the user. : pci-device-count 0= if ( interpreted ) get_arguments then 0= if ." Need an argument" cr abort then \ First argument is 0 when we're interprated. See support.4th \ for get_arguments reading the rest of the line and parsing it \ stack: argN lenN ... arg1 len1 N hex ?number decimal 0= if ." Bad pci-id given (must be legal hex value)" cr abort then dup pcibios-device-count ." Found " . ." instances of " hex . decimal cr ; also forth definitions also builtins builtin: pci-device-count \ Copyright (c) 2000 Daniel C. Sobral \ All rights reserved. \ \ 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. \ \ 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. \ \ $FreeBSD$ \ The following pnp code is used in pnp.4th and pnp.c structure: STAILQ_HEAD ptr stqh_first \ type* ptr stqh_last \ type** ;structure structure: STAILQ_ENTRY ptr stqe_next \ type* ;structure structure: pnphandler ptr pnph.name ptr pnph.enumerate ;structure structure: pnpident ptr pnpid.ident \ char* sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident ;structure structure: pnpinfo \ sync with sys/boot/config/bootstrap.h ptr pnpi.desc int pnpi.revision ptr pnpi.module \ (char*) module args int pnpi.argc ptr pnpi.argv ptr pnpi.handler \ pnphandler sizeof STAILQ_HEAD member: pnpi.ident \ pnpident sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo ;structure \ end of pnp support pnpdevices drop : enumerate pnphandlers begin dup @ while ." Probing " dup @ pnph.name @ dup strlen type ." ..." cr 0 over @ pnph.enumerate @ ccall drop cell+ repeat ; : summary ." PNP scan summary:" cr pnpdevices stqh_first @ begin dup while dup pnpi.ident stqh_first @ pnpid.ident @ dup strlen type dup pnpi.desc @ ?dup if ." : " dup strlen type then cr pnpi.link stqe_next @ repeat drop ; : compare-pnpid ( addr addr' -- flag ) begin over c@ over c@ <> if drop drop false exit then over c@ over c@ and while char+ swap char+ swap repeat c@ swap c@ or 0= ; : search-pnpid ( id -- flag ) >r pnpdevices stqh_first @ begin ( pnpinfo ) dup while dup pnpi.ident stqh_first @ begin ( pnpinfo pnpident ) dup pnpid.ident @ r@ compare-pnpid if r> drop \ XXX Temporary debugging message ." Found " pnpid.ident @ dup strlen type pnpi.desc @ ?dup if ." : " dup strlen type then cr \ drop drop true exit then pnpid.link stqe_next @ ?dup 0= until pnpi.link stqe_next @ repeat r> drop drop false ; : skip-space ( addr -- addr' ) begin dup c@ bl = over c@ 9 = or while char+ repeat ; : skip-to-space ( addr -- addr' ) begin dup c@ bl <> over c@ 9 <> and over c@ and while char+ repeat ; : premature-end? ( addr -- addr flag ) postpone dup postpone c@ postpone 0= postpone if postpone exit postpone then ; immediate 0 value filename 0 value timestamp 0 value id only forth also support-functions : (load) load ; : check-pnpid ( -- ) line_buffer .addr @ \ Search for filename skip-space premature-end? dup to filename \ Search for end of filename skip-to-space premature-end? 0 over c! char+ \ Search for timestamp skip-space premature-end? dup to timestamp skip-to-space premature-end? 0 over c! char+ \ Search for ids begin skip-space premature-end? dup to id skip-to-space dup c@ >r 0 over c! char+ id search-pnpid if filename dup strlen 1 ['] (load) catch if drop drop drop ." Error loading " filename dup strlen type cr then r> drop exit then r> 0= until ; : load-pnp 0 to end_of_file? reset_line_reading s" /boot/pnpid.conf" O_RDONLY fopen fd ! fd @ -1 <> if begin end_of_file? 0= while read_line check-pnpid repeat fd @ fclose then ; \ Copyright (c) 2003 Scott Long \ Copyright (c) 2015 Devin Teske \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. marker task-screen.4th \ emit Esc-[ : escc ( -- ) 27 emit [char] [ emit ; \ Home cursor ( Esc-[H ) : ho ( -- ) escc [char] H emit ; \ Clear from current position to end of display ( Esc-[J ) : cld ( -- ) escc [char] J emit ; \ clear screen : clear ( -- ) ho cld ; \ move cursor to x rows, y cols (1-based coords) ( Esc-[%d;%dH ) : at-xy ( x y -- ) escc .# [char] ; emit .# [char] H emit ; \ Set foreground color ( Esc-[3%dm ) : fg ( x -- ) escc 3 .# .# [char] m emit ; \ Set background color ( Esc-[4%dm ) : bg ( x -- ) escc 4 .# .# [char] m emit ; \ Mode end (clear attributes) : me ( -- ) escc [char] m emit ; \ Enable bold mode ( Esc-[1m ) : b ( -- ) escc 1 .# [char] m emit ; \ Disable bold mode ( Esc-[22m ) : -b ( -- ) escc 22 .# [char] m emit ; \ Enable inverse foreground/background mode ( Esc-[7m ) : inv ( -- ) escc 7 .# [char] m emit ; \ Disable inverse foreground/background mode ( Esc-[27m ) : -inv ( -- ) escc 27 .# [char] m emit ; \ Convert all occurrences of given character (c) in string (c-addr/u) to Esc : escc! ( c-addr/u c -- c-addr/u ) 2 pick 2 pick begin dup 0> while over c@ 3 pick = if over 27 swap c! then 1- swap 1+ swap repeat 2drop drop ; \ Get the number of screen rows/columns : sr ( -- y ) 25 s" screen-#rows" getenvn ; : sc ( -- x ) 80 s" screen-#cols" getenvn ; \ Place the cursor at the bottom left of the screen : at-bl 0 sr at-xy ; \ set cursor invisible or normal (civis/cnorm) : cursor-invisible ( -- ) [char] l ; : cursor-normal ( -- ) [char] h ; : cursor-set ( cursor-mode -- ) escc [char] ? emit 25 .# emit ; \ Copyright (c) 2008-2011 Devin Teske \ All rights reserved. \ \ 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. \ \ 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. \ \ $FreeBSD$ \ FICL words intended to be used as shortcuts for carrying out common tasks or \ producing common results. Generally, words defined here are simply groupings \ of other custom words that pull from multiple libraries (for example, if you \ want to define a custom word that uses words defined in three different \ libraries, this is a good place to define such a word). \ \ This script should be included after you have included any/all other \ libraries. This will prevent calling a word defined here before any required \ words have been defined. marker task-shortcuts.4th \ This "shortcut" word will not be used directly, but is defined here to \ offer the user a quick way to get back into the interactive PXE menu \ after they have escaped to the shell (perhaps by accident). \ : menu ( -- ) clear \ Clear the screen (in screen.4th) print_version \ print version string (bottom-right; see version.4th) draw-beastie \ Draw FreeBSD logo at right (in beastie.4th) draw-brand \ Draw FIS logo at top (in brand.4th) menu-init \ Initialize menu and draw bounding box (in menu.4th) menu-display \ Launch interactive menu (in menu.4th) ; \ Copyright (c) 1999 Daniel C. Sobral \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. \ Loader.rc support functions: \ \ initialize ( addr len -- ) as above, plus load_conf_files \ load_conf ( addr len -- ) load conf file given \ include_bootenv ( -- ) load bootenv.rc \ include_conf_files ( -- ) load all conf files in load_conf_files \ print_syntax_error ( -- ) print line and marker of where a syntax \ error was detected \ print_line ( -- ) print last line processed \ load_kernel ( -- ) load kernel \ load_modules ( -- ) load modules flagged \ \ Exported structures: \ \ string counted string structure \ cell .addr string address \ cell .len string length \ module module loading information structure \ cell module.flag should we load it? \ string module.name module's name \ string module.loadname name to be used in loading the module \ string module.type module's type (file | hash | rootfs) \ string module.hash module's sha1 hash \ string module.args flags to be passed during load \ string module.largs internal argument list \ string module.beforeload command to be executed before load \ string module.afterload command to be executed after load \ string module.loaderror command to be executed if load fails \ cell module.next list chain \ \ Exported global variables; \ \ string conf_files configuration files to be loaded \ cell modules_options pointer to first module information \ value verbose? indicates if user wants a verbose loading \ value any_conf_read? indicates if a conf file was successfully read \ \ Other exported words: \ note, strlen is internal \ strdup ( addr len -- addr' len) similar to strdup(3) \ strcat ( addr len addr' len' -- addr len+len' ) similar to strcat(3) \ s' ( | string' -- addr len | ) similar to s" \ rudimentary structure support \ Exception values 1 constant ESYNTAX 2 constant ENOMEM 3 constant EFREE 4 constant ESETERROR \ error setting environment variable 5 constant EREAD \ error reading 6 constant EOPEN 7 constant EEXEC \ XXX never catched 8 constant EBEFORELOAD 9 constant EAFTERLOAD \ I/O constants 0 constant SEEK_SET 1 constant SEEK_CUR 2 constant SEEK_END 0 constant O_RDONLY 1 constant O_WRONLY 2 constant O_RDWR \ Crude structure support : structure: create here 0 , ['] drop , 0 does> create here swap dup @ allot cell+ @ execute ; : member: create dup , over , + does> cell+ @ + ; : ;structure swap ! ; : constructor! >body cell+ ! ; : constructor: over :noname ; : ;constructor postpone ; swap cell+ ! ; immediate : sizeof ' >body @ state @ if postpone literal then ; immediate : offsetof ' >body cell+ @ state @ if postpone literal then ; immediate : ptr 1 cells member: ; : int 1 cells member: ; \ String structure structure: string ptr .addr int .len constructor: 0 over .addr ! 0 swap .len ! ;constructor ;structure \ Module options linked list structure: module int module.flag sizeof string member: module.name sizeof string member: module.loadname sizeof string member: module.type sizeof string member: module.hash sizeof string member: module.args sizeof string member: module.largs sizeof string member: module.beforeload sizeof string member: module.afterload sizeof string member: module.loaderror ptr module.next ;structure \ Internal loader structures (preloaded_file, kernel_module, file_metadata) \ must be in sync with the C struct in sys/boot/common/bootstrap.h structure: preloaded_file ptr pf.name ptr pf.type ptr pf.args ptr pf.metadata \ file_metadata int pf.loader int pf.addr int pf.size ptr pf.modules \ kernel_module ptr pf.next \ preloaded_file ;structure structure: kernel_module ptr km.name ptr km.args ptr km.fp \ preloaded_file ptr km.next \ kernel_module ;structure structure: file_metadata int md.size 2 member: md.type \ this is not ANS Forth compatible (XXX) ptr md.next \ file_metadata 0 member: md.data \ variable size ;structure \ end of structures \ Global variables string conf_files create module_options sizeof module.next allot 0 module_options ! create last_module_option sizeof module.next allot 0 last_module_option ! 0 value verbose? \ Support string functions : strdup { addr len -- addr' len' } len allocate if ENOMEM throw then addr over len move len ; : strcat { addr len addr' len' -- addr len+len' } addr' addr len + len' move addr len len' + ; : strchr { addr len c -- addr' len' } begin len while addr c@ c = if addr len exit then addr 1 + to addr len 1 - to len repeat 0 0 ; : strspn { addr len addr1 len1 | paddr plen -- addr' len' } begin len while addr1 to paddr len1 to plen begin plen while addr c@ paddr c@ = if addr len exit then paddr 1+ to paddr plen 1- to plen repeat addr 1 + to addr len 1 - to len repeat 0 0 ; : s' \ same as s", allows " in the string [char] ' parse state @ if postpone sliteral then ; immediate : 2>r postpone >r postpone >r ; immediate : 2r> postpone r> postpone r> ; immediate : 2r@ postpone 2r> postpone 2dup postpone 2>r ; immediate \ Number to string : n2s ( n -- c-addr/u ) s>d <# #s #> ; \ String to number : s2n ( c-addr/u1 -- u2 | -1 ) ?number 0= if -1 then ; \ Test if an environment variable is set : getenv? getenv -1 = if false else drop true then ; \ Fetch a number from an environment variable, or a default if not set or does \ not parse (s2n returns -1). : getenvn ( n1 c-addr/u -- n1 | n2 ) getenv dup -1 = if \ environment variable not set drop ( n1 -1 -- n1 ) else s2n ( n1 c-addr/u1 -- n1 n2 ) dup -1 = if \ parse failed drop ( n1 n2 -- n1 ) else nip ( n1 n2 -- n2 ) then then ; \ execute xt for each device listed in console variable. \ this allows us to have device specific output for logos, menu frames etc : console-iterate { xt | caddr clen taddr tlen -- } \ get current console and save it s" console" getenv ['] strdup catch if 2drop exit then to clen to caddr clen to tlen caddr to taddr begin tlen while taddr tlen s" , " strspn \ we need to handle 3 cases for addr len pairs on stack: \ addr len are 0 0 - there was no comma nor space \ addr len are x 0 - the first char is either comma or space \ addr len are x y. 2dup + 0= if \ there was no comma nor space. 2drop taddr tlen s" console" setenv xt execute 0 to tlen else dup 0= if 2drop else dup ( taddr' tlen' tlen' ) tlen swap - dup 0= if \ sequence of comma and space? drop else taddr swap s" console" setenv xt execute then to tlen to taddr then then tlen 0> if \ step over separator tlen 1- to tlen taddr 1+ to taddr then repeat caddr clen s" console" setenv \ restore console setup caddr free drop ; \ Test if booted in an EFI environment : efi? ( -- flag ) s" efi-version" getenv? ; \ determine if a word appears in a string, case-insensitive : contains? ( addr1 len1 addr2 len2 -- 0 | -1 ) 2 pick 0= if 2drop 2drop true exit then dup 0= if 2drop 2drop false exit then begin begin swap dup c@ dup 32 = over 9 = or over 10 = or over 13 = or over 44 = or swap drop while 1+ swap 1- repeat swap 2 pick 1- over < while 2over 2over drop over compare-insensitive 0= if 2 pick over = if 2drop 2drop true exit then 2 pick tuck - -rot + swap over c@ dup 32 = over 9 = or over 10 = or over 13 = or over 44 = or swap drop if 2drop 2drop true exit then then begin swap dup c@ dup 32 = over 9 = or over 10 = or over 13 = or over 44 = or swap drop if false else true then 2 pick 0> and while 1+ swap 1- repeat swap repeat 2drop 2drop false ; : boot_serial? ( -- 0 | -1 ) s" console" getenv dup -1 <> if 2dup s" ttya" 2swap contains? ( addr len f ) -rot 2dup ( f addr len addr len ) s" ttyb" 2swap contains? ( f addr len f ) -rot 2dup ( f f addr len addr len ) s" ttyc" 2swap contains? ( f f addr len f ) -rot ( f f f addr len ) s" ttyd" 2swap contains? ( f f addr len f ) or or or else drop false then s" boot_serial" getenv dup -1 <> if swap drop 0> else drop false then or \ console contains tty ( or ) boot_serial s" boot_multicons" getenv dup -1 <> if swap drop 0> else drop false then or \ previous boolean ( or ) boot_multicons ; : framebuffer? ( -- t ) s" console" getenv s" text" compare 0<> if FALSE exit then s" screen-width" getenv? ; \ Private definitions vocabulary support-functions only forth also support-functions definitions \ Some control characters constants 7 constant bell 8 constant backspace 9 constant tab 10 constant lf 13 constant \ Read buffer size 80 constant read_buffer_size \ Standard suffixes : load_module_suffix s" _load" ; : module_loadname_suffix s" _name" ; : module_type_suffix s" _type" ; : module_hash_suffix s" _hash" ; : module_args_suffix s" _flags" ; : module_beforeload_suffix s" _before" ; : module_afterload_suffix s" _after" ; : module_loaderror_suffix s" _error" ; \ Support operators : >= < 0= ; : <= > 0= ; \ Assorted support functions : free-memory free if EFREE throw then ; : strget { var -- addr len } var .addr @ var .len @ ; \ assign addr len to variable. : strset { addr len var -- } addr var .addr ! len var .len ! ; \ free memory and reset fields : strfree { var -- } var .addr @ ?dup if free-memory 0 0 var strset then ; \ free old content, make a copy of the string and assign to variable : string= { addr len var -- } var strfree addr len strdup var strset ; : strtype ( str -- ) strget type ; \ assign a reference to what is on the stack : strref { addr len var -- addr len } addr var .addr ! len var .len ! addr len ; \ unquote a string : unquote ( addr len -- addr len ) over c@ [char] " = if 2 chars - swap char+ swap then ; \ Assignment data temporary storage string name_buffer string value_buffer \ Line by line file reading functions \ \ exported: \ line_buffer \ end_of_file? \ fd \ read_line \ reset_line_reading vocabulary line-reading also line-reading definitions \ File data temporary storage string read_buffer 0 value read_buffer_ptr \ File's line reading function get-current ( -- wid ) previous definitions string line_buffer 0 value end_of_file? variable fd >search ( wid -- ) definitions : skip_newlines begin read_buffer .len @ read_buffer_ptr > while read_buffer .addr @ read_buffer_ptr + c@ lf = if read_buffer_ptr char+ to read_buffer_ptr else exit then repeat ; : scan_buffer ( -- addr len ) read_buffer_ptr >r begin read_buffer .len @ r@ > while read_buffer .addr @ r@ + c@ lf = if read_buffer .addr @ read_buffer_ptr + ( -- addr ) r@ read_buffer_ptr - ( -- len ) r> to read_buffer_ptr exit then r> char+ >r repeat read_buffer .addr @ read_buffer_ptr + ( -- addr ) r@ read_buffer_ptr - ( -- len ) r> to read_buffer_ptr ; : line_buffer_resize ( len -- len ) dup 0= if exit then >r line_buffer .len @ if line_buffer .addr @ line_buffer .len @ r@ + resize if ENOMEM throw then else r@ allocate if ENOMEM throw then then line_buffer .addr ! r> ; : append_to_line_buffer ( addr len -- ) dup 0= if 2drop exit then line_buffer strget 2swap strcat line_buffer .len ! drop ; : read_from_buffer scan_buffer ( -- addr len ) line_buffer_resize ( len -- len ) append_to_line_buffer ( addr len -- ) ; : refill_required? read_buffer .len @ read_buffer_ptr = end_of_file? 0= and ; : refill_buffer 0 to read_buffer_ptr read_buffer .addr @ 0= if read_buffer_size allocate if ENOMEM throw then read_buffer .addr ! then fd @ read_buffer .addr @ read_buffer_size fread dup -1 = if EREAD throw then dup 0= if true to end_of_file? then read_buffer .len ! ; get-current ( -- wid ) previous definitions >search ( wid -- ) : reset_line_reading 0 to read_buffer_ptr ; : read_line line_buffer strfree skip_newlines begin read_from_buffer refill_required? while refill_buffer repeat ; only forth also support-functions definitions \ Conf file line parser: \ ::= '='[] | \ [] \ ::= {||'_'|'-'|'/'} \ ::= {||'_'|'-'|','} \ ::= '"'{|'\'}'"' | \ ::= ASCII 32 to 126, except '\' and '"' \ ::= '#'{} \ \ bootenv line parser: \ ::= setprop[] | \ [] \ \ exported: \ line_pointer \ process_conf \ process_conf 0 value line_pointer vocabulary file-processing also file-processing definitions \ parser functions \ \ exported: \ get_assignment \ get_prop vocabulary parser also parser definitions 0 value parsing_function 0 value end_of_line : end_of_line? line_pointer end_of_line = ; \ classifiers for various character classes in the input line : letter? line_pointer c@ >r r@ [char] A >= r@ [char] Z <= and r@ [char] a >= r> [char] z <= and or ; : digit? line_pointer c@ >r r@ [char] - = r@ [char] 0 >= r> [char] 9 <= and or ; : "quote? line_pointer c@ [char] " = ; : 'quote? line_pointer c@ [char] ' = ; : assignment_sign? line_pointer c@ [char] = = ; : comment? line_pointer c@ [char] # = ; : space? line_pointer c@ bl = line_pointer c@ tab = or ; : backslash? line_pointer c@ [char] \ = ; : underscore? line_pointer c@ [char] _ = ; : dot? line_pointer c@ [char] . = ; : dash? line_pointer c@ [char] - = ; : comma? line_pointer c@ [char] , = ; : at? line_pointer c@ [char] @ = ; : slash? line_pointer c@ [char] / = ; : colon? line_pointer c@ [char] : = ; \ manipulation of input line : skip_character line_pointer char+ to line_pointer ; : skip_to_end_of_line end_of_line to line_pointer ; : eat_space begin end_of_line? if 0 else space? then while skip_character repeat ; : parse_name ( -- addr len ) line_pointer begin end_of_line? if 0 else letter? digit? underscore? dot? dash? comma? slash? or or or or or or then while skip_character repeat line_pointer over - strdup ; : parse_value ( -- addr len ) line_pointer begin end_of_line? if 0 else letter? digit? underscore? dot? comma? dash? at? slash? colon? or or or or or or or or then while skip_character repeat line_pointer over - strdup ; : remove_backslashes { addr len | addr' len' -- addr' len' } len allocate if ENOMEM throw then to addr' addr >r begin addr c@ [char] \ <> if addr c@ addr' len' + c! len' char+ to len' then addr char+ to addr r@ len + addr = until r> drop addr' len' ; : parse_quote ( xt -- addr len ) >r ( R: xt ) line_pointer skip_character end_of_line? if ESYNTAX throw then begin r@ execute 0= while backslash? if skip_character end_of_line? if ESYNTAX throw then then skip_character end_of_line? if ESYNTAX throw then repeat r> drop skip_character line_pointer over - remove_backslashes ; : read_name parse_name ( -- addr len ) name_buffer strset ; : read_value "quote? if ['] "quote? parse_quote ( -- addr len ) else 'quote? if ['] 'quote? parse_quote ( -- addr len ) else parse_value ( -- addr len ) then then value_buffer strset ; : comment skip_to_end_of_line ; : white_space_4 eat_space comment? if ['] comment to parsing_function exit then end_of_line? 0= if ESYNTAX throw then ; : variable_value read_value ['] white_space_4 to parsing_function ; : white_space_3 eat_space slash? letter? digit? "quote? 'quote? or or or or if ['] variable_value to parsing_function exit then ESYNTAX throw ; : assignment_sign skip_character ['] white_space_3 to parsing_function ; : white_space_2 eat_space assignment_sign? if ['] assignment_sign to parsing_function exit then ESYNTAX throw ; : variable_name read_name ['] white_space_2 to parsing_function ; : white_space_1 eat_space letter? if ['] variable_name to parsing_function exit then comment? if ['] comment to parsing_function exit then end_of_line? 0= if ESYNTAX throw then ; : prop_name eat_space read_name ['] white_space_3 to parsing_function ; : get_prop_cmd eat_space s" setprop" line_pointer over compare 0= if line_pointer 7 + to line_pointer ['] prop_name to parsing_function exit then comment? if ['] comment to parsing_function exit then end_of_line? 0= if ESYNTAX throw then ; get-current ( -- wid ) previous definitions >search ( wid -- ) : get_assignment line_buffer strget + to end_of_line line_buffer .addr @ to line_pointer ['] white_space_1 to parsing_function begin end_of_line? 0= while parsing_function execute repeat parsing_function ['] comment = parsing_function ['] white_space_1 = parsing_function ['] white_space_4 = or or 0= if ESYNTAX throw then ; : get_prop line_buffer strget + to end_of_line line_buffer .addr @ to line_pointer ['] get_prop_cmd to parsing_function begin end_of_line? 0= while parsing_function execute repeat parsing_function ['] comment = parsing_function ['] get_prop_cmd = parsing_function ['] white_space_4 = or or 0= if ESYNTAX throw then ; only forth also support-functions also file-processing definitions \ Process line : assignment_type? ( addr len -- flag ) name_buffer strget compare 0= ; : suffix_type? ( addr len -- flag ) name_buffer .len @ over <= if 2drop false exit then name_buffer .len @ over - name_buffer .addr @ + over compare 0= ; : loader_conf_files? s" loader_conf_files" assignment_type? ; : verbose_flag? s" verbose_loading" assignment_type? ; : execute? s" exec" assignment_type? ; : module_load? load_module_suffix suffix_type? ; : module_loadname? module_loadname_suffix suffix_type? ; : module_type? module_type_suffix suffix_type? ; : module_hash? module_hash_suffix suffix_type? ; : module_args? module_args_suffix suffix_type? ; : module_beforeload? module_beforeload_suffix suffix_type? ; : module_afterload? module_afterload_suffix suffix_type? ; : module_loaderror? module_loaderror_suffix suffix_type? ; \ build a 'set' statement and execute it : set_environment_variable name_buffer .len @ value_buffer .len @ + 5 chars + \ size of result string allocate if ENOMEM throw then dup 0 \ start with an empty string and append the pieces s" set " strcat name_buffer strget strcat s" =" strcat value_buffer strget strcat ['] evaluate catch if 2drop free drop ESETERROR throw else free-memory then ; : set_conf_files set_environment_variable s" loader_conf_files" getenv conf_files string= ; : append_to_module_options_list ( addr -- ) module_options @ 0= if dup module_options ! last_module_option ! else dup last_module_option @ module.next ! last_module_option ! then ; : set_module_name { addr -- } \ check leaks name_buffer strget addr module.name string= ; : yes_value? value_buffer strget unquote s" yes" compare-insensitive 0= ; : find_module_option ( -- addr | 0 ) \ return ptr to entry matching name_buffer module_options @ begin dup while dup module.name strget name_buffer strget compare 0= if exit then module.next @ repeat ; : new_module_option ( -- addr ) sizeof module allocate if ENOMEM throw then dup sizeof module erase dup append_to_module_options_list dup set_module_name ; : get_module_option ( -- addr ) find_module_option ?dup 0= if new_module_option then ; : set_module_flag name_buffer .len @ load_module_suffix nip - name_buffer .len ! yes_value? get_module_option module.flag ! ; : set_module_args name_buffer .len @ module_args_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.args string= ; : set_module_loadname name_buffer .len @ module_loadname_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.loadname string= ; : set_module_type name_buffer .len @ module_type_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.type string= ; : set_module_hash name_buffer .len @ module_hash_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.hash string= ; : set_module_beforeload name_buffer .len @ module_beforeload_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.beforeload string= ; : set_module_afterload name_buffer .len @ module_afterload_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.afterload string= ; : set_module_loaderror name_buffer .len @ module_loaderror_suffix nip - name_buffer .len ! value_buffer strget unquote get_module_option module.loaderror string= ; : set_verbose yes_value? to verbose? ; : execute_command value_buffer strget unquote ['] evaluate catch if EEXEC throw then ; : process_assignment name_buffer .len @ 0= if exit then loader_conf_files? if set_conf_files exit then verbose_flag? if set_verbose exit then execute? if execute_command exit then module_load? if set_module_flag exit then module_loadname? if set_module_loadname exit then module_type? if set_module_type exit then module_hash? if set_module_hash exit then module_args? if set_module_args exit then module_beforeload? if set_module_beforeload exit then module_afterload? if set_module_afterload exit then module_loaderror? if set_module_loaderror exit then set_environment_variable ; \ free_buffer ( -- ) \ \ Free some pointers if needed. The code then tests for errors \ in freeing, and throws an exception if needed. If a pointer is \ not allocated, it's value (0) is used as flag. : free_buffers name_buffer strfree value_buffer strfree ; \ Higher level file processing get-current ( -- wid ) previous definitions >search ( wid -- ) : process_bootenv begin end_of_file? 0= while free_buffers read_line get_prop ['] process_assignment catch ['] free_buffers catch swap throw throw repeat ; : process_conf begin end_of_file? 0= while free_buffers read_line get_assignment ['] process_assignment catch ['] free_buffers catch swap throw throw repeat ; : peek_file ( addr len -- ) 0 to end_of_file? reset_line_reading O_RDONLY fopen fd ! fd @ -1 = if EOPEN throw then free_buffers read_line get_assignment ['] process_assignment catch ['] free_buffers catch fd @ fclose swap throw throw ; only forth also support-functions definitions \ Interface to loading conf files : load_conf ( addr len -- ) 0 to end_of_file? reset_line_reading O_RDONLY fopen fd ! fd @ -1 = if EOPEN throw then ['] process_conf catch fd @ fclose throw ; : print_line line_buffer strtype cr ; : print_syntax_error line_buffer strtype cr line_buffer .addr @ begin line_pointer over <> while bl emit char+ repeat drop ." ^" cr ; : load_bootenv ( addr len -- ) 0 to end_of_file? reset_line_reading O_RDONLY fopen fd ! fd @ -1 = if EOPEN throw then ['] process_bootenv catch fd @ fclose throw ; \ Debugging support functions only forth definitions also support-functions : test-file ['] load_conf catch dup . ESYNTAX = if cr print_syntax_error then ; \ find a module name, leave addr on the stack (0 if not found) : find-module ( -- ptr | 0 ) bl parse ( addr len ) dup 0= if 2drop then ( parse did not find argument, try stack ) depth 2 < if 0 exit then module_options @ >r ( store current pointer ) begin r@ while 2dup ( addr len addr len ) r@ module.name strget compare 0= if drop drop r> exit then ( found it ) r> module.next @ >r repeat type ." was not found" cr r> ; : show-nonempty ( addr len mod -- ) strget dup verbose? or if 2swap type type cr else drop drop drop drop then ; : show-one-module { addr -- addr } ." Name: " addr module.name strtype cr s" Path: " addr module.loadname show-nonempty s" Type: " addr module.type show-nonempty s" Hash: " addr module.hash show-nonempty s" Flags: " addr module.args show-nonempty s" Before load: " addr module.beforeload show-nonempty s" After load: " addr module.afterload show-nonempty s" Error: " addr module.loaderror show-nonempty ." Status: " addr module.flag @ if ." Load" else ." Don't load" then cr cr addr ; : show-module-options module_options @ begin ?dup while show-one-module module.next @ repeat ; : free-one-module { addr -- addr } addr module.name strfree addr module.loadname strfree addr module.type strfree addr module.hash strfree addr module.args strfree addr module.largs strfree addr module.beforeload strfree addr module.afterload strfree addr module.loaderror strfree addr ; : free-module-options module_options @ begin ?dup while free-one-module dup module.next @ swap free-memory repeat 0 module_options ! 0 last_module_option ! ; only forth also support-functions definitions \ Variables used for processing multiple conf files string current_file_name_ref \ used to print the file name \ Indicates if any conf file was successfully read 0 value any_conf_read? \ loader_conf_files processing support functions \ true if string in addr1 is smaller than in addr2 : compar ( addr1 addr2 -- flag ) swap ( addr2 addr1 ) dup cell+ ( addr2 addr1 addr ) swap @ ( addr2 addr len ) rot ( addr len addr2 ) dup cell+ ( addr len addr2 addr' ) swap @ ( addr len addr' len' ) compare -1 = ; \ insertion sort algorithm. we dont expect large amounts of data to be \ sorted, so insert should be ok. compar needs to implement < operator. : insert ( start end -- start ) dup @ >r ( r: v ) \ v = a[i] begin 2dup < \ j>0 while r@ over cell- @ compar \ a[j-1] > v while cell- \ j-- dup @ over cell+ ! \ a[j] = a[j-1] repeat then r> swap ! \ a[j] = v ; : sort ( array len -- ) 1 ?do dup i cells + insert loop drop ; : opendir s" /boot/conf.d" fopendir if fd ! else EOPEN throw then ; : readdir ( addr len flag | flag ) fd @ freaddir ; : closedir fd @ fclosedir ; : entries ( -- n ) \ count directory entries ['] opendir catch ( n array ) throw 0 ( i ) begin \ count the entries readdir ( i addr len flag | i flag ) dup -1 = if -ROT 2drop swap 1+ swap then 0= until closedir ; \ built-in prefix directory name; it must end with /, so we don't \ need to check and insert it. : make_cstring ( addr len -- addr' ) dup ( addr len len ) s" /boot/conf.d/" ( addr len len addr' len' ) rot ( addr len addr' len' len ) over + ( addr len addr' len' total ) \ space for prefix+str dup cell+ 1+ \ 1+ for '\0' allocate if -1 abort" malloc failed" then ( addr len addr' len' total taddr ) dup rot ( addr len addr' len' taddr taddr total ) swap ! ( addr len addr' len' taddr ) \ store length dup >r \ save reference cell+ \ point to string area 2dup 2>r ( addr len addr' len' taddr' ) ( R: taddr len' taddr' ) swap move ( addr len ) 2r> + ( addr len taddr' ) ( R: taddr ) swap 1+ move \ 1+ for '\0' r> ( taddr ) ; : scan_conf_dir ( -- addr len -1 | 0 ) s" currdev" getenv -1 <> if 3 \ we only need first 3 chars s" net" compare 0= if s" boot.tftproot.server" getenv? if 0 exit \ readdir does not work on tftp then then then ['] entries catch if 0 exit then dup 0= if exit then \ nothing to do dup cells allocate ( n array flag ) \ allocate array if 0 exit then ['] opendir catch if ( n array ) free drop drop 0 exit then over 0 do readdir ( n array addr len flag | n array flag ) 0= if -1 abort" unexpected readdir error" then \ shouldnt happen ( n array addr len ) \ we have relative name, make it absolute and convert to counted string make_cstring ( n array addr ) over I cells + ! ( n array ) loop closedir 2dup swap sort \ we have now array of strings with directory entry names. \ calculate size of concatenated string over 0 swap 0 do ( n array 0 ) over I cells + @ ( n array total array[I] ) @ + 1+ ( n array total' ) loop dup allocate if drop free 2drop 0 exit then ( n array len addr ) \ now concatenate all entries. 2swap ( len addr n array ) over 0 swap 0 do ( len addr n array 0 ) over I cells + @ ( len addr n array total array[I] ) dup @ swap cell+ ( len addr n array total len addr' ) over ( len addr n array total len addr' len ) 6 pick ( len addr n array total len addr' len addr ) 4 pick + ( len addr n array total len addr' len addr+total ) swap move + ( len addr n array total+len ) 3 pick ( len addr n array total addr ) over + bl swap c! 1+ ( len addr n array total ) over I cells + @ free drop \ free array[I] loop drop free drop drop ( len addr ) swap ( addr len ) -1 ; : get_conf_files ( -- addr len ) \ put addr/len on stack, reset var \ ." -- starting on <" conf_files strtype ." >" cr \ debugging scan_conf_dir if \ concatenate with conf_files ( addr len ) dup conf_files .len @ + 2 + allocate abort" out of memory" ( addr len addr' ) dup conf_files strget ( addr len addr' caddr clen ) rot swap move ( addr len addr' ) \ add space dup conf_files .len @ + ( addr len addr' addr'+clen ) dup bl swap c! 1+ ( addr len addr' addr'' ) 3 pick swap ( addr len addr' addr addr'' ) 3 pick move ( addr len addr' ) rot ( len addr' addr ) free drop swap ( addr' len ) conf_files .len @ + 1+ ( addr len ) conf_files strfree else conf_files strget 0 0 conf_files strset then ; : skip_leading_spaces { addr len pos -- addr len pos' } begin pos len = if 0 else addr pos + c@ bl = then while pos char+ to pos repeat addr len pos ; \ return the file name at pos, or free the string if nothing left : get_file_name { addr len pos -- addr len pos' addr' len' || 0 } pos len = if addr free abort" Fatal error freeing memory" 0 exit then pos >r begin \ stay in the loop until have chars and they are not blank pos len = if 0 else addr pos + c@ bl <> then while pos char+ to pos repeat addr len pos addr r@ + pos r> - ; : get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 ) skip_leading_spaces get_file_name ; : print_current_file current_file_name_ref strtype ; : process_conf_errors dup 0= if true to any_conf_read? drop exit then >r 2drop r> dup ESYNTAX = if ." Warning: syntax error on file " print_current_file cr print_syntax_error drop exit then dup ESETERROR = if ." Warning: bad definition on file " print_current_file cr print_line drop exit then dup EREAD = if ." Warning: error reading file " print_current_file cr drop exit then dup EOPEN = if verbose? if ." Warning: unable to open file " print_current_file cr then drop exit then dup EFREE = abort" Fatal error freeing memory" dup ENOMEM = abort" Out of memory" throw \ Unknown error -- pass ahead ; \ Process loader_conf_files recursively \ Interface to loader_conf_files processing : include_bootenv s" /boot/solaris/bootenv.rc" ['] load_bootenv catch dup 0= if drop exit then >r 2drop r> dup ESYNTAX = if ." Warning: syntax error on /boot/solaris/bootenv.rc" cr drop exit then dup EREAD = if ." Warning: error reading /boot/solaris/bootenv.rc" cr drop exit then dup EOPEN = if verbose? if ." Warning: unable to open /boot/solaris/bootenv.rc" cr then drop exit then dup EFREE = abort" Fatal error freeing memory" dup ENOMEM = abort" Out of memory" throw \ Unknown error -- pass ahead ; : include_transient s" /boot/transient.conf" ['] load_conf catch dup 0= if drop exit then \ no error >r 2drop r> dup ESYNTAX = if ." Warning: syntax error on file /boot/transient.conf" cr drop exit then dup ESETERROR = if ." Warning: bad definition on file /boot/transient.conf" cr drop exit then dup EREAD = if ." Warning: error reading file /boot/transient.conf" cr drop exit then dup EOPEN = if verbose? if ." Warning: unable to open file /boot/transient.conf" cr then drop exit then dup EFREE = abort" Fatal error freeing memory" dup ENOMEM = abort" Out of memory" throw \ Unknown error -- pass ahead ; : include_conf_files get_conf_files 0 ( addr len offset ) begin get_next_file ?dup ( addr len 1 | 0 ) while current_file_name_ref strref ['] load_conf catch process_conf_errors conf_files .addr @ if recurse then repeat ; \ Module loading functions \ concat two strings by allocating space : concat { a1 l1 a2 l2 -- a' l' } l1 l2 + allocate if ENOMEM throw then 0 a1 l1 strcat a2 l2 strcat ; \ build module argument list as: "hash= name= module.args" \ if type is hash, name= will have module name without .hash suffix \ will free old largs and set new. : build_largs { addr -- addr } addr module.largs strfree addr module.hash .len @ if ( set hash= ) s" hash=" addr module.hash strget concat addr module.largs strset \ largs = "hash=" + module.hash then addr module.type strget s" hash" compare 0= if ( module.type == "hash" ) addr module.largs strget s" name=" concat addr module.loadname .len @ if ( module.loadname != NULL ) addr module.loadname strget concat else addr module.name strget concat then addr module.largs strfree addr module.largs strset \ largs = largs + name \ last thing to do is to strip off ".hash" suffix addr module.largs strget [char] . strchr dup if ( strchr module.largs '.' ) s" .hash" compare 0= if ( it is ".hash" ) addr module.largs .len @ 5 - addr module.largs .len ! then else 2drop then then \ and now add up the module.args addr module.largs strget s" " concat addr module.args strget concat addr module.largs strfree addr module.largs strset addr ; : load_parameters { addr -- addr addrN lenN ... addr1 len1 N } addr build_largs addr module.largs strget addr module.loadname .len @ if addr module.loadname strget else addr module.name strget then addr module.type .len @ if addr module.type strget s" -t " 4 ( -t type name flags ) else 2 ( name flags ) then ; : before_load ( addr -- addr ) dup module.beforeload .len @ if dup module.beforeload strget ['] evaluate catch if EBEFORELOAD throw then then ; : after_load ( addr -- addr ) dup module.afterload .len @ if dup module.afterload strget ['] evaluate catch if EAFTERLOAD throw then then ; : load_error ( addr -- addr ) dup module.loaderror .len @ if dup module.loaderror strget evaluate \ This we do not intercept so it can throw errors then ; : pre_load_message ( addr -- addr ) verbose? if dup module.name strtype ." ..." then ; : load_error_message verbose? if ." failed!" cr then ; : load_successful_message verbose? if ." ok" cr then ; : load_module load_parameters load ; : process_module ( addr -- addr ) pre_load_message before_load begin ['] load_module catch if dup module.loaderror .len @ if load_error \ Command should return a flag! else load_error_message true \ Do not retry then else after_load load_successful_message true \ Successful, do not retry then until ; : process_module_errors ( addr ior -- ) dup EBEFORELOAD = if drop ." Module " dup module.name strtype dup module.loadname .len @ if ." (" dup module.loadname strtype ." )" then cr ." Error executing " dup module.beforeload strtype cr \ XXX there was a typo here abort then dup EAFTERLOAD = if drop ." Module " dup module.name .addr @ over module.name .len @ type dup module.loadname .len @ if ." (" dup module.loadname strtype ." )" then cr ." Error executing " dup module.afterload strtype cr abort then throw \ Don't know what it is all about -- pass ahead ; \ Module loading interface \ scan the list of modules, load enabled ones. : load_modules ( -- ) ( throws: abort & user-defined ) module_options @ ( list_head ) begin ?dup while dup module.flag @ if ['] process_module catch process_module_errors then module.next @ repeat ; \ h00h00 magic used to try loading either a kernel with a given name, \ or a kernel with the default name in a directory of a given name \ (the pain!) : bootpath s" /platform/" ; : modulepath s" module_path" ; \ Functions used to save and restore module_path's value. : saveenv ( addr len | -1 -- addr' len | 0 -1 ) dup -1 = if 0 swap exit then strdup ; : freeenv ( addr len | 0 -1 ) -1 = if drop else free abort" Freeing error" then ; : restoreenv ( addr len | 0 -1 -- ) dup -1 = if ( it wasn't set ) 2drop modulepath unsetenv else over >r modulepath setenv r> free abort" Freeing error" then ; : clip_args \ Drop second string if only one argument is passed 1 = if 2swap 2drop 1 else 2 then ; also builtins \ Parse filename from a semicolon-separated list : parse-; ( addr len -- addr' len-x addr x ) over 0 2swap ( addr 0 addr len ) begin dup 0 <> ( addr 0 addr len ) while over c@ [char] ; <> ( addr 0 addr len flag ) while 1- swap 1+ swap 2swap 1+ 2swap repeat then dup 0 <> if 1- swap 1+ swap then 2swap ; \ Try loading one of multiple kernels specified : try_multiple_kernels ( addr len addr' len' args -- flag ) >r begin parse-; 2>r 2over 2r> r@ clip_args s" DEBUG" getenv? if s" echo Module_path: ${module_path}" evaluate ." Kernel : " >r 2dup type r> cr dup 2 = if ." Flags : " >r 2over type r> cr then then \ if it's xen, the xen kernel is loaded, unix needs to be loaded as module s" xen_kernel" getenv -1 <> if drop \ drop address from getenv >r \ argument count to R s" kernel" s" -t " \ push 2 strings into the stack r> 2 + \ increment argument count then 1 ['] load catch dup if ( addr0 len0 addr1 len1 ... args 1 error ) >r \ error code to R drop \ drop 1 0 do 2drop loop \ drop addr len pairs r> \ set flag for while then while dup 0= until 1 >r \ Failure else 0 >r \ Success then 2drop 2drop r> r> drop ; \ Try to load a kernel; the kernel name is taken from one of \ the following lists, as ordered: \ \ 1. The "bootfile" environment variable \ 2. The "kernel" environment variable \ \ Flags are passed, if available. If not, dummy values must be given. \ \ The kernel gets loaded from the current module_path. : load_a_kernel ( flags len 1 | x x 0 -- flag ) local args 2local flags 0 0 2local kernel end-locals \ Check if a default kernel name exists at all, exits if not s" bootfile" getenv dup -1 <> if to kernel flags kernel args 1+ try_multiple_kernels dup 0= if exit then then drop s" kernel" getenv dup -1 <> if to kernel else drop 1 exit \ Failure then \ Try all default kernel names flags kernel args 1+ try_multiple_kernels ; \ Try to load a kernel; the kernel name is taken from one of \ the following lists, as ordered: \ \ 1. The "bootfile" environment variable \ 2. The "kernel" environment variable \ \ Flags are passed, if provided. \ \ The kernel will be loaded from a directory computed from the \ path given. Two directories will be tried in the following order: \ \ 1. /boot/path \ 2. path \ \ The module_path variable is overridden if load is successful, by \ prepending the successful path. : load_from_directory ( path len 1 | flags len' path len 2 -- flag ) local args 2local path args 1 = if 0 0 then 2local flags 0 0 2local oldmodulepath \ like a string 0 0 2local newmodulepath \ like a string end-locals \ Set the environment variable module_path, and try loading \ the kernel again. modulepath getenv saveenv to oldmodulepath \ Try prepending /boot/ first bootpath nip path nip + \ total length oldmodulepath nip dup -1 = if drop else 1+ + \ add oldpath -- XXX why the 1+ ? then allocate if ( out of memory ) 1 exit then \ XXX throw ? 0 bootpath strcat path strcat 2dup to newmodulepath modulepath setenv \ Try all default kernel names flags args 1- load_a_kernel 0= if ( success ) oldmodulepath nip -1 <> if newmodulepath s" ;" strcat oldmodulepath strcat modulepath setenv newmodulepath drop free-memory oldmodulepath drop free-memory then 0 exit then \ Well, try without the prepended /boot/ path newmodulepath drop swap move newmodulepath drop path nip 2dup to newmodulepath modulepath setenv \ Try all default kernel names flags args 1- load_a_kernel if ( failed once more ) oldmodulepath restoreenv newmodulepath drop free-memory 1 else oldmodulepath nip -1 <> if newmodulepath s" ;" strcat oldmodulepath strcat modulepath setenv newmodulepath drop free-memory oldmodulepath drop free-memory then 0 then ; \ Try to load a kernel; the kernel name is taken from one of \ the following lists, as ordered: \ \ 1. The "bootfile" environment variable \ 2. The "kernel" environment variable \ 3. The "path" argument \ \ Flags are passed, if provided. \ \ The kernel will be loaded from a directory computed from the \ path given. Two directories will be tried in the following order: \ \ 1. /boot/path \ 2. path \ \ Unless "path" is meant to be kernel name itself. In that case, it \ will first be tried as a full path, and, next, search on the \ directories pointed by module_path. \ \ The module_path variable is overridden if load is successful, by \ prepending the successful path. : load_directory_or_file ( path len 1 | flags len' path len 2 -- flag ) local args 2local path args 1 = if 0 0 then 2local flags end-locals \ First, assume path is an absolute path to a directory flags path args clip_args load_from_directory dup 0= if exit else drop then \ Next, assume path points to the kernel flags path args try_multiple_kernels ; : initialize ( addr len -- ) strdup conf_files strset ; : boot-args ( -- addr len 1 | 0 ) s" boot-args" getenv dup -1 = if drop 0 else 1 then ; : standard_kernel_search ( flags 1 | 0 -- flag ) local args args 0= if 0 0 then 2local flags s" kernel" getenv dup -1 = if 0 swap then 2local path end-locals path nip -1 = if ( there isn't a "kernel" environment variable ) flags args load_a_kernel else flags path args 1+ clip_args load_directory_or_file then ; : load_kernel ( -- ) ( throws: abort ) s" xen_kernel" getenv -1 = if boot-args standard_kernel_search abort" Unable to load a kernel!" exit then drop \ we have loaded the xen kernel, load unix as module s" bootfile" getenv dup -1 <> if s" kernel" s" -t " 3 1 load then abort" Unable to load a kernel!" ; : load_xen ( -- ) s" xen_kernel" getenv dup -1 <> if 1 1 load ( c-addr/u flag N -- flag ) else drop 0 ( -1 -- flag ) then ; : load_xen_throw ( -- ) ( throws: abort ) load_xen abort" Unable to load Xen!" ; : set_defaultoptions ( -- ) s" boot-args" getenv dup -1 = if drop else s" temp_options" setenv then ; \ pick the i-th argument, i starts at 0 : argv[] ( aN uN ... a1 u1 N i -- aN uN ... a1 u1 N ai+1 ui+1 ) 2dup = if 0 0 exit then \ out of range dup >r 1+ 2* ( skip N and ui ) pick r> 1+ 2* ( skip N and ai ) pick ; : drop_args ( aN uN ... a1 u1 N -- ) 0 ?do 2drop loop ; : argc dup ; : queue_argv ( aN uN ... a1 u1 N a u -- a u aN uN ... a1 u1 N+1 ) >r over 2* 1+ -roll r> over 2* 1+ -roll 1+ ; : unqueue_argv ( aN uN ... a1 u1 N -- aN uN ... a2 u2 N-1 a1 u1 ) 1- -rot ; \ compute the length of the buffer including the spaces between words : strlen(argv) ( aN uN .. a1 u1 N -- aN uN .. a1 u1 N len ) dup 0= if 0 exit then 0 >r \ Size 0 >r \ Index begin argc r@ <> while r@ argv[] nip r> r> rot + 1+ >r 1+ >r repeat r> drop r> ; : concat_argv ( aN uN ... a1 u1 N -- a u ) strlen(argv) allocate if ENOMEM throw then 0 2>r ( save addr 0 on return stack ) begin dup while unqueue_argv ( ... N a1 u1 ) 2r> 2swap ( old a1 u1 ) strcat s" " strcat ( append one space ) \ XXX this gives a trailing space 2>r ( store string on the result stack ) repeat drop_args 2r> ; : set_tempoptions ( addrN lenN ... addr1 len1 N -- addr len 1 | 0 ) \ Save the first argument, if it exists and is not a flag argc if 0 argv[] drop c@ [char] - <> if unqueue_argv 2>r \ Filename 1 >r \ Filename present else 0 >r \ Filename not present then else 0 >r \ Filename not present then \ If there are other arguments, assume they are flags ?dup if concat_argv 2dup s" temp_options" setenv drop free if EFREE throw then else set_defaultoptions then \ Bring back the filename, if one was provided r> if 2r> 1 else 0 then ; : get_arguments ( -- addrN lenN ... addr1 len1 N ) 0 begin \ Get next word on the command line parse-word ?dup while queue_argv repeat drop ( empty string ) ; : load_kernel_and_modules ( args -- flag ) set_tempoptions argc >r s" temp_options" getenv dup -1 <> if queue_argv else drop then load_xen ?dup 0= if ( success ) r> if ( a path was passed ) load_directory_or_file else standard_kernel_search then ?dup 0= if ['] load_modules catch then then ; only forth definitions \ Copyright (c) 2006-2015 Devin Teske \ Copyright 2019 OmniOS Community Edition (OmniOSce) Association. \ All rights reserved. \ \ 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. \ \ 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. marker task-version.4th vocabulary version-processing only forth also version-processing definitions variable versionX variable versionY \ Default $loader_version value if not overridden or using tribute screen : str_loader_version ( -- C-ADDR/U|-1 ) -1 ; \ Initialize text placement to defaults 80 versionX ! \ NOTE: this is the ending column (text is right-justified) 24 versionY ! only forth definitions also version-processing : print_version ( -- ) \ Get the text placement position (if set) s" loader_version_x" getenv dup -1 <> if ?number drop versionX ! -1 then drop s" loader_version_y" getenv dup -1 <> if ?number drop versionY ! -1 then drop \ Default version if none was set s" loader_version" getenv dup -1 = if drop \ Use above default if no logo is requested s" loader_logo" getenv dup -1 = if drop str_loader_version else \ For tributes, do nothing (defer to logo-*.4th) 2dup s" tribute" compare-insensitive 0= if 2drop s" logo" sfind if drop exit \ see logo-tribute.4th else drop str_loader_version then else 2dup s" tributebw" compare-insensitive 0= if 2drop s" logo" sfind if drop exit \ see logo-tributebw.4th else drop str_loader_version then else 2drop str_loader_version then then then then dup -1 = if drop exit \ default version (above) is disabled then \ Right justify the text dup versionX @ swap - versionY @ at-xy \ Print the version (optionally in cyan) loader_color? dup ( c-addr/u -- c-addr/u bool bool ) if 6 fg then -rot type if me then at-bl ; only forth definitions /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * From @(#)ctype.h 8.4 (Berkeley) 1/21/94 * From FreeBSD: src/include/ctype.h,v 1.27 2004/06/23 07:11:39 tjr Exp * $FreeBSD$ */ #ifndef __CTYPE_H_ #define __CTYPE_H_ #include #include #define _CTYPE_A 0x00000100L /* Alpha */ #define _CTYPE_C 0x00000200L /* Control */ #define _CTYPE_D 0x00000400L /* Digit */ #define _CTYPE_G 0x00000800L /* Graph */ #define _CTYPE_L 0x00001000L /* Lower */ #define _CTYPE_P 0x00002000L /* Punct */ #define _CTYPE_S 0x00004000L /* Space */ #define _CTYPE_U 0x00008000L /* Upper */ #define _CTYPE_X 0x00010000L /* X digit */ #define _CTYPE_B 0x00020000L /* Blank */ #define _CTYPE_R 0x00040000L /* Print */ #define _CTYPE_I 0x00080000L /* Ideogram */ #define _CTYPE_T 0x00100000L /* Special */ #define _CTYPE_Q 0x00200000L /* Phonogram */ #define _CTYPE_N 0x00400000L /* Number (superset of digit) */ #define _CTYPE_SW0 0x20000000L /* 0 width character */ #define _CTYPE_SW1 0x40000000L /* 1 width character */ #define _CTYPE_SW2 0x80000000L /* 2 width character */ #define _CTYPE_SW3 0xc0000000L /* 3 width character */ #define _CTYPE_SWM 0xe0000000L /* Mask for screen width data */ #define _CTYPE_SWS 30 /* Bits to shift to get width */ /* See comments in about __ct_rune_t. */ __BEGIN_DECLS unsigned long ___runetype(__ct_rune_t) __pure; __ct_rune_t ___tolower(__ct_rune_t) __pure; __ct_rune_t ___toupper(__ct_rune_t) __pure; __END_DECLS /* * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us * to generate code for extern versions of all our inline functions. */ #ifdef _EXTERNALIZE_CTYPE_INLINES_ #define _USE_CTYPE_INLINE_ #define static #define __inline #endif extern int __mb_sb_limit; /* * Use inline functions if we are allowed to and the compiler supports them. */ #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) #include static __inline int __maskrune(__ct_rune_t _c, unsigned long _f) { return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) : _CurrentRuneLocale->__runetype[_c]) & _f; } static __inline int __sbmaskrune(__ct_rune_t _c, unsigned long _f) { return (_c < 0 || _c >= __mb_sb_limit) ? 0 : _CurrentRuneLocale->__runetype[_c] & _f; } static __inline int __istype(__ct_rune_t _c, unsigned long _f) { return (!!__maskrune(_c, _f)); } static __inline int __sbistype(__ct_rune_t _c, unsigned long _f) { return (!!__sbmaskrune(_c, _f)); } static __inline int __isctype(__ct_rune_t _c, unsigned long _f) { return (_c < 0 || _c >= 128) ? 0 : !!(_DefaultRuneLocale.__runetype[_c] & _f); } static __inline __ct_rune_t __toupper(__ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) : _CurrentRuneLocale->__mapupper[_c]; } static __inline __ct_rune_t __sbtoupper(__ct_rune_t _c) { return (_c < 0 || _c >= __mb_sb_limit) ? _c : _CurrentRuneLocale->__mapupper[_c]; } static __inline __ct_rune_t __tolower(__ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) : _CurrentRuneLocale->__maplower[_c]; } static __inline __ct_rune_t __sbtolower(__ct_rune_t _c) { return (_c < 0 || _c >= __mb_sb_limit) ? _c : _CurrentRuneLocale->__maplower[_c]; } static __inline int __wcwidth(__ct_rune_t _c) { unsigned int _x; if (_c == 0) return (0); _x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R); if ((_x & _CTYPE_SWM) != 0) return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); return ((_x & _CTYPE_R) != 0 ? 1 : -1); } #else /* not using inlines */ __BEGIN_DECLS int __maskrune(__ct_rune_t, unsigned long); int __sbmaskrune(__ct_rune_t, unsigned long); int __istype(__ct_rune_t, unsigned long); int __sbistype(__ct_rune_t, unsigned long); int __isctype(__ct_rune_t, unsigned long); __ct_rune_t __toupper(__ct_rune_t); __ct_rune_t __sbtoupper(__ct_rune_t); __ct_rune_t __tolower(__ct_rune_t); __ct_rune_t __sbtolower(__ct_rune_t); int __wcwidth(__ct_rune_t); __END_DECLS #endif /* using inlines */ #endif /* !__CTYPE_H_ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)a.out.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _AOUT_H_ #define _AOUT_H_ #include #include #include #include #include #define _AOUT_INCLUDE_ #include #endif /* !_AOUT_H_ */ /* * ++Copyright++ 1983, 1993 * - * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ /*% * @(#)inet.h 8.1 (Berkeley) 6/2/93 * $Id: inet.h,v 1.3 2005/04/27 04:56:16 sra Exp $ * $FreeBSD$ */ #ifndef _ARPA_INET_H_ #define _ARPA_INET_H_ /* External definitions for functions in inet(3). */ #include #include /* Required for byteorder(3) functions. */ #include #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 #ifndef _UINT16_T_DECLARED typedef __uint16_t uint16_t; #define _UINT16_T_DECLARED #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _IN_ADDR_T_DECLARED typedef uint32_t in_addr_t; #define _IN_ADDR_T_DECLARED #endif #ifndef _IN_PORT_T_DECLARED typedef uint16_t in_port_t; #define _IN_PORT_T_DECLARED #endif #if __BSD_VISIBLE #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #endif /* * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by * POSIX.1-2001. */ #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif #ifndef _STRUCT_IN_ADDR_DECLARED struct in_addr { in_addr_t s_addr; }; #define _STRUCT_IN_ADDR_DECLARED #endif /* XXX all new diversions!! argh!! */ #if __BSD_VISIBLE #define inet_addr __inet_addr #define inet_aton __inet_aton #define inet_lnaof __inet_lnaof #define inet_makeaddr __inet_makeaddr #define inet_neta __inet_neta #define inet_netof __inet_netof #define inet_network __inet_network #define inet_net_ntop __inet_net_ntop #define inet_net_pton __inet_net_pton #define inet_cidr_ntop __inet_cidr_ntop #define inet_cidr_pton __inet_cidr_pton #define inet_ntoa __inet_ntoa #define inet_ntoa_r __inet_ntoa_r #define inet_pton __inet_pton #define inet_ntop __inet_ntop #define inet_nsap_addr __inet_nsap_addr #define inet_nsap_ntoa __inet_nsap_ntoa #endif /* __BSD_VISIBLE */ __BEGIN_DECLS #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED uint32_t htonl(uint32_t); uint16_t htons(uint16_t); uint32_t ntohl(uint32_t); uint16_t ntohs(uint16_t); #endif in_addr_t inet_addr(const char *); /*const*/ char *inet_ntoa(struct in_addr); const char *inet_ntop(int, const void * __restrict, char * __restrict, socklen_t); int inet_pton(int, const char * __restrict, void * __restrict); #if __BSD_VISIBLE int inet_aton(const char *, struct in_addr *); in_addr_t inet_lnaof(struct in_addr); struct in_addr inet_makeaddr(in_addr_t, in_addr_t); char * inet_neta(in_addr_t, char *, size_t); in_addr_t inet_netof(struct in_addr); in_addr_t inet_network(const char *); char *inet_net_ntop(int, const void *, int, char *, size_t); int inet_net_pton(int, const char *, void *, size_t); char *inet_ntoa_r(struct in_addr, char *buf, socklen_t size); char *inet_cidr_ntop(int, const void *, int, char *, size_t); int inet_cidr_pton(int, const char *, void *, int *); unsigned inet_nsap_addr(const char *, unsigned char *, int); char *inet_nsap_ntoa(int, const unsigned char *, char *); #endif /* __BSD_VISIBLE */ __END_DECLS #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif #endif /* !_ARPA_INET_H_ */ /*! \file */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)tftp.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _ARPA_TFTP_H_ #define _ARPA_TFTP_H_ #include /* * Trivial File Transfer Protocol (IEN-133) */ #define SEGSIZE 512 /* data segment size */ /* * Packet types. */ #define RRQ 01 /* read request */ #define WRQ 02 /* write request */ #define DATA 03 /* data packet */ #define ACK 04 /* acknowledgement */ #define ERROR 05 /* error code */ #define OACK 06 /* option acknowledgement */ struct tftphdr { unsigned short th_opcode; /* packet type */ union { unsigned short tu_block; /* block # */ unsigned short tu_code; /* error code */ char tu_stuff[1]; /* request packet stuff */ } __packed th_u; char th_data[1]; /* data or error string */ } __packed; #define th_block th_u.tu_block #define th_code th_u.tu_code #define th_stuff th_u.tu_stuff #define th_msg th_data /* * Error codes. */ #define EUNDEF 0 /* not defined */ #define ENOTFOUND 1 /* file not found */ #define EACCESS 2 /* access violation */ #define ENOSPACE 3 /* disk full or allocation exceeded */ #define EBADOP 4 /* illegal TFTP operation */ #define EBADID 5 /* unknown transfer ID */ #define EEXISTS 6 /* file already exists */ #define ENOUSER 7 /* no such user */ #define EOPTNEG 8 /* option negotiation failed */ #endif /* !_TFTP_H_ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)assert.h 8.2 (Berkeley) 1/21/94 * $FreeBSD$ */ #include /* * Unlike other ANSI header files, may usefully be included * multiple times, with and without NDEBUG defined. */ #undef assert #undef _assert #ifdef NDEBUG #define assert(e) ((void)0) #define _assert(e) ((void)0) #else #define _assert(e) assert(e) #define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \ __LINE__, #e)) #endif /* NDEBUG */ #ifndef _ASSERT_H_ #define _ASSERT_H_ /* * Static assertions. In principle we could define static_assert for * C++ older than C++11, but this breaks if _Static_assert is * implemented as a macro. * * C++ template parameters may contain commas, even if not enclosed in * parentheses, causing the _Static_assert macro to be invoked with more * than two parameters. */ #if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus) #define static_assert _Static_assert #endif __BEGIN_DECLS void __assert(const char *, const char *, int, const char *) __dead2; __END_DECLS #endif /* !_ASSERT_H_ */ /*- * Copyright (c) 2003 Poul-Henning Kamp * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _BITSTRING_H_ #define _BITSTRING_H_ #include #endif /* _BITSTRING_H_ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ctype.h 8.4 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _CTYPE_H_ #define _CTYPE_H_ #include #include #include <_ctype.h> __BEGIN_DECLS int isalnum(int); int isalpha(int); int iscntrl(int); int isdigit(int); int isgraph(int); int islower(int); int isprint(int); int ispunct(int); int isspace(int); int isupper(int); int isxdigit(int); int tolower(int); int toupper(int); #if __XSI_VISIBLE int isascii(int); int toascii(int); #endif #if __ISO_C_VISIBLE >= 1999 int isblank(int); #endif #if __BSD_VISIBLE int digittoint(int); int ishexnumber(int); int isideogram(int); int isnumber(int); int isphonogram(int); int isrune(int); int isspecial(int); #endif #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #include #endif __END_DECLS #ifndef __cplusplus #define isalnum(c) __sbistype((c), _CTYPE_A|_CTYPE_D|_CTYPE_N) #define isalpha(c) __sbistype((c), _CTYPE_A) #define iscntrl(c) __sbistype((c), _CTYPE_C) #define isdigit(c) __sbistype((c), _CTYPE_D) #define isgraph(c) __sbistype((c), _CTYPE_G) #define islower(c) __sbistype((c), _CTYPE_L) #define isprint(c) __sbistype((c), _CTYPE_R) #define ispunct(c) __sbistype((c), _CTYPE_P) #define isspace(c) __sbistype((c), _CTYPE_S) #define isupper(c) __sbistype((c), _CTYPE_U) #define isxdigit(c) __sbistype((c), _CTYPE_X) #define tolower(c) __sbtolower(c) #define toupper(c) __sbtoupper(c) #endif /* !__cplusplus */ #if __XSI_VISIBLE /* * POSIX.1-2001 specifies _tolower() and _toupper() to be macros equivalent to * tolower() and toupper() respectively, minus extra checking to ensure that * the argument is a lower or uppercase letter respectively. We've chosen to * implement these macros with the same error checking as tolower() and * toupper() since this doesn't violate the specification itself, only its * intent. We purposely leave _tolower() and _toupper() undocumented to * discourage their use. * * XXX isascii() and toascii() should similarly be undocumented. */ #define _tolower(c) __sbtolower(c) #define _toupper(c) __sbtoupper(c) #define isascii(c) (((c) & ~0x7F) == 0) #define toascii(c) ((c) & 0x7F) #endif #if __ISO_C_VISIBLE >= 1999 && !defined(__cplusplus) #define isblank(c) __sbistype((c), _CTYPE_B) #endif #if __BSD_VISIBLE #define digittoint(c) __sbmaskrune((c), 0xFF) #define ishexnumber(c) __sbistype((c), _CTYPE_X) #define isideogram(c) __sbistype((c), _CTYPE_I) #define isnumber(c) __sbistype((c), _CTYPE_D|_CTYPE_N) #define isphonogram(c) __sbistype((c), _CTYPE_Q) #define isrune(c) __sbistype((c), 0xFFFFFF00L) #define isspecial(c) __sbistype((c), _CTYPE_T) #endif #endif /* !_CTYPE_H_ */ /*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)ns16550.h 7.1 (Berkeley) 5/9/91 * $FreeBSD$ */ /* * NS8250... UART registers. */ /* 8250 registers #[0-6]. */ #define com_data 0 /* data register (R/W) */ #define REG_DATA com_data #define com_ier 1 /* interrupt enable register (W) */ #define REG_IER com_ier #define IER_ERXRDY 0x1 #define IER_ETXRDY 0x2 #define IER_ERLS 0x4 #define IER_EMSC 0x8 #define IER_BITS "\20\1ERXRDY\2ETXRDY\3ERLS\4EMSC" #define com_iir 2 /* interrupt identification register (R) */ #define REG_IIR com_iir #define IIR_IMASK 0xf #define IIR_RXTOUT 0xc #define IIR_BUSY 0x7 #define IIR_RLS 0x6 #define IIR_RXRDY 0x4 #define IIR_TXRDY 0x2 #define IIR_NOPEND 0x1 #define IIR_MLSC 0x0 #define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ #define IIR_BITS "\20\1NOPEND\2TXRDY\3RXRDY" #define com_lcr 3 /* line control register (R/W) */ #define com_cfcr com_lcr /* character format control register (R/W) */ #define REG_LCR com_lcr #define LCR_DLAB 0x80 #define CFCR_DLAB LCR_DLAB #define LCR_EFR_ENABLE 0xbf /* magic to enable EFR on 16650 up */ #define CFCR_EFR_ENABLE LCR_EFR_ENABLE #define LCR_SBREAK 0x40 #define CFCR_SBREAK LCR_SBREAK #define LCR_PZERO 0x30 #define CFCR_PZERO LCR_PZERO #define LCR_PONE 0x20 #define CFCR_PONE LCR_PONE #define LCR_PEVEN 0x10 #define CFCR_PEVEN LCR_PEVEN #define LCR_PODD 0x00 #define CFCR_PODD LCR_PODD #define LCR_PENAB 0x08 #define CFCR_PENAB LCR_PENAB #define LCR_STOPB 0x04 #define CFCR_STOPB LCR_STOPB #define LCR_8BITS 0x03 #define CFCR_8BITS LCR_8BITS #define LCR_7BITS 0x02 #define CFCR_7BITS LCR_7BITS #define LCR_6BITS 0x01 #define CFCR_6BITS LCR_6BITS #define LCR_5BITS 0x00 #define CFCR_5BITS LCR_5BITS #define com_mcr 4 /* modem control register (R/W) */ #define REG_MCR com_mcr #define MCR_PRESCALE 0x80 /* only available on 16650 up */ #define MCR_LOOPBACK 0x10 #define MCR_IE 0x08 #define MCR_IENABLE MCR_IE #define MCR_DRS 0x04 #define MCR_RTS 0x02 #define MCR_DTR 0x01 #define MCR_BITS "\20\1DTR\2RTS\3DRS\4IE\5LOOPBACK\10PRESCALE" #define com_lsr 5 /* line status register (R/W) */ #define REG_LSR com_lsr #define LSR_RCV_FIFO 0x80 #define LSR_TEMT 0x40 #define LSR_TSRE LSR_TEMT #define LSR_THRE 0x20 #define LSR_TXRDY LSR_THRE #define LSR_BI 0x10 #define LSR_FE 0x08 #define LSR_PE 0x04 #define LSR_OE 0x02 #define LSR_RXRDY 0x01 #define LSR_RCV_MASK 0x1f #define LSR_BITS "\20\1RXRDY\2OE\3PE\4FE\5BI\6THRE\7TEMT\10RCV_FIFO" #define com_msr 6 /* modem status register (R/W) */ #define REG_MSR com_msr #define MSR_DCD 0x80 #define MSR_RI 0x40 #define MSR_DSR 0x20 #define MSR_CTS 0x10 #define MSR_DDCD 0x08 #define MSR_TERI 0x04 #define MSR_DDSR 0x02 #define MSR_DCTS 0x01 #define MSR_BITS "\20\1DCTS\2DDSR\3TERI\4DDCD\5CTS\6DSR\7RI\10DCD" /* 8250 multiplexed registers #[0-1]. Access enabled by LCR[7]. */ #define com_dll 0 /* divisor latch low (R/W) */ #define com_dlbl com_dll #define com_dlm 1 /* divisor latch high (R/W) */ #define com_dlbh com_dlm #define REG_DLL com_dll #define REG_DLH com_dlm /* 16450 register #7. Not multiplexed. */ #define com_scr 7 /* scratch register (R/W) */ /* 16550 register #2. Not multiplexed. */ #define com_fcr 2 /* FIFO control register (W) */ #define com_fifo com_fcr #define REG_FCR com_fcr #define FCR_ENABLE 0x01 #define FIFO_ENABLE FCR_ENABLE #define FCR_RCV_RST 0x02 #define FIFO_RCV_RST FCR_RCV_RST #define FCR_XMT_RST 0x04 #define FIFO_XMT_RST FCR_XMT_RST #define FCR_DMA 0x08 #define FIFO_DMA_MODE FCR_DMA #define FCR_RX_LOW 0x00 #define FIFO_RX_LOW FCR_RX_LOW #define FCR_RX_MEDL 0x40 #define FIFO_RX_MEDL FCR_RX_MEDL #define FCR_RX_MEDH 0x80 #define FIFO_RX_MEDH FCR_RX_MEDH #define FCR_RX_HIGH 0xc0 #define FIFO_RX_HIGH FCR_RX_HIGH #define FCR_BITS "\20\1ENABLE\2RCV_RST\3XMT_RST\4DMA" /* 16650 registers #2,[4-7]. Access enabled by LCR_EFR_ENABLE. */ #define com_efr 2 /* enhanced features register (R/W) */ #define REG_EFR com_efr #define EFR_CTS 0x80 #define EFR_AUTOCTS EFR_CTS #define EFR_RTS 0x40 #define EFR_AUTORTS EFR_RTS #define EFR_EFE 0x10 /* enhanced functions enable */ #define com_xon1 4 /* XON 1 character (R/W) */ #define com_xon2 5 /* XON 2 character (R/W) */ #define com_xoff1 6 /* XOFF 1 character (R/W) */ #define com_xoff2 7 /* XOFF 2 character (R/W) */ #define DW_REG_USR 31 /* DesignWare derived Uart Status Reg */ #define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */ #define REG_USR com_usr #define USR_BUSY 1 /* Uart Busy. Serial transfer in progress */ #define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */ /* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */ #define com_asr 1 /* additional status register (R[0-7]/W[0-1]) */ /* 16950 register #3. R/W access enabled by ACR[7]. */ #define com_rfl 3 /* receiver fifo level (R) */ /* * 16950 register #4. Access enabled by ACR[7]. Also requires * !LCR_EFR_ENABLE. */ #define com_tfl 4 /* transmitter fifo level (R) */ /* * 16950 register #5. Accessible if !LCR_EFR_ENABLE. Read access also * requires ACR[6]. */ #define com_icr 5 /* index control register (R/W) */ /* * 16950 register #7. It is the same as com_scr except it has a different * abbreviation in the manufacturer's data sheet and it also serves as an * index into the Indexed Control register set. */ #define com_spr com_scr /* scratch pad (and index) register (R/W) */ #define REG_SPR com_scr /* * 16950 indexed control registers #[0-0x13]. Access is via index in SPR, * data in ICR (if ICR is accessible). */ #define com_acr 0 /* additional control register (R/W) */ #define ACR_ASE 0x80 /* ASR/RFL/TFL enable */ #define ACR_ICRE 0x40 /* ICR enable */ #define ACR_TLE 0x20 /* TTL/RTL enable */ #define com_cpr 1 /* clock prescaler register (R/W) */ #define com_tcr 2 /* times clock register (R/W) */ #define com_ttl 4 /* transmitter trigger level (R/W) */ #define com_rtl 5 /* receiver trigger level (R/W) */ /* ... */ /* Hardware extension mode register for RSB-2000/3000. */ #define com_emr com_msr #define EMR_EXBUFF 0x04 #define EMR_CTSFLW 0x08 #define EMR_DSRFLW 0x10 #define EMR_RTSFLW 0x20 #define EMR_DTRFLW 0x40 #define EMR_EFMODE 0x80 /*- * Copyright (c) 1997, Stefan Esser * All rights reserved. * * 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 unmodified, 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * * $FreeBSD$ * */ /* * PCIM_xxx: mask to locate subfield in register * PCIR_xxx: config register offset * PCIC_xxx: device class * PCIS_xxx: device subclass * PCIP_xxx: device programming interface * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) * PCID_xxx: device ID * PCIY_xxx: capability identification number * PCIZ_xxx: extended capability identification number */ /* some PCI bus constants */ #define PCI_DOMAINMAX 65535 /* highest supported domain number */ #define PCI_BUSMAX 255 /* highest supported bus number */ #define PCI_SLOTMAX 31 /* highest supported slot number */ #define PCI_FUNCMAX 7 /* highest supported function number */ #define PCI_REGMAX 255 /* highest supported config register addr. */ #define PCIE_REGMAX 4095 /* highest supported config register addr. */ #define PCI_MAXHDRTYPE 2 #define PCIE_ARI_SLOTMAX 0 #define PCIE_ARI_FUNCMAX 255 #define PCI_RID_DOMAIN_SHIFT 16 #define PCI_RID_BUS_SHIFT 8 #define PCI_RID_SLOT_SHIFT 3 #define PCI_RID_FUNC_SHIFT 0 #define PCI_RID(bus, slot, func) \ ((((bus) & PCI_BUSMAX) << PCI_RID_BUS_SHIFT) | \ (((slot) & PCI_SLOTMAX) << PCI_RID_SLOT_SHIFT) | \ (((func) & PCI_FUNCMAX) << PCI_RID_FUNC_SHIFT)) #define PCI_ARI_RID(bus, func) \ ((((bus) & PCI_BUSMAX) << PCI_RID_BUS_SHIFT) | \ (((func) & PCIE_ARI_FUNCMAX) << PCI_RID_FUNC_SHIFT)) #define PCI_RID2BUS(rid) (((rid) >> PCI_RID_BUS_SHIFT) & PCI_BUSMAX) #define PCI_RID2SLOT(rid) (((rid) >> PCI_RID_SLOT_SHIFT) & PCI_SLOTMAX) #define PCI_RID2FUNC(rid) (((rid) >> PCI_RID_FUNC_SHIFT) & PCI_FUNCMAX) #define PCIE_ARI_RID2SLOT(rid) (0) #define PCIE_ARI_RID2FUNC(rid) \ (((rid) >> PCI_RID_FUNC_SHIFT) & PCIE_ARI_FUNCMAX) #define PCIE_ARI_SLOT(func) (((func) >> PCI_RID_SLOT_SHIFT) & PCI_SLOTMAX) #define PCIE_ARI_FUNC(func) (((func) >> PCI_RID_FUNC_SHIFT) & PCI_FUNCMAX) /* PCI config header registers for all devices */ #define PCIR_DEVVENDOR 0x00 #define PCIR_VENDOR 0x00 #define PCIR_DEVICE 0x02 #define PCIR_COMMAND 0x04 #define PCIM_CMD_PORTEN 0x0001 #define PCIM_CMD_MEMEN 0x0002 #define PCIM_CMD_BUSMASTEREN 0x0004 #define PCIM_CMD_SPECIALEN 0x0008 #define PCIM_CMD_MWRICEN 0x0010 #define PCIM_CMD_PERRESPEN 0x0040 #define PCIM_CMD_SERRESPEN 0x0100 #define PCIM_CMD_BACKTOBACK 0x0200 #define PCIM_CMD_INTxDIS 0x0400 #define PCIR_STATUS 0x06 #define PCIM_STATUS_INTxSTATE 0x0008 #define PCIM_STATUS_CAPPRESENT 0x0010 #define PCIM_STATUS_66CAPABLE 0x0020 #define PCIM_STATUS_BACKTOBACK 0x0080 #define PCIM_STATUS_MDPERR 0x0100 #define PCIM_STATUS_SEL_FAST 0x0000 #define PCIM_STATUS_SEL_MEDIMUM 0x0200 #define PCIM_STATUS_SEL_SLOW 0x0400 #define PCIM_STATUS_SEL_MASK 0x0600 #define PCIM_STATUS_STABORT 0x0800 #define PCIM_STATUS_RTABORT 0x1000 #define PCIM_STATUS_RMABORT 0x2000 #define PCIM_STATUS_SERR 0x4000 #define PCIM_STATUS_PERR 0x8000 #define PCIR_REVID 0x08 #define PCIR_PROGIF 0x09 #define PCIR_SUBCLASS 0x0a #define PCIR_CLASS 0x0b #define PCIR_CACHELNSZ 0x0c #define PCIR_LATTIMER 0x0d #define PCIR_HDRTYPE 0x0e #define PCIM_HDRTYPE 0x7f #define PCIM_HDRTYPE_NORMAL 0x00 #define PCIM_HDRTYPE_BRIDGE 0x01 #define PCIM_HDRTYPE_CARDBUS 0x02 #define PCIM_MFDEV 0x80 #define PCIR_BIST 0x0f /* Capability Register Offsets */ #define PCICAP_ID 0x0 #define PCICAP_NEXTPTR 0x1 /* Capability Identification Numbers */ #define PCIY_PMG 0x01 /* PCI Power Management */ #define PCIY_AGP 0x02 /* AGP */ #define PCIY_VPD 0x03 /* Vital Product Data */ #define PCIY_SLOTID 0x04 /* Slot Identification */ #define PCIY_MSI 0x05 /* Message Signaled Interrupts */ #define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */ #define PCIY_PCIX 0x07 /* PCI-X */ #define PCIY_HT 0x08 /* HyperTransport */ #define PCIY_VENDOR 0x09 /* Vendor Unique */ #define PCIY_DEBUG 0x0a /* Debug port */ #define PCIY_CRES 0x0b /* CompactPCI central resource control */ #define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */ #define PCIY_SUBVENDOR 0x0d /* PCI-PCI bridge subvendor ID */ #define PCIY_AGP8X 0x0e /* AGP 8x */ #define PCIY_SECDEV 0x0f /* Secure Device */ #define PCIY_EXPRESS 0x10 /* PCI Express */ #define PCIY_MSIX 0x11 /* MSI-X */ #define PCIY_SATA 0x12 /* SATA */ #define PCIY_PCIAF 0x13 /* PCI Advanced Features */ /* Extended Capability Register Fields */ #define PCIR_EXTCAP 0x100 #define PCIM_EXTCAP_ID 0x0000ffff #define PCIM_EXTCAP_VER 0x000f0000 #define PCIM_EXTCAP_NEXTPTR 0xfff00000 #define PCI_EXTCAP_ID(ecap) ((ecap) & PCIM_EXTCAP_ID) #define PCI_EXTCAP_VER(ecap) (((ecap) & PCIM_EXTCAP_VER) >> 16) #define PCI_EXTCAP_NEXTPTR(ecap) (((ecap) & PCIM_EXTCAP_NEXTPTR) >> 20) /* Extended Capability Identification Numbers */ #define PCIZ_AER 0x0001 /* Advanced Error Reporting */ #define PCIZ_VC 0x0002 /* Virtual Channel if MFVC Ext Cap not set */ #define PCIZ_SERNUM 0x0003 /* Device Serial Number */ #define PCIZ_PWRBDGT 0x0004 /* Power Budgeting */ #define PCIZ_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */ #define PCIZ_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */ #define PCIZ_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */ #define PCIZ_MFVC 0x0008 /* Multi-Function Virtual Channel */ #define PCIZ_VC2 0x0009 /* Virtual Channel if MFVC Ext Cap set */ #define PCIZ_RCRB 0x000a /* RCRB Header */ #define PCIZ_VENDOR 0x000b /* Vendor Unique */ #define PCIZ_CAC 0x000c /* Configuration Access Correction -- obsolete */ #define PCIZ_ACS 0x000d /* Access Control Services */ #define PCIZ_ARI 0x000e /* Alternative Routing-ID Interpretation */ #define PCIZ_ATS 0x000f /* Address Translation Services */ #define PCIZ_SRIOV 0x0010 /* Single Root IO Virtualization */ #define PCIZ_MRIOV 0x0011 /* Multiple Root IO Virtualization */ #define PCIZ_MULTICAST 0x0012 /* Multicast */ #define PCIZ_PAGE_REQ 0x0013 /* Page Request */ #define PCIZ_AMD 0x0014 /* Reserved for AMD */ #define PCIZ_RESIZE_BAR 0x0015 /* Resizable BAR */ #define PCIZ_DPA 0x0016 /* Dynamic Power Allocation */ #define PCIZ_TPH_REQ 0x0017 /* TPH Requester */ #define PCIZ_LTR 0x0018 /* Latency Tolerance Reporting */ #define PCIZ_SEC_PCIE 0x0019 /* Secondary PCI Express */ #define PCIZ_PMUX 0x001a /* Protocol Multiplexing */ #define PCIZ_PASID 0x001b /* Process Address Space ID */ #define PCIZ_LN_REQ 0x001c /* LN Requester */ #define PCIZ_DPC 0x001d /* Downstream Porto Containment */ #define PCIZ_L1PM 0x001e /* L1 PM Substates */ /* config registers for header type 0 devices */ #define PCIR_BARS 0x10 #define PCIR_BAR(x) (PCIR_BARS + (x) * 4) #define PCIR_MAX_BAR_0 5 #define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4) #define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) #define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE) #define PCIM_BAR_SPACE 0x00000001 #define PCIM_BAR_MEM_SPACE 0 #define PCIM_BAR_IO_SPACE 1 #define PCIM_BAR_MEM_TYPE 0x00000006 #define PCIM_BAR_MEM_32 0 #define PCIM_BAR_MEM_1MB 2 /* Locate below 1MB in PCI <= 2.1 */ #define PCIM_BAR_MEM_64 4 #define PCIM_BAR_MEM_PREFETCH 0x00000008 #define PCIM_BAR_MEM_BASE 0xfffffffffffffff0ULL #define PCIM_BAR_IO_RESERVED 0x00000002 #define PCIM_BAR_IO_BASE 0xfffffffc #define PCIR_CIS 0x28 #define PCIM_CIS_ASI_MASK 0x00000007 #define PCIM_CIS_ASI_CONFIG 0 #define PCIM_CIS_ASI_BAR0 1 #define PCIM_CIS_ASI_BAR1 2 #define PCIM_CIS_ASI_BAR2 3 #define PCIM_CIS_ASI_BAR3 4 #define PCIM_CIS_ASI_BAR4 5 #define PCIM_CIS_ASI_BAR5 6 #define PCIM_CIS_ASI_ROM 7 #define PCIM_CIS_ADDR_MASK 0x0ffffff8 #define PCIM_CIS_ROM_MASK 0xf0000000 #define PCIM_CIS_CONFIG_MASK 0xff #define PCIR_SUBVEND_0 0x2c #define PCIR_SUBDEV_0 0x2e #define PCIR_BIOS 0x30 #define PCIM_BIOS_ENABLE 0x01 #define PCIM_BIOS_ADDR_MASK 0xfffff800 #define PCIR_CAP_PTR 0x34 #define PCIR_INTLINE 0x3c #define PCIR_INTPIN 0x3d #define PCIR_MINGNT 0x3e #define PCIR_MAXLAT 0x3f /* config registers for header type 1 (PCI-to-PCI bridge) devices */ #define PCIR_MAX_BAR_1 1 #define PCIR_SECSTAT_1 0x1e #define PCIR_PRIBUS_1 0x18 #define PCIR_SECBUS_1 0x19 #define PCIR_SUBBUS_1 0x1a #define PCIR_SECLAT_1 0x1b #define PCIR_IOBASEL_1 0x1c #define PCIR_IOLIMITL_1 0x1d #define PCIR_IOBASEH_1 0x30 #define PCIR_IOLIMITH_1 0x32 #define PCIM_BRIO_16 0x0 #define PCIM_BRIO_32 0x1 #define PCIM_BRIO_MASK 0xf #define PCIR_MEMBASE_1 0x20 #define PCIR_MEMLIMIT_1 0x22 #define PCIR_PMBASEL_1 0x24 #define PCIR_PMLIMITL_1 0x26 #define PCIR_PMBASEH_1 0x28 #define PCIR_PMLIMITH_1 0x2c #define PCIM_BRPM_32 0x0 #define PCIM_BRPM_64 0x1 #define PCIM_BRPM_MASK 0xf #define PCIR_BIOS_1 0x38 #define PCIR_BRIDGECTL_1 0x3e /* config registers for header type 2 (CardBus) devices */ #define PCIR_MAX_BAR_2 0 #define PCIR_CAP_PTR_2 0x14 #define PCIR_SECSTAT_2 0x16 #define PCIR_PRIBUS_2 0x18 #define PCIR_SECBUS_2 0x19 #define PCIR_SUBBUS_2 0x1a #define PCIR_SECLAT_2 0x1b #define PCIR_MEMBASE0_2 0x1c #define PCIR_MEMLIMIT0_2 0x20 #define PCIR_MEMBASE1_2 0x24 #define PCIR_MEMLIMIT1_2 0x28 #define PCIR_IOBASE0_2 0x2c #define PCIR_IOLIMIT0_2 0x30 #define PCIR_IOBASE1_2 0x34 #define PCIR_IOLIMIT1_2 0x38 #define PCIR_BRIDGECTL_2 0x3e #define PCIR_SUBVEND_2 0x40 #define PCIR_SUBDEV_2 0x42 #define PCIR_PCCARDIF_2 0x44 /* PCI device class, subclass and programming interface definitions */ #define PCIC_OLD 0x00 #define PCIS_OLD_NONVGA 0x00 #define PCIS_OLD_VGA 0x01 #define PCIC_STORAGE 0x01 #define PCIS_STORAGE_SCSI 0x00 #define PCIS_STORAGE_IDE 0x01 #define PCIP_STORAGE_IDE_MODEPRIM 0x01 #define PCIP_STORAGE_IDE_PROGINDPRIM 0x02 #define PCIP_STORAGE_IDE_MODESEC 0x04 #define PCIP_STORAGE_IDE_PROGINDSEC 0x08 #define PCIP_STORAGE_IDE_MASTERDEV 0x80 #define PCIS_STORAGE_FLOPPY 0x02 #define PCIS_STORAGE_IPI 0x03 #define PCIS_STORAGE_RAID 0x04 #define PCIS_STORAGE_ATA_ADMA 0x05 #define PCIS_STORAGE_SATA 0x06 #define PCIP_STORAGE_SATA_AHCI_1_0 0x01 #define PCIS_STORAGE_SAS 0x07 #define PCIS_STORAGE_NVM 0x08 #define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01 #define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02 #define PCIS_STORAGE_OTHER 0x80 #define PCIC_NETWORK 0x02 #define PCIS_NETWORK_ETHERNET 0x00 #define PCIS_NETWORK_TOKENRING 0x01 #define PCIS_NETWORK_FDDI 0x02 #define PCIS_NETWORK_ATM 0x03 #define PCIS_NETWORK_ISDN 0x04 #define PCIS_NETWORK_WORLDFIP 0x05 #define PCIS_NETWORK_PICMG 0x06 #define PCIS_NETWORK_OTHER 0x80 #define PCIC_DISPLAY 0x03 #define PCIS_DISPLAY_VGA 0x00 #define PCIS_DISPLAY_XGA 0x01 #define PCIS_DISPLAY_3D 0x02 #define PCIS_DISPLAY_OTHER 0x80 #define PCIC_MULTIMEDIA 0x04 #define PCIS_MULTIMEDIA_VIDEO 0x00 #define PCIS_MULTIMEDIA_AUDIO 0x01 #define PCIS_MULTIMEDIA_TELE 0x02 #define PCIS_MULTIMEDIA_HDA 0x03 #define PCIS_MULTIMEDIA_OTHER 0x80 #define PCIC_MEMORY 0x05 #define PCIS_MEMORY_RAM 0x00 #define PCIS_MEMORY_FLASH 0x01 #define PCIS_MEMORY_OTHER 0x80 #define PCIC_BRIDGE 0x06 #define PCIS_BRIDGE_HOST 0x00 #define PCIS_BRIDGE_ISA 0x01 #define PCIS_BRIDGE_EISA 0x02 #define PCIS_BRIDGE_MCA 0x03 #define PCIS_BRIDGE_PCI 0x04 #define PCIP_BRIDGE_PCI_SUBTRACTIVE 0x01 #define PCIS_BRIDGE_PCMCIA 0x05 #define PCIS_BRIDGE_NUBUS 0x06 #define PCIS_BRIDGE_CARDBUS 0x07 #define PCIS_BRIDGE_RACEWAY 0x08 #define PCIS_BRIDGE_PCI_TRANSPARENT 0x09 #define PCIS_BRIDGE_INFINIBAND 0x0a #define PCIS_BRIDGE_OTHER 0x80 #define PCIC_SIMPLECOMM 0x07 #define PCIS_SIMPLECOMM_UART 0x00 #define PCIP_SIMPLECOMM_UART_8250 0x00 #define PCIP_SIMPLECOMM_UART_16450A 0x01 #define PCIP_SIMPLECOMM_UART_16550A 0x02 #define PCIP_SIMPLECOMM_UART_16650A 0x03 #define PCIP_SIMPLECOMM_UART_16750A 0x04 #define PCIP_SIMPLECOMM_UART_16850A 0x05 #define PCIP_SIMPLECOMM_UART_16950A 0x06 #define PCIS_SIMPLECOMM_PAR 0x01 #define PCIS_SIMPLECOMM_MULSER 0x02 #define PCIS_SIMPLECOMM_MODEM 0x03 #define PCIS_SIMPLECOMM_GPIB 0x04 #define PCIS_SIMPLECOMM_SMART_CARD 0x05 #define PCIS_SIMPLECOMM_OTHER 0x80 #define PCIC_BASEPERIPH 0x08 #define PCIS_BASEPERIPH_PIC 0x00 #define PCIP_BASEPERIPH_PIC_8259A 0x00 #define PCIP_BASEPERIPH_PIC_ISA 0x01 #define PCIP_BASEPERIPH_PIC_EISA 0x02 #define PCIP_BASEPERIPH_PIC_IO_APIC 0x10 #define PCIP_BASEPERIPH_PIC_IOX_APIC 0x20 #define PCIS_BASEPERIPH_DMA 0x01 #define PCIS_BASEPERIPH_TIMER 0x02 #define PCIS_BASEPERIPH_RTC 0x03 #define PCIS_BASEPERIPH_PCIHOT 0x04 #define PCIS_BASEPERIPH_SDHC 0x05 #define PCIS_BASEPERIPH_IOMMU 0x06 #define PCIS_BASEPERIPH_OTHER 0x80 #define PCIC_INPUTDEV 0x09 #define PCIS_INPUTDEV_KEYBOARD 0x00 #define PCIS_INPUTDEV_DIGITIZER 0x01 #define PCIS_INPUTDEV_MOUSE 0x02 #define PCIS_INPUTDEV_SCANNER 0x03 #define PCIS_INPUTDEV_GAMEPORT 0x04 #define PCIS_INPUTDEV_OTHER 0x80 #define PCIC_DOCKING 0x0a #define PCIS_DOCKING_GENERIC 0x00 #define PCIS_DOCKING_OTHER 0x80 #define PCIC_PROCESSOR 0x0b #define PCIS_PROCESSOR_386 0x00 #define PCIS_PROCESSOR_486 0x01 #define PCIS_PROCESSOR_PENTIUM 0x02 #define PCIS_PROCESSOR_ALPHA 0x10 #define PCIS_PROCESSOR_POWERPC 0x20 #define PCIS_PROCESSOR_MIPS 0x30 #define PCIS_PROCESSOR_COPROC 0x40 #define PCIC_SERIALBUS 0x0c #define PCIS_SERIALBUS_FW 0x00 #define PCIS_SERIALBUS_ACCESS 0x01 #define PCIS_SERIALBUS_SSA 0x02 #define PCIS_SERIALBUS_USB 0x03 #define PCIP_SERIALBUS_USB_UHCI 0x00 #define PCIP_SERIALBUS_USB_OHCI 0x10 #define PCIP_SERIALBUS_USB_EHCI 0x20 #define PCIP_SERIALBUS_USB_XHCI 0x30 #define PCIP_SERIALBUS_USB_DEVICE 0xfe #define PCIS_SERIALBUS_FC 0x04 #define PCIS_SERIALBUS_SMBUS 0x05 #define PCIS_SERIALBUS_INFINIBAND 0x06 #define PCIS_SERIALBUS_IPMI 0x07 #define PCIP_SERIALBUS_IPMI_SMIC 0x00 #define PCIP_SERIALBUS_IPMI_KCS 0x01 #define PCIP_SERIALBUS_IPMI_BT 0x02 #define PCIS_SERIALBUS_SERCOS 0x08 #define PCIS_SERIALBUS_CANBUS 0x09 #define PCIC_WIRELESS 0x0d #define PCIS_WIRELESS_IRDA 0x00 #define PCIS_WIRELESS_IR 0x01 #define PCIS_WIRELESS_RF 0x10 #define PCIS_WIRELESS_BLUETOOTH 0x11 #define PCIS_WIRELESS_BROADBAND 0x12 #define PCIS_WIRELESS_80211A 0x20 #define PCIS_WIRELESS_80211B 0x21 #define PCIS_WIRELESS_OTHER 0x80 #define PCIC_INTELLIIO 0x0e #define PCIS_INTELLIIO_I2O 0x00 #define PCIC_SATCOM 0x0f #define PCIS_SATCOM_TV 0x01 #define PCIS_SATCOM_AUDIO 0x02 #define PCIS_SATCOM_VOICE 0x03 #define PCIS_SATCOM_DATA 0x04 #define PCIC_CRYPTO 0x10 #define PCIS_CRYPTO_NETCOMP 0x00 #define PCIS_CRYPTO_ENTERTAIN 0x10 #define PCIS_CRYPTO_OTHER 0x80 #define PCIC_DASP 0x11 #define PCIS_DASP_DPIO 0x00 #define PCIS_DASP_PERFCNTRS 0x01 #define PCIS_DASP_COMM_SYNC 0x10 #define PCIS_DASP_MGMT_CARD 0x20 #define PCIS_DASP_OTHER 0x80 #define PCIC_OTHER 0xff /* Bridge Control Values. */ #define PCIB_BCR_PERR_ENABLE 0x0001 #define PCIB_BCR_SERR_ENABLE 0x0002 #define PCIB_BCR_ISA_ENABLE 0x0004 #define PCIB_BCR_VGA_ENABLE 0x0008 #define PCIB_BCR_MASTER_ABORT_MODE 0x0020 #define PCIB_BCR_SECBUS_RESET 0x0040 #define PCIB_BCR_SECBUS_BACKTOBACK 0x0080 #define PCIB_BCR_PRI_DISCARD_TIMEOUT 0x0100 #define PCIB_BCR_SEC_DISCARD_TIMEOUT 0x0200 #define PCIB_BCR_DISCARD_TIMER_STATUS 0x0400 #define PCIB_BCR_DISCARD_TIMER_SERREN 0x0800 /* PCI power manangement */ #define PCIR_POWER_CAP 0x2 #define PCIM_PCAP_SPEC 0x0007 #define PCIM_PCAP_PMEREQCLK 0x0008 #define PCIM_PCAP_DEVSPECINIT 0x0020 #define PCIM_PCAP_AUXPWR_0 0x0000 #define PCIM_PCAP_AUXPWR_55 0x0040 #define PCIM_PCAP_AUXPWR_100 0x0080 #define PCIM_PCAP_AUXPWR_160 0x00c0 #define PCIM_PCAP_AUXPWR_220 0x0100 #define PCIM_PCAP_AUXPWR_270 0x0140 #define PCIM_PCAP_AUXPWR_320 0x0180 #define PCIM_PCAP_AUXPWR_375 0x01c0 #define PCIM_PCAP_AUXPWRMASK 0x01c0 #define PCIM_PCAP_D1SUPP 0x0200 #define PCIM_PCAP_D2SUPP 0x0400 #define PCIM_PCAP_D0PME 0x0800 #define PCIM_PCAP_D1PME 0x1000 #define PCIM_PCAP_D2PME 0x2000 #define PCIM_PCAP_D3PME_HOT 0x4000 #define PCIM_PCAP_D3PME_COLD 0x8000 #define PCIR_POWER_STATUS 0x4 #define PCIM_PSTAT_D0 0x0000 #define PCIM_PSTAT_D1 0x0001 #define PCIM_PSTAT_D2 0x0002 #define PCIM_PSTAT_D3 0x0003 #define PCIM_PSTAT_DMASK 0x0003 #define PCIM_PSTAT_NOSOFTRESET 0x0008 #define PCIM_PSTAT_PMEENABLE 0x0100 #define PCIM_PSTAT_D0POWER 0x0000 #define PCIM_PSTAT_D1POWER 0x0200 #define PCIM_PSTAT_D2POWER 0x0400 #define PCIM_PSTAT_D3POWER 0x0600 #define PCIM_PSTAT_D0HEAT 0x0800 #define PCIM_PSTAT_D1HEAT 0x0a00 #define PCIM_PSTAT_D2HEAT 0x0c00 #define PCIM_PSTAT_D3HEAT 0x0e00 #define PCIM_PSTAT_DATASELMASK 0x1e00 #define PCIM_PSTAT_DATAUNKN 0x0000 #define PCIM_PSTAT_DATADIV10 0x2000 #define PCIM_PSTAT_DATADIV100 0x4000 #define PCIM_PSTAT_DATADIV1000 0x6000 #define PCIM_PSTAT_DATADIVMASK 0x6000 #define PCIM_PSTAT_PME 0x8000 #define PCIR_POWER_BSE 0x6 #define PCIM_PMCSR_BSE_D3B3 0x00 #define PCIM_PMCSR_BSE_D3B2 0x40 #define PCIM_PMCSR_BSE_BPCCE 0x80 #define PCIR_POWER_DATA 0x7 /* VPD capability registers */ #define PCIR_VPD_ADDR 0x2 #define PCIR_VPD_DATA 0x4 /* PCI Message Signalled Interrupts (MSI) */ #define PCIR_MSI_CTRL 0x2 #define PCIM_MSICTRL_VECTOR 0x0100 #define PCIM_MSICTRL_64BIT 0x0080 #define PCIM_MSICTRL_MME_MASK 0x0070 #define PCIM_MSICTRL_MME_1 0x0000 #define PCIM_MSICTRL_MME_2 0x0010 #define PCIM_MSICTRL_MME_4 0x0020 #define PCIM_MSICTRL_MME_8 0x0030 #define PCIM_MSICTRL_MME_16 0x0040 #define PCIM_MSICTRL_MME_32 0x0050 #define PCIM_MSICTRL_MMC_MASK 0x000E #define PCIM_MSICTRL_MMC_1 0x0000 #define PCIM_MSICTRL_MMC_2 0x0002 #define PCIM_MSICTRL_MMC_4 0x0004 #define PCIM_MSICTRL_MMC_8 0x0006 #define PCIM_MSICTRL_MMC_16 0x0008 #define PCIM_MSICTRL_MMC_32 0x000A #define PCIM_MSICTRL_MSI_ENABLE 0x0001 #define PCIR_MSI_ADDR 0x4 #define PCIR_MSI_ADDR_HIGH 0x8 #define PCIR_MSI_DATA 0x8 #define PCIR_MSI_DATA_64BIT 0xc #define PCIR_MSI_MASK 0x10 #define PCIR_MSI_PENDING 0x14 /* PCI-X definitions */ /* For header type 0 devices */ #define PCIXR_COMMAND 0x2 #define PCIXM_COMMAND_DPERR_E 0x0001 /* Data Parity Error Recovery */ #define PCIXM_COMMAND_ERO 0x0002 /* Enable Relaxed Ordering */ #define PCIXM_COMMAND_MAX_READ 0x000c /* Maximum Burst Read Count */ #define PCIXM_COMMAND_MAX_READ_512 0x0000 #define PCIXM_COMMAND_MAX_READ_1024 0x0004 #define PCIXM_COMMAND_MAX_READ_2048 0x0008 #define PCIXM_COMMAND_MAX_READ_4096 0x000c #define PCIXM_COMMAND_MAX_SPLITS 0x0070 /* Maximum Split Transactions */ #define PCIXM_COMMAND_MAX_SPLITS_1 0x0000 #define PCIXM_COMMAND_MAX_SPLITS_2 0x0010 #define PCIXM_COMMAND_MAX_SPLITS_3 0x0020 #define PCIXM_COMMAND_MAX_SPLITS_4 0x0030 #define PCIXM_COMMAND_MAX_SPLITS_8 0x0040 #define PCIXM_COMMAND_MAX_SPLITS_12 0x0050 #define PCIXM_COMMAND_MAX_SPLITS_16 0x0060 #define PCIXM_COMMAND_MAX_SPLITS_32 0x0070 #define PCIXM_COMMAND_VERSION 0x3000 #define PCIXR_STATUS 0x4 #define PCIXM_STATUS_DEVFN 0x000000FF #define PCIXM_STATUS_BUS 0x0000FF00 #define PCIXM_STATUS_64BIT 0x00010000 #define PCIXM_STATUS_133CAP 0x00020000 #define PCIXM_STATUS_SC_DISCARDED 0x00040000 #define PCIXM_STATUS_UNEXP_SC 0x00080000 #define PCIXM_STATUS_COMPLEX_DEV 0x00100000 #define PCIXM_STATUS_MAX_READ 0x00600000 #define PCIXM_STATUS_MAX_READ_512 0x00000000 #define PCIXM_STATUS_MAX_READ_1024 0x00200000 #define PCIXM_STATUS_MAX_READ_2048 0x00400000 #define PCIXM_STATUS_MAX_READ_4096 0x00600000 #define PCIXM_STATUS_MAX_SPLITS 0x03800000 #define PCIXM_STATUS_MAX_SPLITS_1 0x00000000 #define PCIXM_STATUS_MAX_SPLITS_2 0x00800000 #define PCIXM_STATUS_MAX_SPLITS_3 0x01000000 #define PCIXM_STATUS_MAX_SPLITS_4 0x01800000 #define PCIXM_STATUS_MAX_SPLITS_8 0x02000000 #define PCIXM_STATUS_MAX_SPLITS_12 0x02800000 #define PCIXM_STATUS_MAX_SPLITS_16 0x03000000 #define PCIXM_STATUS_MAX_SPLITS_32 0x03800000 #define PCIXM_STATUS_MAX_CUM_READ 0x1C000000 #define PCIXM_STATUS_RCVD_SC_ERR 0x20000000 #define PCIXM_STATUS_266CAP 0x40000000 #define PCIXM_STATUS_533CAP 0x80000000 /* For header type 1 devices (PCI-X bridges) */ #define PCIXR_SEC_STATUS 0x2 #define PCIXM_SEC_STATUS_64BIT 0x0001 #define PCIXM_SEC_STATUS_133CAP 0x0002 #define PCIXM_SEC_STATUS_SC_DISC 0x0004 #define PCIXM_SEC_STATUS_UNEXP_SC 0x0008 #define PCIXM_SEC_STATUS_SC_OVERRUN 0x0010 #define PCIXM_SEC_STATUS_SR_DELAYED 0x0020 #define PCIXM_SEC_STATUS_BUS_MODE 0x03c0 #define PCIXM_SEC_STATUS_VERSION 0x3000 #define PCIXM_SEC_STATUS_266CAP 0x4000 #define PCIXM_SEC_STATUS_533CAP 0x8000 #define PCIXR_BRIDGE_STATUS 0x4 #define PCIXM_BRIDGE_STATUS_DEVFN 0x000000FF #define PCIXM_BRIDGE_STATUS_BUS 0x0000FF00 #define PCIXM_BRIDGE_STATUS_64BIT 0x00010000 #define PCIXM_BRIDGE_STATUS_133CAP 0x00020000 #define PCIXM_BRIDGE_STATUS_SC_DISCARDED 0x00040000 #define PCIXM_BRIDGE_STATUS_UNEXP_SC 0x00080000 #define PCIXM_BRIDGE_STATUS_SC_OVERRUN 0x00100000 #define PCIXM_BRIDGE_STATUS_SR_DELAYED 0x00200000 #define PCIXM_BRIDGE_STATUS_DEVID_MSGCAP 0x20000000 #define PCIXM_BRIDGE_STATUS_266CAP 0x40000000 #define PCIXM_BRIDGE_STATUS_533CAP 0x80000000 /* HT (HyperTransport) Capability definitions */ #define PCIR_HT_COMMAND 0x2 #define PCIM_HTCMD_CAP_MASK 0xf800 /* Capability type. */ #define PCIM_HTCAP_SLAVE 0x0000 /* 000xx */ #define PCIM_HTCAP_HOST 0x2000 /* 001xx */ #define PCIM_HTCAP_SWITCH 0x4000 /* 01000 */ #define PCIM_HTCAP_INTERRUPT 0x8000 /* 10000 */ #define PCIM_HTCAP_REVISION_ID 0x8800 /* 10001 */ #define PCIM_HTCAP_UNITID_CLUMPING 0x9000 /* 10010 */ #define PCIM_HTCAP_EXT_CONFIG_SPACE 0x9800 /* 10011 */ #define PCIM_HTCAP_ADDRESS_MAPPING 0xa000 /* 10100 */ #define PCIM_HTCAP_MSI_MAPPING 0xa800 /* 10101 */ #define PCIM_HTCAP_DIRECT_ROUTE 0xb000 /* 10110 */ #define PCIM_HTCAP_VCSET 0xb800 /* 10111 */ #define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */ #define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */ #define PCIM_HTCAP_GEN3 0xd000 /* 11010 */ #define PCIM_HTCAP_FLE 0xd800 /* 11011 */ #define PCIM_HTCAP_PM 0xe000 /* 11100 */ #define PCIM_HTCAP_HIGH_NODE_COUNT 0xe800 /* 11101 */ /* HT MSI Mapping Capability definitions. */ #define PCIM_HTCMD_MSI_ENABLE 0x0001 #define PCIM_HTCMD_MSI_FIXED 0x0002 #define PCIR_HTMSI_ADDRESS_LO 0x4 #define PCIR_HTMSI_ADDRESS_HI 0x8 /* PCI Vendor capability definitions */ #define PCIR_VENDOR_LENGTH 0x2 #define PCIR_VENDOR_DATA 0x3 /* PCI EHCI Debug Port definitions */ #define PCIR_DEBUG_PORT 0x2 #define PCIM_DEBUG_PORT_OFFSET 0x1FFF #define PCIM_DEBUG_PORT_BAR 0xe000 /* PCI-PCI Bridge Subvendor definitions */ #define PCIR_SUBVENDCAP_ID 0x4 /* PCI Express definitions */ #define PCIER_FLAGS 0x2 #define PCIEM_FLAGS_VERSION 0x000F #define PCIEM_FLAGS_TYPE 0x00F0 #define PCIEM_TYPE_ENDPOINT 0x0000 #define PCIEM_TYPE_LEGACY_ENDPOINT 0x0010 #define PCIEM_TYPE_ROOT_PORT 0x0040 #define PCIEM_TYPE_UPSTREAM_PORT 0x0050 #define PCIEM_TYPE_DOWNSTREAM_PORT 0x0060 #define PCIEM_TYPE_PCI_BRIDGE 0x0070 #define PCIEM_TYPE_PCIE_BRIDGE 0x0080 #define PCIEM_TYPE_ROOT_INT_EP 0x0090 #define PCIEM_TYPE_ROOT_EC 0x00a0 #define PCIEM_FLAGS_SLOT 0x0100 #define PCIEM_FLAGS_IRQ 0x3e00 #define PCIER_DEVICE_CAP 0x4 #define PCIEM_CAP_MAX_PAYLOAD 0x00000007 #define PCIEM_CAP_PHANTHOM_FUNCS 0x00000018 #define PCIEM_CAP_EXT_TAG_FIELD 0x00000020 #define PCIEM_CAP_L0S_LATENCY 0x000001c0 #define PCIEM_CAP_L1_LATENCY 0x00000e00 #define PCIEM_CAP_ROLE_ERR_RPT 0x00008000 #define PCIEM_CAP_SLOT_PWR_LIM_VAL 0x03fc0000 #define PCIEM_CAP_SLOT_PWR_LIM_SCALE 0x0c000000 #define PCIEM_CAP_FLR 0x10000000 #define PCIER_DEVICE_CTL 0x8 #define PCIEM_CTL_COR_ENABLE 0x0001 #define PCIEM_CTL_NFER_ENABLE 0x0002 #define PCIEM_CTL_FER_ENABLE 0x0004 #define PCIEM_CTL_URR_ENABLE 0x0008 #define PCIEM_CTL_RELAXED_ORD_ENABLE 0x0010 #define PCIEM_CTL_MAX_PAYLOAD 0x00e0 #define PCIEM_CTL_EXT_TAG_FIELD 0x0100 #define PCIEM_CTL_PHANTHOM_FUNCS 0x0200 #define PCIEM_CTL_AUX_POWER_PM 0x0400 #define PCIEM_CTL_NOSNOOP_ENABLE 0x0800 #define PCIEM_CTL_MAX_READ_REQUEST 0x7000 #define PCIEM_CTL_BRDG_CFG_RETRY 0x8000 /* PCI-E - PCI/PCI-X bridges */ #define PCIEM_CTL_INITIATE_FLR 0x8000 /* FLR capable endpoints */ #define PCIER_DEVICE_STA 0xa #define PCIEM_STA_CORRECTABLE_ERROR 0x0001 #define PCIEM_STA_NON_FATAL_ERROR 0x0002 #define PCIEM_STA_FATAL_ERROR 0x0004 #define PCIEM_STA_UNSUPPORTED_REQ 0x0008 #define PCIEM_STA_AUX_POWER 0x0010 #define PCIEM_STA_TRANSACTION_PND 0x0020 #define PCIER_LINK_CAP 0xc #define PCIEM_LINK_CAP_MAX_SPEED 0x0000000f #define PCIEM_LINK_CAP_MAX_WIDTH 0x000003f0 #define PCIEM_LINK_CAP_ASPM 0x00000c00 #define PCIEM_LINK_CAP_L0S_EXIT 0x00007000 #define PCIEM_LINK_CAP_L1_EXIT 0x00038000 #define PCIEM_LINK_CAP_CLOCK_PM 0x00040000 #define PCIEM_LINK_CAP_SURPRISE_DOWN 0x00080000 #define PCIEM_LINK_CAP_DL_ACTIVE 0x00100000 #define PCIEM_LINK_CAP_LINK_BW_NOTIFY 0x00200000 #define PCIEM_LINK_CAP_ASPM_COMPLIANCE 0x00400000 #define PCIEM_LINK_CAP_PORT 0xff000000 #define PCIER_LINK_CTL 0x10 #define PCIEM_LINK_CTL_ASPMC_DIS 0x0000 #define PCIEM_LINK_CTL_ASPMC_L0S 0x0001 #define PCIEM_LINK_CTL_ASPMC_L1 0x0002 #define PCIEM_LINK_CTL_ASPMC 0x0003 #define PCIEM_LINK_CTL_RCB 0x0008 #define PCIEM_LINK_CTL_LINK_DIS 0x0010 #define PCIEM_LINK_CTL_RETRAIN_LINK 0x0020 #define PCIEM_LINK_CTL_COMMON_CLOCK 0x0040 #define PCIEM_LINK_CTL_EXTENDED_SYNC 0x0080 #define PCIEM_LINK_CTL_ECPM 0x0100 #define PCIEM_LINK_CTL_HAWD 0x0200 #define PCIEM_LINK_CTL_LBMIE 0x0400 #define PCIEM_LINK_CTL_LABIE 0x0800 #define PCIER_LINK_STA 0x12 #define PCIEM_LINK_STA_SPEED 0x000f #define PCIEM_LINK_STA_WIDTH 0x03f0 #define PCIEM_LINK_STA_TRAINING_ERROR 0x0400 #define PCIEM_LINK_STA_TRAINING 0x0800 #define PCIEM_LINK_STA_SLOT_CLOCK 0x1000 #define PCIEM_LINK_STA_DL_ACTIVE 0x2000 #define PCIEM_LINK_STA_LINK_BW_MGMT 0x4000 #define PCIEM_LINK_STA_LINK_AUTO_BW 0x8000 #define PCIER_SLOT_CAP 0x14 #define PCIEM_SLOT_CAP_APB 0x00000001 #define PCIEM_SLOT_CAP_PCP 0x00000002 #define PCIEM_SLOT_CAP_MRLSP 0x00000004 #define PCIEM_SLOT_CAP_AIP 0x00000008 #define PCIEM_SLOT_CAP_PIP 0x00000010 #define PCIEM_SLOT_CAP_HPS 0x00000020 #define PCIEM_SLOT_CAP_HPC 0x00000040 #define PCIEM_SLOT_CAP_SPLV 0x00007f80 #define PCIEM_SLOT_CAP_SPLS 0x00018000 #define PCIEM_SLOT_CAP_EIP 0x00020000 #define PCIEM_SLOT_CAP_NCCS 0x00040000 #define PCIEM_SLOT_CAP_PSN 0xfff80000 #define PCIER_SLOT_CTL 0x18 #define PCIEM_SLOT_CTL_ABPE 0x0001 #define PCIEM_SLOT_CTL_PFDE 0x0002 #define PCIEM_SLOT_CTL_MRLSCE 0x0004 #define PCIEM_SLOT_CTL_PDCE 0x0008 #define PCIEM_SLOT_CTL_CCIE 0x0010 #define PCIEM_SLOT_CTL_HPIE 0x0020 #define PCIEM_SLOT_CTL_AIC 0x00c0 #define PCIEM_SLOT_CTL_PIC 0x0300 #define PCIEM_SLOT_CTL_PCC 0x0400 #define PCIEM_SLOT_CTL_EIC 0x0800 #define PCIEM_SLOT_CTL_DLLSCE 0x1000 #define PCIER_SLOT_STA 0x1a #define PCIEM_SLOT_STA_ABP 0x0001 #define PCIEM_SLOT_STA_PFD 0x0002 #define PCIEM_SLOT_STA_MRLSC 0x0004 #define PCIEM_SLOT_STA_PDC 0x0008 #define PCIEM_SLOT_STA_CC 0x0010 #define PCIEM_SLOT_STA_MRLSS 0x0020 #define PCIEM_SLOT_STA_PDS 0x0040 #define PCIEM_SLOT_STA_EIS 0x0080 #define PCIEM_SLOT_STA_DLLSC 0x0100 #define PCIER_ROOT_CTL 0x1c #define PCIEM_ROOT_CTL_SERR_CORR 0x0001 #define PCIEM_ROOT_CTL_SERR_NONFATAL 0x0002 #define PCIEM_ROOT_CTL_SERR_FATAL 0x0004 #define PCIEM_ROOT_CTL_PME 0x0008 #define PCIEM_ROOT_CTL_CRS_VIS 0x0010 #define PCIER_ROOT_CAP 0x1e #define PCIEM_ROOT_CAP_CRS_VIS 0x0001 #define PCIER_ROOT_STA 0x20 #define PCIEM_ROOT_STA_PME_REQID_MASK 0x0000ffff #define PCIEM_ROOT_STA_PME_STATUS 0x00010000 #define PCIEM_ROOT_STA_PME_PEND 0x00020000 #define PCIER_DEVICE_CAP2 0x24 #define PCIEM_CAP2_ARI 0x20 #define PCIER_DEVICE_CTL2 0x28 #define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f #define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010 #define PCIEM_CTL2_ARI 0x0020 #define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040 #define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080 #define PCIEM_CTL2_ID_ORDERED_REQ_EN 0x0100 #define PCIEM_CTL2_ID_ORDERED_CMP_EN 0x0200 #define PCIEM_CTL2_LTR_ENABLE 0x0400 #define PCIEM_CTL2_OBFF 0x6000 #define PCIEM_OBFF_DISABLE 0x0000 #define PCIEM_OBFF_MSGA_ENABLE 0x2000 #define PCIEM_OBFF_MSGB_ENABLE 0x4000 #define PCIEM_OBFF_WAKE_ENABLE 0x6000 #define PCIEM_CTL2_END2END_TLP 0x8000 #define PCIER_DEVICE_STA2 0x2a #define PCIER_LINK_CAP2 0x2c #define PCIER_LINK_CTL2 0x30 #define PCIER_LINK_STA2 0x32 #define PCIER_SLOT_CAP2 0x34 #define PCIER_SLOT_CTL2 0x38 #define PCIER_SLOT_STA2 0x3a /* MSI-X definitions */ #define PCIR_MSIX_CTRL 0x2 #define PCIM_MSIXCTRL_MSIX_ENABLE 0x8000 #define PCIM_MSIXCTRL_FUNCTION_MASK 0x4000 #define PCIM_MSIXCTRL_TABLE_SIZE 0x07FF #define PCIR_MSIX_TABLE 0x4 #define PCIR_MSIX_PBA 0x8 #define PCIM_MSIX_BIR_MASK 0x7 #define PCIM_MSIX_BIR_BAR_10 0 #define PCIM_MSIX_BIR_BAR_14 1 #define PCIM_MSIX_BIR_BAR_18 2 #define PCIM_MSIX_BIR_BAR_1C 3 #define PCIM_MSIX_BIR_BAR_20 4 #define PCIM_MSIX_BIR_BAR_24 5 #define PCIM_MSIX_VCTRL_MASK 0x1 /* PCI Advanced Features definitions */ #define PCIR_PCIAF_CAP 0x3 #define PCIM_PCIAFCAP_TP 0x01 #define PCIM_PCIAFCAP_FLR 0x02 #define PCIR_PCIAF_CTRL 0x4 #define PCIR_PCIAFCTRL_FLR 0x01 #define PCIR_PCIAF_STATUS 0x5 #define PCIR_PCIAFSTATUS_TP 0x01 /* Advanced Error Reporting */ #define PCIR_AER_UC_STATUS 0x04 #define PCIM_AER_UC_TRAINING_ERROR 0x00000001 #define PCIM_AER_UC_DL_PROTOCOL_ERROR 0x00000010 #define PCIM_AER_UC_SURPRISE_LINK_DOWN 0x00000020 #define PCIM_AER_UC_POISONED_TLP 0x00001000 #define PCIM_AER_UC_FC_PROTOCOL_ERROR 0x00002000 #define PCIM_AER_UC_COMPLETION_TIMEOUT 0x00004000 #define PCIM_AER_UC_COMPLETER_ABORT 0x00008000 #define PCIM_AER_UC_UNEXPECTED_COMPLETION 0x00010000 #define PCIM_AER_UC_RECEIVER_OVERFLOW 0x00020000 #define PCIM_AER_UC_MALFORMED_TLP 0x00040000 #define PCIM_AER_UC_ECRC_ERROR 0x00080000 #define PCIM_AER_UC_UNSUPPORTED_REQUEST 0x00100000 #define PCIM_AER_UC_ACS_VIOLATION 0x00200000 #define PCIM_AER_UC_INTERNAL_ERROR 0x00400000 #define PCIM_AER_UC_MC_BLOCKED_TLP 0x00800000 #define PCIM_AER_UC_ATOMIC_EGRESS_BLK 0x01000000 #define PCIM_AER_UC_TLP_PREFIX_BLOCKED 0x02000000 #define PCIR_AER_UC_MASK 0x08 /* Shares bits with UC_STATUS */ #define PCIR_AER_UC_SEVERITY 0x0c /* Shares bits with UC_STATUS */ #define PCIR_AER_COR_STATUS 0x10 #define PCIM_AER_COR_RECEIVER_ERROR 0x00000001 #define PCIM_AER_COR_BAD_TLP 0x00000040 #define PCIM_AER_COR_BAD_DLLP 0x00000080 #define PCIM_AER_COR_REPLAY_ROLLOVER 0x00000100 #define PCIM_AER_COR_REPLAY_TIMEOUT 0x00001000 #define PCIM_AER_COR_ADVISORY_NF_ERROR 0x00002000 #define PCIM_AER_COR_INTERNAL_ERROR 0x00004000 #define PCIM_AER_COR_HEADER_LOG_OVFLOW 0x00008000 #define PCIR_AER_COR_MASK 0x14 /* Shares bits with COR_STATUS */ #define PCIR_AER_CAP_CONTROL 0x18 #define PCIM_AER_FIRST_ERROR_PTR 0x0000001f #define PCIM_AER_ECRC_GEN_CAPABLE 0x00000020 #define PCIM_AER_ECRC_GEN_ENABLE 0x00000040 #define PCIM_AER_ECRC_CHECK_CAPABLE 0x00000080 #define PCIM_AER_ECRC_CHECK_ENABLE 0x00000100 #define PCIM_AER_MULT_HDR_CAPABLE 0x00000200 #define PCIM_AER_MULT_HDR_ENABLE 0x00000400 #define PCIM_AER_TLP_PREFIX_LOG_PRESENT 0x00000800 #define PCIR_AER_HEADER_LOG 0x1c #define PCIR_AER_ROOTERR_CMD 0x2c /* Only for root complex ports */ #define PCIM_AER_ROOTERR_COR_ENABLE 0x00000001 #define PCIM_AER_ROOTERR_NF_ENABLE 0x00000002 #define PCIM_AER_ROOTERR_F_ENABLE 0x00000004 #define PCIR_AER_ROOTERR_STATUS 0x30 /* Only for root complex ports */ #define PCIM_AER_ROOTERR_COR_ERR 0x00000001 #define PCIM_AER_ROOTERR_MULTI_COR_ERR 0x00000002 #define PCIM_AER_ROOTERR_UC_ERR 0x00000004 #define PCIM_AER_ROOTERR_MULTI_UC_ERR 0x00000008 #define PCIM_AER_ROOTERR_FIRST_UC_FATAL 0x00000010 #define PCIM_AER_ROOTERR_NF_ERR 0x00000020 #define PCIM_AER_ROOTERR_F_ERR 0x00000040 #define PCIM_AER_ROOTERR_INT_MESSAGE 0xf8000000 #define PCIR_AER_COR_SOURCE_ID 0x34 /* Only for root complex ports */ #define PCIR_AER_ERR_SOURCE_ID 0x36 /* Only for root complex ports */ #define PCIR_AER_TLP_PREFIX_LOG 0x38 /* Only for TLP prefix functions */ /* Virtual Channel definitions */ #define PCIR_VC_CAP1 0x04 #define PCIM_VC_CAP1_EXT_COUNT 0x00000007 #define PCIM_VC_CAP1_LOWPRI_EXT_COUNT 0x00000070 #define PCIR_VC_CAP2 0x08 #define PCIR_VC_CONTROL 0x0C #define PCIR_VC_STATUS 0x0E #define PCIR_VC_RESOURCE_CAP(n) (0x10 + (n) * 0x0C) #define PCIR_VC_RESOURCE_CTL(n) (0x14 + (n) * 0x0C) #define PCIR_VC_RESOURCE_STA(n) (0x18 + (n) * 0x0C) /* Serial Number definitions */ #define PCIR_SERIAL_LOW 0x04 #define PCIR_SERIAL_HIGH 0x08 /* SR-IOV definitions */ #define PCIR_SRIOV_CTL 0x08 #define PCIM_SRIOV_VF_EN 0x01 #define PCIM_SRIOV_VF_MSE 0x08 /* Memory space enable. */ #define PCIM_SRIOV_ARI_EN 0x10 #define PCIR_SRIOV_TOTAL_VFS 0x0E #define PCIR_SRIOV_NUM_VFS 0x10 #define PCIR_SRIOV_VF_OFF 0x14 #define PCIR_SRIOV_VF_STRIDE 0x16 #define PCIR_SRIOV_VF_DID 0x1A #define PCIR_SRIOV_PAGE_CAP 0x1C #define PCIR_SRIOV_PAGE_SIZE 0x20 #define PCI_SRIOV_BASE_PAGE_SHIFT 12 #define PCIR_SRIOV_BARS 0x24 #define PCIR_SRIOV_BAR(x) (PCIR_SRIOV_BARS + (x) * 4) /*- * Copyright (c) 2001 David E. O'Brien. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ /* * This is a Solaris compatibility header */ #ifndef _ELF_H_ #define _ELF_H_ #include #include #include #include #endif /* !_ELF_H_ */ #include /*- * Copyright (c) 2001 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _INTTYPES_H_ #define _INTTYPES_H_ #include #include #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef ___wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif typedef struct { intmax_t quot; /* Quotient. */ intmax_t rem; /* Remainder. */ } imaxdiv_t; __BEGIN_DECLS #ifdef _XLOCALE_H_ #include #endif intmax_t imaxabs(intmax_t) __pure2; imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2; intmax_t strtoimax(const char * __restrict, char ** __restrict, int); uintmax_t strtoumax(const char * __restrict, char ** __restrict, int); intmax_t wcstoimax(const wchar_t * __restrict, wchar_t ** __restrict, int); uintmax_t wcstoumax(const wchar_t * __restrict, wchar_t ** __restrict, int); __END_DECLS #endif /* !_INTTYPES_H_ */ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)limits.h 8.2 (Berkeley) 1/4/94 * $FreeBSD$ */ #ifndef _LIMITS_H_ #define _LIMITS_H_ #include #if __POSIX_VISIBLE #define _POSIX_ARG_MAX 4096 #define _POSIX_LINK_MAX 8 #define _POSIX_MAX_CANON 255 #define _POSIX_MAX_INPUT 255 #define _POSIX_NAME_MAX 14 #define _POSIX_PIPE_BUF 512 #define _POSIX_SSIZE_MAX 32767 #define _POSIX_STREAM_MAX 8 #if __POSIX_VISIBLE >= 200112 #define _POSIX_CHILD_MAX 25 #define _POSIX_NGROUPS_MAX 8 #define _POSIX_OPEN_MAX 20 #define _POSIX_PATH_MAX 256 #define _POSIX_TZNAME_MAX 6 #else #define _POSIX_CHILD_MAX 6 #define _POSIX_NGROUPS_MAX 0 #define _POSIX_OPEN_MAX 16 #define _POSIX_PATH_MAX 255 #define _POSIX_TZNAME_MAX 3 #endif #if __POSIX_VISIBLE >= 200112 #define BC_BASE_MAX 99 /* max ibase/obase values in bc(1) */ #define BC_DIM_MAX 2048 /* max array elements in bc(1) */ #define BC_SCALE_MAX 99 /* max scale value in bc(1) */ #define BC_STRING_MAX 1000 /* max const string length in bc(1) */ #define CHARCLASS_NAME_MAX 14 /* max character class name size */ #define COLL_WEIGHTS_MAX 10 /* max weights for order keyword */ #define EXPR_NEST_MAX 32 /* max expressions nested in expr(1) */ #define LINE_MAX 2048 /* max bytes in an input line */ #define RE_DUP_MAX 255 /* max RE's in interval notation */ #define _POSIX2_BC_BASE_MAX 99 #define _POSIX2_BC_DIM_MAX 2048 #define _POSIX2_BC_SCALE_MAX 99 #define _POSIX2_BC_STRING_MAX 1000 #define _POSIX2_CHARCLASS_NAME_MAX 14 #define _POSIX2_COLL_WEIGHTS_MAX 2 #define _POSIX2_EQUIV_CLASS_MAX 2 #define _POSIX2_EXPR_NEST_MAX 32 #define _POSIX2_LINE_MAX 2048 #define _POSIX2_RE_DUP_MAX 255 #endif #endif #if __POSIX_VISIBLE >= 199309 #define _POSIX_AIO_LISTIO_MAX 2 #define _POSIX_AIO_MAX 1 #define _POSIX_DELAYTIMER_MAX 32 #define _POSIX_MQ_OPEN_MAX 8 #define _POSIX_MQ_PRIO_MAX 32 #define _POSIX_RTSIG_MAX 8 #define _POSIX_SEM_NSEMS_MAX 256 #define _POSIX_SEM_VALUE_MAX 32767 #define _POSIX_SIGQUEUE_MAX 32 #define _POSIX_TIMER_MAX 32 #define _POSIX_CLOCKRES_MIN 20000000 #endif #if __POSIX_VISIBLE >= 199506 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 #define _POSIX_THREAD_KEYS_MAX 128 #define _POSIX_THREAD_THREADS_MAX 64 #endif #if __POSIX_VISIBLE >= 200112 #define _POSIX_HOST_NAME_MAX 255 #define _POSIX_LOGIN_NAME_MAX 9 #define _POSIX_SS_REPL_MAX 4 #define _POSIX_SYMLINK_MAX 255 #define _POSIX_SYMLOOP_MAX 8 #define _POSIX_TRACE_EVENT_NAME_MAX 30 #define _POSIX_TRACE_NAME_MAX 8 #define _POSIX_TRACE_SYS_MAX 8 #define _POSIX_TRACE_USER_EVENT_MAX 32 #define _POSIX_TTY_NAME_MAX 9 #define _POSIX_RE_DUP_MAX _POSIX2_RE_DUP_MAX #endif #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 #define NL_ARGMAX 99 /* max # of position args for printf */ #define NL_MSGMAX 32767 #define NL_SETMAX 255 #define NL_TEXTMAX 2048 #endif #if __XSI_VISIBLE #define _XOPEN_IOV_MAX 16 #define _XOPEN_NAME_MAX 255 #define _XOPEN_PATH_MAX 1024 #define PASS_MAX 128 /* _PASSWORD_LEN from */ #define NL_LANGMAX 31 /* max LANG name length */ #define NL_NMAX 1 #endif #define MB_LEN_MAX 6 /* 31-bit UTF-8 */ #include #if __POSIX_VISIBLE #include #endif #endif /* !_LIMITS_H_ */ /* * Copyright (c) 1993 Paul Kranenburg * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Paul Kranenburg. * 4. 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 ``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 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. * * $FreeBSD$ */ #include /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ /* * from: @(#)fdlibm.h 5.1 93/09/24 * $FreeBSD$ */ #ifndef _MATH_H_ #define _MATH_H_ #include #include #include /* * ANSI/POSIX */ extern const union __infinity_un { unsigned char __uc[8]; double __ud; } __infinity; extern const union __nan_un { unsigned char __uc[sizeof(float)]; float __uf; } __nan; #if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) #define __MATH_BUILTIN_CONSTANTS #endif #if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER) #define __MATH_BUILTIN_RELOPS #endif #ifdef __MATH_BUILTIN_CONSTANTS #define HUGE_VAL __builtin_huge_val() #else #define HUGE_VAL (__infinity.__ud) #endif #if __ISO_C_VISIBLE >= 1999 #define FP_ILOGB0 (-__INT_MAX) #define FP_ILOGBNAN __INT_MAX #ifdef __MATH_BUILTIN_CONSTANTS #define HUGE_VALF __builtin_huge_valf() #define HUGE_VALL __builtin_huge_vall() #define INFINITY __builtin_inff() #define NAN __builtin_nanf("") #else #define HUGE_VALF (float)HUGE_VAL #define HUGE_VALL (long double)HUGE_VAL #define INFINITY HUGE_VALF #define NAN (__nan.__uf) #endif /* __MATH_BUILTIN_CONSTANTS */ #define MATH_ERRNO 1 #define MATH_ERREXCEPT 2 #define math_errhandling MATH_ERREXCEPT #define FP_FAST_FMAF 1 /* Symbolic constants to classify floating point numbers. */ #define FP_INFINITE 0x01 #define FP_NAN 0x02 #define FP_NORMAL 0x04 #define FP_SUBNORMAL 0x08 #define FP_ZERO 0x10 #if (__STDC_VERSION__ >= 201112L && defined(__clang__)) || \ __has_extension(c_generic_selections) #define __fp_type_select(x, f, d, ld) _Generic((x), \ float: f(x), \ double: d(x), \ long double: ld(x), \ volatile float: f(x), \ volatile double: d(x), \ volatile long double: ld(x), \ volatile const float: f(x), \ volatile const double: d(x), \ volatile const long double: ld(x), \ const float: f(x), \ const double: d(x), \ const long double: ld(x)) #elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus) #define __fp_type_select(x, f, d, ld) __builtin_choose_expr( \ __builtin_types_compatible_p(__typeof(x), long double), ld(x), \ __builtin_choose_expr( \ __builtin_types_compatible_p(__typeof(x), double), d(x), \ __builtin_choose_expr( \ __builtin_types_compatible_p(__typeof(x), float), f(x), (void)0))) #else #define __fp_type_select(x, f, d, ld) \ ((sizeof(x) == sizeof(float)) ? f(x) \ : (sizeof(x) == sizeof(double)) ? d(x) \ : ld(x)) #endif #define fpclassify(x) \ __fp_type_select(x, __fpclassifyf, __fpclassifyd, __fpclassifyl) #define isfinite(x) __fp_type_select(x, __isfinitef, __isfinite, __isfinitel) #define isinf(x) __fp_type_select(x, __isinff, __isinf, __isinfl) #define isnan(x) \ __fp_type_select(x, __inline_isnanf, __inline_isnan, __inline_isnanl) #define isnormal(x) __fp_type_select(x, __isnormalf, __isnormal, __isnormall) #ifdef __MATH_BUILTIN_RELOPS #define isgreater(x, y) __builtin_isgreater((x), (y)) #define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y)) #define isless(x, y) __builtin_isless((x), (y)) #define islessequal(x, y) __builtin_islessequal((x), (y)) #define islessgreater(x, y) __builtin_islessgreater((x), (y)) #define isunordered(x, y) __builtin_isunordered((x), (y)) #else #define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y)) #define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y)) #define isless(x, y) (!isunordered((x), (y)) && (x) < (y)) #define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y)) #define islessgreater(x, y) (!isunordered((x), (y)) && \ ((x) > (y) || (y) > (x))) #define isunordered(x, y) (isnan(x) || isnan(y)) #endif /* __MATH_BUILTIN_RELOPS */ #define signbit(x) __fp_type_select(x, __signbitf, __signbit, __signbitl) typedef __double_t double_t; typedef __float_t float_t; #endif /* __ISO_C_VISIBLE >= 1999 */ /* * XOPEN/SVID */ #if __BSD_VISIBLE || __XSI_VISIBLE #define M_E 2.7182818284590452354 /* e */ #define M_LOG2E 1.4426950408889634074 /* log 2e */ #define M_LOG10E 0.43429448190325182765 /* log 10e */ #define M_LN2 0.69314718055994530942 /* log e2 */ #define M_LN10 2.30258509299404568402 /* log e10 */ #define M_PI 3.14159265358979323846 /* pi */ #define M_PI_2 1.57079632679489661923 /* pi/2 */ #define M_PI_4 0.78539816339744830962 /* pi/4 */ #define M_1_PI 0.31830988618379067154 /* 1/pi */ #define M_2_PI 0.63661977236758134308 /* 2/pi */ #define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #define MAXFLOAT ((float)3.40282346638528860e+38) extern int signgam; #endif /* __BSD_VISIBLE || __XSI_VISIBLE */ #if __BSD_VISIBLE #if 0 /* Old value from 4.4BSD-Lite math.h; this is probably better. */ #define HUGE HUGE_VAL #else #define HUGE MAXFLOAT #endif #endif /* __BSD_VISIBLE */ /* * Most of these functions depend on the rounding mode and have the side * effect of raising floating-point exceptions, so they are not declared * as __pure2. In C99, FENV_ACCESS affects the purity of these functions. */ __BEGIN_DECLS /* * ANSI/POSIX */ int __fpclassifyd(double) __pure2; int __fpclassifyf(float) __pure2; int __fpclassifyl(long double) __pure2; int __isfinitef(float) __pure2; int __isfinite(double) __pure2; int __isfinitel(long double) __pure2; int __isinff(float) __pure2; int __isinf(double) __pure2; int __isinfl(long double) __pure2; int __isnormalf(float) __pure2; int __isnormal(double) __pure2; int __isnormall(long double) __pure2; int __signbit(double) __pure2; int __signbitf(float) __pure2; int __signbitl(long double) __pure2; static __inline int __inline_isnan(__const double __x) { return (__x != __x); } static __inline int __inline_isnanf(__const float __x) { return (__x != __x); } static __inline int __inline_isnanl(__const long double __x) { return (__x != __x); } /* * Version 2 of the Single UNIX Specification (UNIX98) defined isnan() and * isinf() as functions taking double. C99, and the subsequent POSIX revisions * (SUSv3, POSIX.1-2001, define it as a macro that accepts any real floating * point type. If we are targeting SUSv2 and C99 or C11 (or C++11) then we * expose the newer definition, assuming that the language spec takes * precedence over the operating system interface spec. */ #if __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600 && __ISO_C_VISIBLE < 1999 #undef isinf #undef isnan int isinf(double); int isnan(double); #endif double acos(double); double asin(double); double atan(double); double atan2(double, double); double cos(double); double sin(double); double tan(double); double cosh(double); double sinh(double); double tanh(double); double exp(double); double frexp(double, int *); /* fundamentally !__pure2 */ double ldexp(double, int); double log(double); double log10(double); double modf(double, double *); /* fundamentally !__pure2 */ double pow(double, double); double sqrt(double); double ceil(double); double fabs(double) __pure2; double floor(double); double fmod(double, double); /* * These functions are not in C90. */ #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE double acosh(double); double asinh(double); double atanh(double); double cbrt(double); double erf(double); double erfc(double); double exp2(double); double expm1(double); double fma(double, double, double); double hypot(double, double); int ilogb(double) __pure2; double lgamma(double); long long llrint(double); long long llround(double); double log1p(double); double log2(double); double logb(double); long lrint(double); long lround(double); double nan(const char *) __pure2; double nextafter(double, double); double remainder(double, double); double remquo(double, double, int *); double rint(double); #endif /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */ #if __BSD_VISIBLE || __XSI_VISIBLE double j0(double); double j1(double); double jn(int, double); double y0(double); double y1(double); double yn(int, double); #if __XSI_VISIBLE <= 500 || __BSD_VISIBLE double gamma(double); #endif #if __XSI_VISIBLE <= 600 || __BSD_VISIBLE double scalb(double, double); #endif #endif /* __BSD_VISIBLE || __XSI_VISIBLE */ #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 double copysign(double, double) __pure2; double fdim(double, double); double fmax(double, double) __pure2; double fmin(double, double) __pure2; double nearbyint(double); double round(double); double scalbln(double, long); double scalbn(double, int); double tgamma(double); double trunc(double); #endif /* * BSD math library entry points */ #if __BSD_VISIBLE double drem(double, double); int finite(double) __pure2; int isnanf(float) __pure2; /* * Reentrant version of gamma & lgamma; passes signgam back by reference * as the second argument; user must allocate space for signgam. */ double gamma_r(double, int *); double lgamma_r(double, int *); /* * IEEE Test Vector */ double significand(double); #endif /* __BSD_VISIBLE */ /* float versions of ANSI/POSIX functions */ #if __ISO_C_VISIBLE >= 1999 float acosf(float); float asinf(float); float atanf(float); float atan2f(float, float); float cosf(float); float sinf(float); float tanf(float); float coshf(float); float sinhf(float); float tanhf(float); float exp2f(float); float expf(float); float expm1f(float); float frexpf(float, int *); /* fundamentally !__pure2 */ int ilogbf(float) __pure2; float ldexpf(float, int); float log10f(float); float log1pf(float); float log2f(float); float logf(float); float modff(float, float *); /* fundamentally !__pure2 */ float powf(float, float); float sqrtf(float); float ceilf(float); float fabsf(float) __pure2; float floorf(float); float fmodf(float, float); float roundf(float); float erff(float); float erfcf(float); float hypotf(float, float); float lgammaf(float); float tgammaf(float); float acoshf(float); float asinhf(float); float atanhf(float); float cbrtf(float); float logbf(float); float copysignf(float, float) __pure2; long long llrintf(float); long long llroundf(float); long lrintf(float); long lroundf(float); float nanf(const char *) __pure2; float nearbyintf(float); float nextafterf(float, float); float remainderf(float, float); float remquof(float, float, int *); float rintf(float); float scalblnf(float, long); float scalbnf(float, int); float truncf(float); float fdimf(float, float); float fmaf(float, float, float); float fmaxf(float, float) __pure2; float fminf(float, float) __pure2; #endif /* * float versions of BSD math library entry points */ #if __BSD_VISIBLE float dremf(float, float); int finitef(float) __pure2; float gammaf(float); float j0f(float); float j1f(float); float jnf(int, float); float scalbf(float, float); float y0f(float); float y1f(float); float ynf(int, float); /* * Float versions of reentrant version of gamma & lgamma; passes * signgam back by reference as the second argument; user must * allocate space for signgam. */ float gammaf_r(float, int *); float lgammaf_r(float, int *); /* * float version of IEEE Test Vector */ float significandf(float); #endif /* __BSD_VISIBLE */ /* * long double versions of ISO/POSIX math functions */ #if __ISO_C_VISIBLE >= 1999 long double acoshl(long double); long double acosl(long double); long double asinhl(long double); long double asinl(long double); long double atan2l(long double, long double); long double atanhl(long double); long double atanl(long double); long double cbrtl(long double); long double ceill(long double); long double copysignl(long double, long double) __pure2; long double coshl(long double); long double cosl(long double); long double erfcl(long double); long double erfl(long double); long double exp2l(long double); long double expl(long double); long double expm1l(long double); long double fabsl(long double) __pure2; long double fdiml(long double, long double); long double floorl(long double); long double fmal(long double, long double, long double); long double fmaxl(long double, long double) __pure2; long double fminl(long double, long double) __pure2; long double fmodl(long double, long double); long double frexpl(long double value, int *); /* fundamentally !__pure2 */ long double hypotl(long double, long double); int ilogbl(long double) __pure2; long double ldexpl(long double, int); long double lgammal(long double); long long llrintl(long double); long long llroundl(long double); long double log10l(long double); long double log1pl(long double); long double log2l(long double); long double logbl(long double); long double logl(long double); long lrintl(long double); long lroundl(long double); long double modfl(long double, long double *); /* fundamentally !__pure2 */ long double nanl(const char *) __pure2; long double nearbyintl(long double); long double nextafterl(long double, long double); double nexttoward(double, long double); float nexttowardf(float, long double); long double nexttowardl(long double, long double); long double powl(long double, long double); long double remainderl(long double, long double); long double remquol(long double, long double, int *); long double rintl(long double); long double roundl(long double); long double scalblnl(long double, long); long double scalbnl(long double, int); long double sinhl(long double); long double sinl(long double); long double sqrtl(long double); long double tanhl(long double); long double tanl(long double); long double tgammal(long double); long double truncl(long double); #endif /* __ISO_C_VISIBLE >= 1999 */ #if __BSD_VISIBLE long double lgammal_r(long double, int *); #endif __END_DECLS #endif /* !_MATH_H_ */ /* * Fundamental constants relating to ethernet. * * $FreeBSD$ * */ #ifndef _NET_ETHERNET_H_ #define _NET_ETHERNET_H_ /* * Some basic Ethernet constants. */ #define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ #define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */ #define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */ #define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) #define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */ #define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */ #define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */ #define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */ /* * Mbuf adjust factor to force 32-bit alignment of IP header. * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a * receive so the upper layers get the IP header properly aligned * past the 14-byte Ethernet header. */ #define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */ /* * Compute the maximum frame size based on ethertype (i.e. possible * encapsulation) and whether or not an FCS is present. */ #define ETHER_MAX_FRAME(ifp, etype, hasfcs) \ ((ifp)->if_mtu + ETHER_HDR_LEN + \ ((hasfcs) ? ETHER_CRC_LEN : 0) + \ (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0)) /* * Ethernet-specific mbuf flags. */ #define M_HASFCS M_PROTO5 /* FCS included at end of frame */ /* * Ethernet CRC32 polynomials (big- and little-endian verions). */ #define ETHER_CRC_POLY_LE 0xedb88320 #define ETHER_CRC_POLY_BE 0x04c11db6 /* * A macro to validate a length with */ #define ETHER_IS_VALID_LEN(foo) \ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) /* * Structure of a 10Mb/s Ethernet header. */ struct ether_header { u_char ether_dhost[ETHER_ADDR_LEN]; u_char ether_shost[ETHER_ADDR_LEN]; u_short ether_type; } __packed; /* * Structure of a 48-bit Ethernet address. */ struct ether_addr { u_char octet[ETHER_ADDR_LEN]; } __packed; #define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ /* * 802.1q Virtual LAN header. */ struct ether_vlan_header { uint8_t evl_dhost[ETHER_ADDR_LEN]; uint8_t evl_shost[ETHER_ADDR_LEN]; uint16_t evl_encap_proto; uint16_t evl_tag; uint16_t evl_proto; } __packed; #define EVL_VLID_MASK 0x0FFF #define EVL_PRI_MASK 0xE000 #define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) #define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7) #define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) #define EVL_MAKETAG(vlid, pri, cfi) \ ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) /* * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. * However, there are some conflicts. */ #define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */ /* 0x0101 .. 0x1FF Experimental */ #define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */ #define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */ #define ETHERTYPE_SPRITE 0x0500 /* ??? */ /* 0x0400 Nixdorf */ #define ETHERTYPE_NS 0x0600 /* XNS */ #define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */ #define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */ #define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */ #define ETHERTYPE_IP 0x0800 /* IP protocol */ #define ETHERTYPE_X75 0x0801 /* X.75 Internet */ #define ETHERTYPE_NBS 0x0802 /* NBS Internet */ #define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */ #define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */ #define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */ #define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */ #define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */ #define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */ /* 0x081C Symbolics Private */ /* 0x0888 - 0x088A Xyplex */ #define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */ #define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */ #define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */ #define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */ #define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */ #define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */ /* 0x1000 - 0x100F Berkeley Trailer */ /* * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have * (type-ETHERTYPE_TRAIL)*512 bytes of data followed * by an ETHER type (as given above) and then the (variable-length) header. */ #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ #define ETHERTYPE_NTRAILER 16 #define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */ #define ETHERTYPE_VALID 0x1600 /* VALID system protocol */ #define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */ #define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */ /* The following 3C0x types are unregistered: */ #define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */ #define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */ #define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */ #define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect response not registered */ #define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */ #define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */ #define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */ #define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */ #define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */ #define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */ #define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete NetBIOS name not registered */ #define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */ #define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */ #define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */ #define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */ #define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */ #define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */ #define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */ #define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */ #define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */ #define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */ #define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */ #define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */ #define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */ #define ETHERTYPE_LAT 0x6004 /* DEC LAT */ #define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */ #define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */ #define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */ #define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */ #define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */ /* 0x6010 - 0x6014 3Com Corporation */ #define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/ #define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */ #define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */ #define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */ #define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */ #define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */ #define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */ #define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */ #define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */ /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */ #define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */ #define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */ #define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */ #define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */ #define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */ #define ETHERTYPE_HP 0x8005 /* HP Probe */ #define ETHERTYPE_NESTAR 0x8006 /* Nestar */ #define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */ #define ETHERTYPE_EXCELAN 0x8010 /* Excelan */ #define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */ #define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */ #define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */ #define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */ #define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */ #define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */ #define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */ #define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */ #define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */ #define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */ #define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */ #define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */ #define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */ #define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */ #define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */ #define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */ #define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */ #define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */ #define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */ #define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */ /* 0x8042 DEC Unassigned */ #define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */ /* 0x8046 - 0x8047 AT&T */ #define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */ #define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */ #define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */ #define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */ #define ETHERTYPE_ES 0x805D /* Evans & Sutherland */ #define ETHERTYPE_LITTLE 0x8060 /* Little Machines */ #define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */ /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */ #define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */ #define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */ #define ETHERTYPE_ATT 0x8069 /* AT&T */ #define ETHERTYPE_AUTOPHON 0x806A /* Autophon */ #define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */ #define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */ /* 0x806E - 0x8077 Landmark Graphics Corp. */ #define ETHERTYPE_MATRA 0x807A /* Matra */ #define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */ #define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */ /* 0x807D - 0x807F Vitalink Communications */ #define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */ /* 0x8081 - 0x8083 Counterpoint Computers */ /* 0x8088 - 0x808A Xyplex */ #define ETHERTYPE_ATALK 0x809B /* AppleTalk */ #define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */ #define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */ /* 0x809C - 0x809E Datability */ #define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */ /* 0x80A3 Nixdorf */ /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */ /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */ /* 0x80C4 - 0x80C5 Banyan Systems */ #define ETHERTYPE_PACER 0x80C6 /* Pacer Software */ #define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */ /* 0x80C8 - 0x80CC Intergraph Corporation */ /* 0x80CD - 0x80CE Harris Corporation */ /* 0x80CF - 0x80D2 Taylor Instrument */ /* 0x80D3 - 0x80D4 Rosemount Corporation */ #define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */ #define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */ /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */ /* 0x80E0 - 0x80E3 Allen-Bradley */ /* 0x80E4 - 0x80F0 Datability */ #define ETHERTYPE_RETIX 0x80F2 /* Retix */ #define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */ /* 0x80F4 - 0x80F5 Kinetics */ #define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */ #define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */ /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */ #define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */ #define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */ /* 0x8107 - 0x8109 Symbolics Private */ #define ETHERTYPE_TALARIS 0x812B /* Talaris */ #define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */ #define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */ #define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */ /* 0x8132 - 0x8137 Bridge Communications */ #define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */ #define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */ /* 0x8139 - 0x813D KTI */ #define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */ #define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */ #define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */ #define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */ #define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */ #define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */ #define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */ #define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */ /* 0x814D - 0x814E BIIN */ #define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */ #define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */ /* 0x8151 - 0x8153 Qualcomm */ /* 0x815C - 0x815E Computer Protocol Pty Ltd */ /* 0x8164 - 0x8166 Charles River Data Systems */ #define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */ #define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */ #define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */ #define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */ /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */ /* 0x8184 - 0x818C SGI prop. */ #define ETHERTYPE_MOTOROLA 0x818D /* Motorola */ #define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */ /* 0x819A - 0x81A3 RAD Network Devices */ /* 0x81B7 - 0x81B9 Xyplex */ /* 0x81CC - 0x81D5 Apricot Computers */ /* 0x81D6 - 0x81DD Artisoft Lantastic */ /* 0x81E6 - 0x81EF Polygon */ /* 0x81F0 - 0x81F2 Comsat Labs */ /* 0x81F3 - 0x81F5 SAIC */ /* 0x81F6 - 0x81F8 VG Analytical */ /* 0x8203 - 0x8205 QNX Software Systems Ltd. */ /* 0x8221 - 0x8222 Ascom Banking Systems */ /* 0x823E - 0x8240 Advanced Encryption Systems */ /* 0x8263 - 0x826A Charles River Data Systems */ /* 0x827F - 0x8282 Athena Programming */ /* 0x829A - 0x829B Inst Ind Info Tech */ /* 0x829C - 0x82AB Taurus Controls */ /* 0x82AC - 0x8693 Walker Richer & Quinn */ #define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */ #define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */ #define ETHERTYPE_KALPANA 0x8582 /* Kalpana */ /* 0x8694 - 0x869D Idea Courier */ /* 0x869E - 0x86A1 Computer Network Tech */ /* 0x86A3 - 0x86AC Gateway Communications */ #define ETHERTYPE_SECTRA 0x86DB /* SECTRA */ #define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */ #define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */ #define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */ /* 0x86E0 - 0x86EF Landis & Gyr Powers */ /* 0x8700 - 0x8710 Motorola */ #define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */ #define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */ /* 0x873B - 0x873C Control Technology Inc. Proprietary */ #define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */ #define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */ #define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */ #define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */ #define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */ #define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPoE) */ #define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */ #define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */ #define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */ #define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */ #define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ #define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ #define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */ #define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ #define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */ #define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */ #define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */ #define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */ #define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */ #define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */ #define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */ #define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */ /* 0xFF00 - 0xFFOF ISC Bunker Ramo */ #define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */ /* * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have * (type-ETHERTYPE_TRAIL)*512 bytes of data followed * by an ETHER type (as given above) and then the (variable-length) header. */ #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ #define ETHERTYPE_NTRAILER 16 #define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN) #define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN) #define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN) /* * The ETHER_BPF_MTAP macro should be used by drivers which support hardware * offload for VLAN tag processing. It will check the mbuf to see if it has * M_VLANTAG set, and if it does, will pass the packet along to * ether_vlan_mtap. This function will re-insert VLAN tags for the duration * of the tap, so they show up properly for network analyzers. */ #define ETHER_BPF_MTAP(_ifp, _m) do { \ if (bpf_peers_present((_ifp)->if_bpf)) { \ M_ASSERTVALID(_m); \ if (((_m)->m_flags & M_VLANTAG) != 0) \ ether_vlan_mtap((_ifp)->if_bpf, (_m), NULL, 0); \ else \ bpf_mtap((_ifp)->if_bpf, (_m)); \ } \ } while (0) #ifdef _KERNEL struct ifnet; struct mbuf; struct route; struct sockaddr; struct bpf_if; extern uint32_t ether_crc32_le(const uint8_t *, size_t); extern uint32_t ether_crc32_be(const uint8_t *, size_t); extern void ether_demux(struct ifnet *, struct mbuf *); extern void ether_ifattach(struct ifnet *, const u_int8_t *); extern void ether_ifdetach(struct ifnet *); extern int ether_ioctl(struct ifnet *, u_long, caddr_t); extern int ether_output(struct ifnet *, struct mbuf *, const struct sockaddr *, struct route *); extern int ether_output_frame(struct ifnet *, struct mbuf *); extern char *ether_sprintf(const u_int8_t *); void ether_vlan_mtap(struct bpf_if *, struct mbuf *, void *, u_int); struct mbuf *ether_vlanencap(struct mbuf *, uint16_t); #else /* _KERNEL */ #include /* * Ethernet address conversion/parsing routines. */ __BEGIN_DECLS struct ether_addr *ether_aton(const char *); struct ether_addr *ether_aton_r(const char *, struct ether_addr *); int ether_hostton(const char *, struct ether_addr *); int ether_line(const char *, struct ether_addr *, char *); char *ether_ntoa(const struct ether_addr *); char *ether_ntoa_r(const struct ether_addr *, char *); int ether_ntohost(char *, const struct ether_addr *); __END_DECLS #endif /* !_KERNEL */ #endif /* !_NET_ETHERNET_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)if.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NET_IF_H_ #define _NET_IF_H_ #include #if __BSD_VISIBLE /* * does not depend on on most other systems. This * helps userland compatibility. (struct timeval ifi_lastchange) * The same holds for . (struct sockaddr ifru_addr) */ #ifndef _KERNEL #include #include #endif #endif /* * Length of interface external name, including terminating '\0'. * Note: this is the same size as a generic device's external name. */ #define IF_NAMESIZE 16 #if __BSD_VISIBLE #define IFNAMSIZ IF_NAMESIZE #define IF_MAXUNIT 0x7fff /* historical value */ #endif #if __BSD_VISIBLE /* * Structure used to query names of interface cloners. */ struct if_clonereq { int ifcr_total; /* total cloners (out) */ int ifcr_count; /* room for this many in user buffer */ char *ifcr_buffer; /* buffer for cloner names */ }; /* * Structure describing information about an interface * which may be of interest to management entities. */ struct if_data { /* generic interface information */ uint8_t ifi_type; /* ethernet, tokenring, etc */ uint8_t ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ uint8_t ifi_addrlen; /* media address length */ uint8_t ifi_hdrlen; /* media header length */ uint8_t ifi_link_state; /* current link state */ uint8_t ifi_vhid; /* carp vhid */ uint16_t ifi_datalen; /* length of this data struct */ uint32_t ifi_mtu; /* maximum transmission unit */ uint32_t ifi_metric; /* routing metric (external only) */ uint64_t ifi_baudrate; /* linespeed */ /* volatile statistics */ uint64_t ifi_ipackets; /* packets received on interface */ uint64_t ifi_ierrors; /* input errors on interface */ uint64_t ifi_opackets; /* packets sent on interface */ uint64_t ifi_oerrors; /* output errors on interface */ uint64_t ifi_collisions; /* collisions on csma interfaces */ uint64_t ifi_ibytes; /* total number of octets received */ uint64_t ifi_obytes; /* total number of octets sent */ uint64_t ifi_imcasts; /* packets received via multicast */ uint64_t ifi_omcasts; /* packets sent via multicast */ uint64_t ifi_iqdrops; /* dropped on input */ uint64_t ifi_oqdrops; /* dropped on output */ uint64_t ifi_noproto; /* destined for unsupported protocol */ uint64_t ifi_hwassist; /* HW offload capabilities, see IFCAP */ /* Unions are here to make sizes MI. */ union { /* uptime at attach or stat reset */ time_t tt; uint64_t ph; } __ifi_epoch; #define ifi_epoch __ifi_epoch.tt union { /* time of last administrative change */ struct timeval tv; struct { uint64_t ph1; uint64_t ph2; } ph; } __ifi_lastchange; #define ifi_lastchange __ifi_lastchange.tv }; /*- * Interface flags are of two types: network stack owned flags, and driver * owned flags. Historically, these values were stored in the same ifnet * flags field, but with the advent of fine-grained locking, they have been * broken out such that the network stack is responsible for synchronizing * the stack-owned fields, and the device driver the device-owned fields. * Both halves can perform lockless reads of the other half's field, subject * to accepting the involved races. * * Both sets of flags come from the same number space, and should not be * permitted to conflict, as they are exposed to user space via a single * field. * * The following symbols identify read and write requirements for fields: * * (i) if_flags field set by device driver before attach, read-only there * after. * (n) if_flags field written only by the network stack, read by either the * stack or driver. * (d) if_drv_flags field written only by the device driver, read by either * the stack or driver. */ #define IFF_UP 0x1 /* (n) interface is up */ #define IFF_BROADCAST 0x2 /* (i) broadcast address valid */ #define IFF_DEBUG 0x4 /* (n) turn on debugging */ #define IFF_LOOPBACK 0x8 /* (i) is a loopback net */ #define IFF_POINTOPOINT 0x10 /* (i) is a point-to-point link */ /* 0x20 was IFF_SMART */ #define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */ #define IFF_NOARP 0x80 /* (n) no address resolution protocol */ #define IFF_PROMISC 0x100 /* (n) receive all packets */ #define IFF_ALLMULTI 0x200 /* (n) receive all multicast packets */ #define IFF_DRV_OACTIVE 0x400 /* (d) tx hardware queue is full */ #define IFF_SIMPLEX 0x800 /* (i) can't hear own transmissions */ #define IFF_LINK0 0x1000 /* per link layer defined bit */ #define IFF_LINK1 0x2000 /* per link layer defined bit */ #define IFF_LINK2 0x4000 /* per link layer defined bit */ #define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */ #define IFF_MULTICAST 0x8000 /* (i) supports multicast */ #define IFF_CANTCONFIG 0x10000 /* (i) unconfigurable using ioctl(2) */ #define IFF_PPROMISC 0x20000 /* (n) user-requested promisc mode */ #define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */ #define IFF_STATICARP 0x80000 /* (n) static ARP */ #define IFF_DYING 0x200000 /* (n) interface is winding down */ #define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ /* * Old names for driver flags so that user space tools can continue to use * the old (portable) names. */ #ifndef _KERNEL #define IFF_RUNNING IFF_DRV_RUNNING #define IFF_OACTIVE IFF_DRV_OACTIVE #endif /* flags set internally only: */ #define IFF_CANTCHANGE \ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC|\ IFF_DYING|IFF_CANTCONFIG) /* * Values for if_link_state. */ #define LINK_STATE_UNKNOWN 0 /* link invalid/unknown */ #define LINK_STATE_DOWN 1 /* link is down */ #define LINK_STATE_UP 2 /* link is up */ /* * Some convenience macros used for setting ifi_baudrate. * XXX 1000 vs. 1024? --thorpej@netbsd.org */ #define IF_Kbps(x) ((uintmax_t)(x) * 1000) /* kilobits/sec. */ #define IF_Mbps(x) (IF_Kbps((x) * 1000)) /* megabits/sec. */ #define IF_Gbps(x) (IF_Mbps((x) * 1000)) /* gigabits/sec. */ /* * Capabilities that interfaces can advertise. * * struct ifnet.if_capabilities * contains the optional features & capabilities a particular interface * supports (not only the driver but also the detected hw revision). * Capabilities are defined by IFCAP_* below. * struct ifnet.if_capenable * contains the enabled (either by default or through ifconfig) optional * features & capabilities on this interface. * Capabilities are defined by IFCAP_* below. * struct if_data.ifi_hwassist in mbuf CSUM_ flag form, controlled by above * contains the enabled optional feature & capabilites that can be used * individually per packet and are specified in the mbuf pkthdr.csum_flags * field. IFCAP_* and CSUM_* do not match one to one and CSUM_* may be * more detailed or differenciated than IFCAP_*. * Hwassist features are defined CSUM_* in sys/mbuf.h * * Capabilities that cannot be arbitrarily changed with ifconfig/ioctl * are listed in IFCAP_CANTCHANGE, similar to IFF_CANTCHANGE. * This is not strictly necessary because the common code never * changes capabilities, and it is left to the individual driver * to do the right thing. However, having the filter here * avoids replication of the same code in all individual drivers. */ #define IFCAP_RXCSUM 0x00001 /* can offload checksum on RX */ #define IFCAP_TXCSUM 0x00002 /* can offload checksum on TX */ #define IFCAP_NETCONS 0x00004 /* can be a network console */ #define IFCAP_VLAN_MTU 0x00008 /* VLAN-compatible MTU */ #define IFCAP_VLAN_HWTAGGING 0x00010 /* hardware VLAN tag support */ #define IFCAP_JUMBO_MTU 0x00020 /* 9000 byte MTU supported */ #define IFCAP_POLLING 0x00040 /* driver supports polling */ #define IFCAP_VLAN_HWCSUM 0x00080 /* can do IFCAP_HWCSUM on VLANs */ #define IFCAP_TSO4 0x00100 /* can do TCP Segmentation Offload */ #define IFCAP_TSO6 0x00200 /* can do TCP6 Segmentation Offload */ #define IFCAP_LRO 0x00400 /* can do Large Receive Offload */ #define IFCAP_WOL_UCAST 0x00800 /* wake on any unicast frame */ #define IFCAP_WOL_MCAST 0x01000 /* wake on any multicast frame */ #define IFCAP_WOL_MAGIC 0x02000 /* wake on any Magic Packet */ #define IFCAP_TOE4 0x04000 /* interface can offload TCP */ #define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */ #define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ #define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */ #define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */ #define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */ #define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */ #define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */ #define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */ #define IFCAP_HWSTATS 0x800000 /* manages counters internally */ #define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6) #define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM) #define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) #define IFCAP_WOL (IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC) #define IFCAP_TOE (IFCAP_TOE4 | IFCAP_TOE6) #define IFCAP_CANTCHANGE (IFCAP_NETMAP) #define IFQ_MAXLEN 50 #define IFNET_SLOWHZ 1 /* granularity is 1 second */ /* * Message format for use in obtaining information about interfaces * from getkerninfo and the routing socket * For the new, extensible interface see struct if_msghdrl below. */ struct if_msghdr { u_short ifm_msglen; /* to skip over non-understood messages */ u_char ifm_version; /* future binary compatibility */ u_char ifm_type; /* message type */ int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ u_short ifm_index; /* index for associated ifp */ struct if_data ifm_data;/* statistics and other data about if */ }; /* * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is * extensible after ifm_data_off or within ifm_data. Both the if_msghdr and * if_data now have a member field detailing the struct length in addition to * the routing message length. Macros are provided to find the start of * ifm_data and the start of the socket address strucutres immediately following * struct if_msghdrl given a pointer to struct if_msghdrl. */ #define IF_MSGHDRL_IFM_DATA(_l) \ (struct if_data *)((char *)(_l) + (_l)->ifm_data_off) #define IF_MSGHDRL_RTA(_l) \ (void *)((uintptr_t)(_l) + (_l)->ifm_len) struct if_msghdrl { u_short ifm_msglen; /* to skip over non-understood messages */ u_char ifm_version; /* future binary compatibility */ u_char ifm_type; /* message type */ int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ u_short ifm_index; /* index for associated ifp */ u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */ u_short ifm_len; /* length of if_msghdrl incl. if_data */ u_short ifm_data_off; /* offset of if_data from beginning */ struct if_data ifm_data;/* statistics and other data about if */ }; /* * Message format for use in obtaining information about interface addresses * from getkerninfo and the routing socket * For the new, extensible interface see struct ifa_msghdrl below. */ struct ifa_msghdr { u_short ifam_msglen; /* to skip over non-understood messages */ u_char ifam_version; /* future binary compatibility */ u_char ifam_type; /* message type */ int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ u_short ifam_index; /* index for associated ifp */ int ifam_metric; /* value of ifa_ifp->if_metric */ }; /* * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is * extensible after ifam_metric or within ifam_data. Both the ifa_msghdrl and * if_data now have a member field detailing the struct length in addition to * the routing message length. Macros are provided to find the start of * ifm_data and the start of the socket address strucutres immediately following * struct ifa_msghdrl given a pointer to struct ifa_msghdrl. */ #define IFA_MSGHDRL_IFAM_DATA(_l) \ (struct if_data *)((char *)(_l) + (_l)->ifam_data_off) #define IFA_MSGHDRL_RTA(_l) \ (void *)((uintptr_t)(_l) + (_l)->ifam_len) struct ifa_msghdrl { u_short ifam_msglen; /* to skip over non-understood messages */ u_char ifam_version; /* future binary compatibility */ u_char ifam_type; /* message type */ int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ u_short ifam_index; /* index for associated ifp */ u_short _ifam_spare1; /* spare space to grow if_index, see if_var.h */ u_short ifam_len; /* length of ifa_msghdrl incl. if_data */ u_short ifam_data_off; /* offset of if_data from beginning */ int ifam_metric; /* value of ifa_ifp->if_metric */ struct if_data ifam_data;/* statistics and other data about if or * address */ }; /* * Message format for use in obtaining information about multicast addresses * from the routing socket */ struct ifma_msghdr { u_short ifmam_msglen; /* to skip over non-understood messages */ u_char ifmam_version; /* future binary compatibility */ u_char ifmam_type; /* message type */ int ifmam_addrs; /* like rtm_addrs */ int ifmam_flags; /* value of ifa_flags */ u_short ifmam_index; /* index for associated ifp */ }; /* * Message format announcing the arrival or departure of a network interface. */ struct if_announcemsghdr { u_short ifan_msglen; /* to skip over non-understood messages */ u_char ifan_version; /* future binary compatibility */ u_char ifan_type; /* message type */ u_short ifan_index; /* index for associated ifp */ char ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */ u_short ifan_what; /* what type of announcement */ }; #define IFAN_ARRIVAL 0 /* interface arrival */ #define IFAN_DEPARTURE 1 /* interface departure */ /* * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests */ struct ifreq_buffer { size_t length; void *buffer; }; /* * Interface request structure used for socket * ioctl's. All interface ioctl's must have parameter * definitions which begin with ifr_name. The * remainder may be interface specific. */ struct ifreq { char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct ifreq_buffer ifru_buffer; short ifru_flags[2]; short ifru_index; int ifru_jid; int ifru_metric; int ifru_mtu; int ifru_phys; int ifru_media; caddr_t ifru_data; int ifru_cap[2]; u_int ifru_fib; } ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_buffer ifr_ifru.ifru_buffer /* user supplied buffer with its length */ #define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */ #define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */ #define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */ #define ifr_metric ifr_ifru.ifru_metric /* metric */ #define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ #define ifr_phys ifr_ifru.ifru_phys /* physical wire */ #define ifr_media ifr_ifru.ifru_media /* physical media */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ #define ifr_reqcap ifr_ifru.ifru_cap[0] /* requested capabilities */ #define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */ #define ifr_index ifr_ifru.ifru_index /* interface index */ #define ifr_fib ifr_ifru.ifru_fib /* interface fib */ }; #define _SIZEOF_ADDR_IFREQ(ifr) \ ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ (ifr).ifr_addr.sa_len) : sizeof(struct ifreq)) struct ifaliasreq { char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ struct sockaddr ifra_addr; struct sockaddr ifra_broadaddr; struct sockaddr ifra_mask; int ifra_vhid; }; /* 9.x compat */ struct oifaliasreq { char ifra_name[IFNAMSIZ]; struct sockaddr ifra_addr; struct sockaddr ifra_broadaddr; struct sockaddr ifra_mask; }; struct ifmediareq { char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */ int ifm_current; /* current media options */ int ifm_mask; /* don't care mask */ int ifm_status; /* media status */ int ifm_active; /* active options */ int ifm_count; /* # entries in ifm_ulist array */ int *ifm_ulist; /* media words */ }; struct ifdrv { char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ unsigned long ifd_cmd; size_t ifd_len; void *ifd_data; }; /* * Structure used to retrieve aux status data from interfaces. * Kernel suppliers to this interface should respect the formatting * needed by ifconfig(8): each line starts with a TAB and ends with * a newline. The canonical example to copy and paste is in if_tun.c. */ #define IFSTATMAX 800 /* 10 lines of text */ struct ifstat { char ifs_name[IFNAMSIZ]; /* if name, e.g. "en0" */ char ascii[IFSTATMAX + 1]; }; /* * Structure used in SIOCGIFCONF request. * Used to retrieve interface configuration * for machine (useful for programs which * must know all networks accessible). */ struct ifconf { int ifc_len; /* size of associated buffer */ union { caddr_t ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ }; /* * interface groups */ #define IFG_ALL "all" /* group contains all interfaces */ /* XXX: will we implement this? */ #define IFG_EGRESS "egress" /* if(s) default route(s) point to */ struct ifg_req { union { char ifgrqu_group[IFNAMSIZ]; char ifgrqu_member[IFNAMSIZ]; } ifgrq_ifgrqu; #define ifgrq_group ifgrq_ifgrqu.ifgrqu_group #define ifgrq_member ifgrq_ifgrqu.ifgrqu_member }; /* * Used to lookup groups for an interface */ struct ifgroupreq { char ifgr_name[IFNAMSIZ]; u_int ifgr_len; union { char ifgru_group[IFNAMSIZ]; struct ifg_req *ifgru_groups; } ifgr_ifgru; #define ifgr_group ifgr_ifgru.ifgru_group #define ifgr_groups ifgr_ifgru.ifgru_groups }; /* * Structure used to request i2c data * from interface transceivers. */ struct ifi2creq { uint8_t dev_addr; /* i2c address (0xA0, 0xA2) */ uint8_t offset; /* read offset */ uint8_t len; /* read length */ uint8_t spare0; uint32_t spare1; uint8_t data[8]; /* read buffer */ }; #endif /* __BSD_VISIBLE */ #ifdef _KERNEL #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_IFADDR); MALLOC_DECLARE(M_IFMADDR); #endif #endif #ifndef _KERNEL struct if_nameindex { unsigned int if_index; /* 1, 2, ... */ char *if_name; /* null terminated name: "le0", ... */ }; __BEGIN_DECLS void if_freenameindex(struct if_nameindex *); char *if_indextoname(unsigned int, char *); struct if_nameindex *if_nameindex(void); unsigned int if_nametoindex(const char *); __END_DECLS #endif #endif /* !_NET_IF_H_ */ /*- * Copyright (c) 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)if_arp.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NET_IF_ARP_H_ #define _NET_IF_ARP_H_ /* * Address Resolution Protocol. * * See RFC 826 for protocol description. ARP packets are variable * in size; the arphdr structure defines the fixed-length portion. * Protocol type values are the same as those for 10 Mb/s Ethernet. * It is followed by the variable-sized fields ar_sha, arp_spa, * arp_tha and arp_tpa in that order, according to the lengths * specified. Field names used correspond to RFC 826. */ struct arphdr { u_short ar_hrd; /* format of hardware address */ #define ARPHRD_ETHER 1 /* ethernet hardware format */ #define ARPHRD_IEEE802 6 /* token-ring hardware format */ #define ARPHRD_ARCNET 7 /* arcnet hardware format */ #define ARPHRD_FRELAY 15 /* frame relay hardware format */ #define ARPHRD_IEEE1394 24 /* firewire hardware format */ #define ARPHRD_INFINIBAND 32 /* infiniband hardware format */ u_short ar_pro; /* format of protocol address */ u_char ar_hln; /* length of hardware address */ u_char ar_pln; /* length of protocol address */ u_short ar_op; /* one of: */ #define ARPOP_REQUEST 1 /* request to resolve address */ #define ARPOP_REPLY 2 /* response to previous request */ #define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ #define ARPOP_REVREPLY 4 /* response giving protocol address */ #define ARPOP_INVREQUEST 8 /* request to identify peer */ #define ARPOP_INVREPLY 9 /* response identifying peer */ /* * The remaining fields are variable in size, * according to the sizes above. */ #ifdef COMMENT_ONLY u_char ar_sha[]; /* sender hardware address */ u_char ar_spa[]; /* sender protocol address */ u_char ar_tha[]; /* target hardware address */ u_char ar_tpa[]; /* target protocol address */ #endif }; #define ar_sha(ap) (((caddr_t)((ap)+1)) + 0) #define ar_spa(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln) #define ar_tha(ap) (((caddr_t)((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln) #define ar_tpa(ap) (((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln) #define arphdr_len2(ar_hln, ar_pln) \ (sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln)) #define arphdr_len(ap) (arphdr_len2((ap)->ar_hln, (ap)->ar_pln)) /* * ARP ioctl request */ struct arpreq { struct sockaddr arp_pa; /* protocol address */ struct sockaddr arp_ha; /* hardware address */ int arp_flags; /* flags */ }; /* arp_flags and at_flags field values */ #define ATF_INUSE 0x01 /* entry in use */ #define ATF_COM 0x02 /* completed entry (enaddr valid) */ #define ATF_PERM 0x04 /* permanent entry */ #define ATF_PUBL 0x08 /* publish entry (respond for other host) */ #define ATF_USETRAILERS 0x10 /* has requested trailers */ struct arpstat { /* Normal things that happen: */ uint64_t txrequests; /* # of ARP requests sent by this host. */ uint64_t txreplies; /* # of ARP replies sent by this host. */ uint64_t rxrequests; /* # of ARP requests received by this host. */ uint64_t rxreplies; /* # of ARP replies received by this host. */ uint64_t received; /* # of ARP packets received by this host. */ uint64_t arp_spares[4]; /* For either the upper or lower half. */ /* Abnormal event and error counting: */ uint64_t dropped; /* # of packets dropped waiting for a reply. */ uint64_t timeouts; /* # of times with entries removed */ /* due to timeout. */ uint64_t dupips; /* # of duplicate IPs detected. */ }; #ifdef _KERNEL #include #include VNET_PCPUSTAT_DECLARE(struct arpstat, arpstat); /* * In-kernel consumers can use these accessor macros directly to update * stats. */ #define ARPSTAT_ADD(name, val) \ VNET_PCPUSTAT_ADD(struct arpstat, arpstat, name, (val)) #define ARPSTAT_SUB(name, val) ARPSTAT_ADD(name, -(val)) #define ARPSTAT_INC(name) ARPSTAT_ADD(name, 1) #define ARPSTAT_DEC(name) ARPSTAT_SUB(name, 1) #endif /* _KERNEL */ #endif /* !_NET_IF_ARP_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 * $FreeBSD$ */ #ifndef _NETINET_IF_ETHER_H_ #define _NETINET_IF_ETHER_H_ #include #include /* * Macro to map an IP multicast address to an Ethernet multicast address. * The high-order 25 bits of the Ethernet address are statically assigned, * and the low-order 23 bits are taken from the low end of the IP address. */ #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \ /* struct in_addr *ipaddr; */ \ /* u_char enaddr[ETHER_ADDR_LEN]; */ \ { \ (enaddr)[0] = 0x01; \ (enaddr)[1] = 0x00; \ (enaddr)[2] = 0x5e; \ (enaddr)[3] = ((const u_char *)ipaddr)[1] & 0x7f; \ (enaddr)[4] = ((const u_char *)ipaddr)[2]; \ (enaddr)[5] = ((const u_char *)ipaddr)[3]; \ } /* * Macro to map an IP6 multicast address to an Ethernet multicast address. * The high-order 16 bits of the Ethernet address are statically assigned, * and the low-order 32 bits are taken from the low end of the IP6 address. */ #define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr) \ /* struct in6_addr *ip6addr; */ \ /* u_char enaddr[ETHER_ADDR_LEN]; */ \ { \ (enaddr)[0] = 0x33; \ (enaddr)[1] = 0x33; \ (enaddr)[2] = ((const u_char *)ip6addr)[12]; \ (enaddr)[3] = ((const u_char *)ip6addr)[13]; \ (enaddr)[4] = ((const u_char *)ip6addr)[14]; \ (enaddr)[5] = ((const u_char *)ip6addr)[15]; \ } /* * Ethernet Address Resolution Protocol. * * See RFC 826 for protocol description. Structure below is adapted * to resolving internet addresses. Field names used correspond to * RFC 826. */ struct ether_arp { struct arphdr ea_hdr; /* fixed-size header */ u_char arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */ u_char arp_spa[4]; /* sender protocol address */ u_char arp_tha[ETHER_ADDR_LEN]; /* target hardware address */ u_char arp_tpa[4]; /* target protocol address */ }; #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln #define arp_pln ea_hdr.ar_pln #define arp_op ea_hdr.ar_op #ifndef BURN_BRIDGES /* Can be used by third party software. */ struct sockaddr_inarp { u_char sin_len; u_char sin_family; u_short sin_port; struct in_addr sin_addr; struct in_addr sin_srcaddr; u_short sin_tos; u_short sin_other; #define SIN_PROXY 1 }; #endif /* !BURN_BRIDGES */ /* * IP and ethernet specific routing flags */ #define RTF_USETRAILERS RTF_PROTO1 /* use trailers */ #define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */ #ifdef _KERNEL extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN]; extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN]; struct ifaddr; int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m, const struct sockaddr *dst, u_char *desten, uint32_t *pflags); void arprequest(struct ifnet *, const struct in_addr *, const struct in_addr *, u_char *); void arp_ifinit(struct ifnet *, struct ifaddr *); void arp_ifinit2(struct ifnet *, struct ifaddr *, u_char *); #endif #endif /*- * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)in.h 8.3 (Berkeley) 1/3/94 * $FreeBSD$ */ #ifndef _NETINET_IN_H_ #define _NETINET_IN_H_ #include #include #include /* Protocols common to RFC 1700, POSIX, and X/Open. */ #define IPPROTO_IP 0 /* dummy for IP */ #define IPPROTO_ICMP 1 /* control message protocol */ #define IPPROTO_TCP 6 /* tcp */ #define IPPROTO_UDP 17 /* user datagram protocol */ #define INADDR_ANY ((in_addr_t)0x00000000) #define INADDR_BROADCAST ((in_addr_t)0xffffffff) /* must be masked */ #ifndef _UINT8_T_DECLARED typedef __uint8_t uint8_t; #define _UINT8_T_DECLARED #endif #ifndef _UINT16_T_DECLARED typedef __uint16_t uint16_t; #define _UINT16_T_DECLARED #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _IN_ADDR_T_DECLARED typedef uint32_t in_addr_t; #define _IN_ADDR_T_DECLARED #endif #ifndef _IN_PORT_T_DECLARED typedef uint16_t in_port_t; #define _IN_PORT_T_DECLARED #endif #ifndef _SA_FAMILY_T_DECLARED typedef __sa_family_t sa_family_t; #define _SA_FAMILY_T_DECLARED #endif /* Internet address (a structure for historical reasons). */ #ifndef _STRUCT_IN_ADDR_DECLARED struct in_addr { in_addr_t s_addr; }; #define _STRUCT_IN_ADDR_DECLARED #endif #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif #include /* Socket address, internet style. */ struct sockaddr_in { uint8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero[8]; }; #if !defined(_KERNEL) && __POSIX_VISIBLE >= 200112 #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED __BEGIN_DECLS uint32_t htonl(uint32_t); uint16_t htons(uint16_t); uint32_t ntohl(uint32_t); uint16_t ntohs(uint16_t); __END_DECLS #endif #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif #endif /* !_KERNEL && __POSIX_VISIBLE >= 200112 */ #if __POSIX_VISIBLE >= 200112 #define IPPROTO_IPV6 41 /* IP6 header */ #define IPPROTO_RAW 255 /* raw IP packet */ #define INET_ADDRSTRLEN 16 #endif #if __BSD_VISIBLE /* * Constants and structures defined by the internet system, * Per RFC 790, September 1981, and numerous additions. */ /* * Protocols (RFC 1700) */ #define IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */ #define IPPROTO_IGMP 2 /* group mgmt protocol */ #define IPPROTO_GGP 3 /* gateway^2 (deprecated) */ #define IPPROTO_IPV4 4 /* IPv4 encapsulation */ #define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */ #define IPPROTO_ST 7 /* Stream protocol II */ #define IPPROTO_EGP 8 /* exterior gateway protocol */ #define IPPROTO_PIGP 9 /* private interior gateway */ #define IPPROTO_RCCMON 10 /* BBN RCC Monitoring */ #define IPPROTO_NVPII 11 /* network voice protocol*/ #define IPPROTO_PUP 12 /* pup */ #define IPPROTO_ARGUS 13 /* Argus */ #define IPPROTO_EMCON 14 /* EMCON */ #define IPPROTO_XNET 15 /* Cross Net Debugger */ #define IPPROTO_CHAOS 16 /* Chaos*/ #define IPPROTO_MUX 18 /* Multiplexing */ #define IPPROTO_MEAS 19 /* DCN Measurement Subsystems */ #define IPPROTO_HMP 20 /* Host Monitoring */ #define IPPROTO_PRM 21 /* Packet Radio Measurement */ #define IPPROTO_IDP 22 /* xns idp */ #define IPPROTO_TRUNK1 23 /* Trunk-1 */ #define IPPROTO_TRUNK2 24 /* Trunk-2 */ #define IPPROTO_LEAF1 25 /* Leaf-1 */ #define IPPROTO_LEAF2 26 /* Leaf-2 */ #define IPPROTO_RDP 27 /* Reliable Data */ #define IPPROTO_IRTP 28 /* Reliable Transaction */ #define IPPROTO_TP 29 /* tp-4 w/ class negotiation */ #define IPPROTO_BLT 30 /* Bulk Data Transfer */ #define IPPROTO_NSP 31 /* Network Services */ #define IPPROTO_INP 32 /* Merit Internodal */ #define IPPROTO_SEP 33 /* Sequential Exchange */ #define IPPROTO_3PC 34 /* Third Party Connect */ #define IPPROTO_IDPR 35 /* InterDomain Policy Routing */ #define IPPROTO_XTP 36 /* XTP */ #define IPPROTO_DDP 37 /* Datagram Delivery */ #define IPPROTO_CMTP 38 /* Control Message Transport */ #define IPPROTO_TPXX 39 /* TP++ Transport */ #define IPPROTO_IL 40 /* IL transport protocol */ #define IPPROTO_SDRP 42 /* Source Demand Routing */ #define IPPROTO_ROUTING 43 /* IP6 routing header */ #define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */ #define IPPROTO_IDRP 45 /* InterDomain Routing*/ #define IPPROTO_RSVP 46 /* resource reservation */ #define IPPROTO_GRE 47 /* General Routing Encap. */ #define IPPROTO_MHRP 48 /* Mobile Host Routing */ #define IPPROTO_BHA 49 /* BHA */ #define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */ #define IPPROTO_AH 51 /* IP6 Auth Header */ #define IPPROTO_INLSP 52 /* Integ. Net Layer Security */ #define IPPROTO_SWIPE 53 /* IP with encryption */ #define IPPROTO_NHRP 54 /* Next Hop Resolution */ #define IPPROTO_MOBILE 55 /* IP Mobility */ #define IPPROTO_TLSP 56 /* Transport Layer Security */ #define IPPROTO_SKIP 57 /* SKIP */ #define IPPROTO_ICMPV6 58 /* ICMP6 */ #define IPPROTO_NONE 59 /* IP6 no next header */ #define IPPROTO_DSTOPTS 60 /* IP6 destination option */ #define IPPROTO_AHIP 61 /* any host internal protocol */ #define IPPROTO_CFTP 62 /* CFTP */ #define IPPROTO_HELLO 63 /* "hello" routing protocol */ #define IPPROTO_SATEXPAK 64 /* SATNET/Backroom EXPAK */ #define IPPROTO_KRYPTOLAN 65 /* Kryptolan */ #define IPPROTO_RVD 66 /* Remote Virtual Disk */ #define IPPROTO_IPPC 67 /* Pluribus Packet Core */ #define IPPROTO_ADFS 68 /* Any distributed FS */ #define IPPROTO_SATMON 69 /* Satnet Monitoring */ #define IPPROTO_VISA 70 /* VISA Protocol */ #define IPPROTO_IPCV 71 /* Packet Core Utility */ #define IPPROTO_CPNX 72 /* Comp. Prot. Net. Executive */ #define IPPROTO_CPHB 73 /* Comp. Prot. HeartBeat */ #define IPPROTO_WSN 74 /* Wang Span Network */ #define IPPROTO_PVP 75 /* Packet Video Protocol */ #define IPPROTO_BRSATMON 76 /* BackRoom SATNET Monitoring */ #define IPPROTO_ND 77 /* Sun net disk proto (temp.) */ #define IPPROTO_WBMON 78 /* WIDEBAND Monitoring */ #define IPPROTO_WBEXPAK 79 /* WIDEBAND EXPAK */ #define IPPROTO_EON 80 /* ISO cnlp */ #define IPPROTO_VMTP 81 /* VMTP */ #define IPPROTO_SVMTP 82 /* Secure VMTP */ #define IPPROTO_VINES 83 /* Banyon VINES */ #define IPPROTO_TTP 84 /* TTP */ #define IPPROTO_IGP 85 /* NSFNET-IGP */ #define IPPROTO_DGP 86 /* dissimilar gateway prot. */ #define IPPROTO_TCF 87 /* TCF */ #define IPPROTO_IGRP 88 /* Cisco/GXS IGRP */ #define IPPROTO_OSPFIGP 89 /* OSPFIGP */ #define IPPROTO_SRPC 90 /* Strite RPC protocol */ #define IPPROTO_LARP 91 /* Locus Address Resoloution */ #define IPPROTO_MTP 92 /* Multicast Transport */ #define IPPROTO_AX25 93 /* AX.25 Frames */ #define IPPROTO_IPEIP 94 /* IP encapsulated in IP */ #define IPPROTO_MICP 95 /* Mobile Int.ing control */ #define IPPROTO_SCCSP 96 /* Semaphore Comm. security */ #define IPPROTO_ETHERIP 97 /* Ethernet IP encapsulation */ #define IPPROTO_ENCAP 98 /* encapsulation header */ #define IPPROTO_APES 99 /* any private encr. scheme */ #define IPPROTO_GMTP 100 /* GMTP*/ #define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */ #define IPPROTO_SCTP 132 /* SCTP */ #define IPPROTO_MH 135 /* IPv6 Mobility Header */ #define IPPROTO_UDPLITE 136 /* UDP-Lite */ #define IPPROTO_HIP 139 /* IP6 Host Identity Protocol */ #define IPPROTO_SHIM6 140 /* IP6 Shim6 Protocol */ /* 101-254: Partly Unassigned */ #define IPPROTO_PIM 103 /* Protocol Independent Mcast */ #define IPPROTO_CARP 112 /* CARP */ #define IPPROTO_PGM 113 /* PGM */ #define IPPROTO_MPLS 137 /* MPLS-in-IP */ #define IPPROTO_PFSYNC 240 /* PFSYNC */ #define IPPROTO_RESERVED_253 253 /* Reserved */ #define IPPROTO_RESERVED_254 254 /* Reserved */ /* 255: Reserved */ /* BSD Private, local use, namespace incursion, no longer used */ #define IPPROTO_OLD_DIVERT 254 /* OLD divert pseudo-proto */ #define IPPROTO_MAX 256 /* last return value of *_input(), meaning "all job for this pkt is done". */ #define IPPROTO_DONE 257 /* Only used internally, so can be outside the range of valid IP protocols. */ #define IPPROTO_DIVERT 258 /* divert pseudo-protocol */ #define IPPROTO_SEND 259 /* SeND pseudo-protocol */ /* * Defined to avoid confusion. The master value is defined by * PROTO_SPACER in sys/protosw.h. */ #define IPPROTO_SPACER 32767 /* spacer for loadable protos */ /* * Local port number conventions: * * When a user does a bind(2) or connect(2) with a port number of zero, * a non-conflicting local port address is chosen. * The default range is IPPORT_HIFIRSTAUTO through * IPPORT_HILASTAUTO, although that is settable by sysctl. * * A user may set the IPPROTO_IP option IP_PORTRANGE to change this * default assignment range. * * The value IP_PORTRANGE_DEFAULT causes the default behavior. * * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers * into the "high" range. These are reserved for client outbound connections * which do not want to be filtered by any firewalls. * * The value IP_PORTRANGE_LOW changes the range to the "low" are * that is (by convention) restricted to privileged processes. This * convention is based on "vouchsafe" principles only. It is only secure * if you trust the remote host to restrict these ports. * * The default range of ports and the high range can be changed by * sysctl(3). (net.inet.ip.port{hi,low}{first,last}_auto) * * Changing those values has bad security implications if you are * using a stateless firewall that is allowing packets outside of that * range in order to allow transparent outgoing connections. * * Such a firewall configuration will generally depend on the use of these * default values. If you change them, you may find your Security * Administrator looking for you with a heavy object. * * For a slightly more orthodox text view on this: * * ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers * * port numbers are divided into three ranges: * * 0 - 1023 Well Known Ports * 1024 - 49151 Registered Ports * 49152 - 65535 Dynamic and/or Private Ports * */ /* * Ports < IPPORT_RESERVED are reserved for * privileged processes (e.g. root). (IP_PORTRANGE_LOW) */ #define IPPORT_RESERVED 1024 /* * Default local port range, used by IP_PORTRANGE_DEFAULT */ #define IPPORT_EPHEMERALFIRST 10000 #define IPPORT_EPHEMERALLAST 65535 /* * Dynamic port range, used by IP_PORTRANGE_HIGH. */ #define IPPORT_HIFIRSTAUTO 49152 #define IPPORT_HILASTAUTO 65535 /* * Scanning for a free reserved port return a value below IPPORT_RESERVED, * but higher than IPPORT_RESERVEDSTART. Traditionally the start value was * 512, but that conflicts with some well-known-services that firewalls may * have a fit if we use. */ #define IPPORT_RESERVEDSTART 600 #define IPPORT_MAX 65535 /* * Definitions of bits in internet address integers. * On subnets, the decomposition of addresses to host and net parts * is done according to subnet mask, not the masks here. */ #define IN_CLASSA(i) (((in_addr_t)(i) & 0x80000000) == 0) #define IN_CLASSA_NET 0xff000000 #define IN_CLASSA_NSHIFT 24 #define IN_CLASSA_HOST 0x00ffffff #define IN_CLASSA_MAX 128 #define IN_CLASSB(i) (((in_addr_t)(i) & 0xc0000000) == 0x80000000) #define IN_CLASSB_NET 0xffff0000 #define IN_CLASSB_NSHIFT 16 #define IN_CLASSB_HOST 0x0000ffff #define IN_CLASSB_MAX 65536 #define IN_CLASSC(i) (((in_addr_t)(i) & 0xe0000000) == 0xc0000000) #define IN_CLASSC_NET 0xffffff00 #define IN_CLASSC_NSHIFT 8 #define IN_CLASSC_HOST 0x000000ff #define IN_CLASSD(i) (((in_addr_t)(i) & 0xf0000000) == 0xe0000000) #define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ #define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ #define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ #define IN_MULTICAST(i) IN_CLASSD(i) #define IN_EXPERIMENTAL(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000) #define IN_BADCLASS(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000) #define IN_LINKLOCAL(i) (((in_addr_t)(i) & 0xffff0000) == 0xa9fe0000) #define IN_LOOPBACK(i) (((in_addr_t)(i) & 0xff000000) == 0x7f000000) #define IN_ZERONET(i) (((in_addr_t)(i) & 0xff000000) == 0) #define IN_PRIVATE(i) ((((in_addr_t)(i) & 0xff000000) == 0x0a000000) || \ (((in_addr_t)(i) & 0xfff00000) == 0xac100000) || \ (((in_addr_t)(i) & 0xffff0000) == 0xc0a80000)) #define IN_LOCAL_GROUP(i) (((in_addr_t)(i) & 0xffffff00) == 0xe0000000) #define IN_ANY_LOCAL(i) (IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i)) #define INADDR_LOOPBACK ((in_addr_t)0x7f000001) #ifndef _KERNEL #define INADDR_NONE ((in_addr_t)0xffffffff) /* -1 return */ #endif #define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000) /* 224.0.0.0 */ #define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001) /* 224.0.0.1 */ #define INADDR_ALLRTRS_GROUP ((in_addr_t)0xe0000002) /* 224.0.0.2 */ #define INADDR_ALLRPTS_GROUP ((in_addr_t)0xe0000016) /* 224.0.0.22, IGMPv3 */ #define INADDR_CARP_GROUP ((in_addr_t)0xe0000012) /* 224.0.0.18 */ #define INADDR_PFSYNC_GROUP ((in_addr_t)0xe00000f0) /* 224.0.0.240 */ #define INADDR_ALLMDNS_GROUP ((in_addr_t)0xe00000fb) /* 224.0.0.251 */ #define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff) /* 224.0.0.255 */ #define IN_LOOPBACKNET 127 /* official! */ #define IN_RFC3021_MASK ((in_addr_t)0xfffffffe) /* * Options for use with [gs]etsockopt at the IP level. * First word of comment is data type; bool is stored in int. */ #define IP_OPTIONS 1 /* buf/ip_opts; set/get IP options */ #define IP_HDRINCL 2 /* int; header is included with data */ #define IP_TOS 3 /* int; IP type of service and preced. */ #define IP_TTL 4 /* int; IP time to live */ #define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */ #define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */ #define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */ #define IP_SENDSRCADDR IP_RECVDSTADDR /* cmsg_type to set src addr */ #define IP_RETOPTS 8 /* ip_opts; set/get IP options */ #define IP_MULTICAST_IF 9 /* struct in_addr *or* struct ip_mreqn; * set/get IP multicast i/f */ #define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */ #define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */ #define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */ #define IP_MULTICAST_VIF 14 /* set/get IP mcast virt. iface */ #define IP_RSVP_ON 15 /* enable RSVP in kernel */ #define IP_RSVP_OFF 16 /* disable RSVP in kernel */ #define IP_RSVP_VIF_ON 17 /* set RSVP per-vif socket */ #define IP_RSVP_VIF_OFF 18 /* unset RSVP per-vif socket */ #define IP_PORTRANGE 19 /* int; range to choose for unspec port */ #define IP_RECVIF 20 /* bool; receive reception if w/dgram */ /* for IPSEC */ #define IP_IPSEC_POLICY 21 /* int; set/get security policy */ /* unused; was IP_FAITH */ #define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ #define IP_BINDANY 24 /* bool: allow bind to any address */ #define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */ #define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */ /* * Options for controlling the firewall and dummynet. * Historical options (from 40 to 64) will eventually be * replaced by only two options, IP_FW3 and IP_DUMMYNET3. */ #define IP_FW_TABLE_ADD 40 /* add entry */ #define IP_FW_TABLE_DEL 41 /* delete entry */ #define IP_FW_TABLE_FLUSH 42 /* flush table */ #define IP_FW_TABLE_GETSIZE 43 /* get table size */ #define IP_FW_TABLE_LIST 44 /* list table contents */ #define IP_FW3 48 /* generic ipfw v.3 sockopts */ #define IP_DUMMYNET3 49 /* generic dummynet v.3 sockopts */ #define IP_FW_ADD 50 /* add a firewall rule to chain */ #define IP_FW_DEL 51 /* delete a firewall rule from chain */ #define IP_FW_FLUSH 52 /* flush firewall rule chain */ #define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */ #define IP_FW_GET 54 /* get entire firewall rule chain */ #define IP_FW_RESETLOG 55 /* reset logging counters */ #define IP_FW_NAT_CFG 56 /* add/config a nat rule */ #define IP_FW_NAT_DEL 57 /* delete a nat rule */ #define IP_FW_NAT_GET_CONFIG 58 /* get configuration of a nat rule */ #define IP_FW_NAT_GET_LOG 59 /* get log of a nat rule */ #define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */ #define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */ #define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ #define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */ #define IP_RECVTTL 65 /* bool; receive IP TTL w/dgram */ #define IP_MINTTL 66 /* minimum TTL for packet or drop */ #define IP_DONTFRAG 67 /* don't fragment packet */ #define IP_RECVTOS 68 /* bool; receive IP TOS w/dgram */ /* IPv4 Source Filter Multicast API [RFC3678] */ #define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ #define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ #define IP_BLOCK_SOURCE 72 /* block a source */ #define IP_UNBLOCK_SOURCE 73 /* unblock a source */ /* The following option is private; do not use it from user applications. */ #define IP_MSFILTER 74 /* set/get filter list */ /* Protocol Independent Multicast API [RFC3678] */ #define MCAST_JOIN_GROUP 80 /* join an any-source group */ #define MCAST_LEAVE_GROUP 81 /* leave all sources for group */ #define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ #define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ #define MCAST_BLOCK_SOURCE 84 /* block a source */ #define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ /* Flow and RSS definitions */ #define IP_FLOWID 90 /* get flow id for the given socket/inp */ #define IP_FLOWTYPE 91 /* get flow type (M_HASHTYPE) */ #define IP_RSSBUCKETID 92 /* get RSS flowid -> bucket mapping */ #define IP_RECVFLOWID 93 /* bool; receive IP flowid/flowtype w/ datagram */ #define IP_RECVRSSBUCKETID 94 /* bool; receive IP RSS bucket id w/ datagram */ /* * Defaults and limits for options */ #define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */ #define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ /* * The imo_membership vector for each socket is now dynamically allocated at * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized * according to a power-of-two increment. */ #define IP_MIN_MEMBERSHIPS 31 #define IP_MAX_MEMBERSHIPS 4095 #define IP_MAX_SOURCE_FILTER 1024 /* XXX to be unused */ /* * Default resource limits for IPv4 multicast source filtering. * These may be modified by sysctl. */ #define IP_MAX_GROUP_SRC_FILTER 512 /* sources per group */ #define IP_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */ #define IP_MAX_SOCK_MUTE_FILTER 128 /* XXX no longer used */ /* * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. */ struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_interface; /* local IP address of interface */ }; /* * Modified argument structure for IP_MULTICAST_IF, obtained from Linux. * This is used to specify an interface index for multicast sends, as * the IPv4 legacy APIs do not support this (unless IP_SENDIF is available). */ struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_address; /* local IP address of interface */ int imr_ifindex; /* Interface index; cast to uint32_t */ }; /* * Argument structure for IPv4 Multicast Source Filter APIs. [RFC3678] */ struct ip_mreq_source { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_sourceaddr; /* IP address of source */ struct in_addr imr_interface; /* local IP address of interface */ }; /* * Argument structures for Protocol-Independent Multicast Source * Filter APIs. [RFC3678] */ struct group_req { uint32_t gr_interface; /* interface index */ struct sockaddr_storage gr_group; /* group address */ }; struct group_source_req { uint32_t gsr_interface; /* interface index */ struct sockaddr_storage gsr_group; /* group address */ struct sockaddr_storage gsr_source; /* source address */ }; #ifndef __MSFILTERREQ_DEFINED #define __MSFILTERREQ_DEFINED /* * The following structure is private; do not use it from user applications. * It is used to communicate IP_MSFILTER/IPV6_MSFILTER information between * the RFC 3678 libc functions and the kernel. */ struct __msfilterreq { uint32_t msfr_ifindex; /* interface index */ uint32_t msfr_fmode; /* filter mode for group */ uint32_t msfr_nsrcs; /* # of sources in msfr_srcs */ struct sockaddr_storage msfr_group; /* group address */ struct sockaddr_storage *msfr_srcs; /* pointer to the first member * of a contiguous array of * sources to filter in full. */ }; #endif struct sockaddr; /* * Advanced (Full-state) APIs [RFC3678] * The RFC specifies uint_t for the 6th argument to [sg]etsourcefilter(). * We use uint32_t here to be consistent. */ int setipv4sourcefilter(int, struct in_addr, struct in_addr, uint32_t, uint32_t, struct in_addr *); int getipv4sourcefilter(int, struct in_addr, struct in_addr, uint32_t *, uint32_t *, struct in_addr *); int setsourcefilter(int, uint32_t, struct sockaddr *, socklen_t, uint32_t, uint32_t, struct sockaddr_storage *); int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t, uint32_t *, uint32_t *, struct sockaddr_storage *); /* * Filter modes; also used to represent per-socket filter mode internally. */ #define MCAST_UNDEFINED 0 /* fmode: not yet defined */ #define MCAST_INCLUDE 1 /* fmode: include these source(s) */ #define MCAST_EXCLUDE 2 /* fmode: exclude these source(s) */ /* * Argument for IP_PORTRANGE: * - which range to search when port is unspecified at bind() or connect() */ #define IP_PORTRANGE_DEFAULT 0 /* default range */ #define IP_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */ #define IP_PORTRANGE_LOW 2 /* "low" - vouchsafe security */ /* * Identifiers for IP sysctl nodes */ #define IPCTL_FORWARDING 1 /* act as router */ #define IPCTL_SENDREDIRECTS 2 /* may send redirects when forwarding */ #define IPCTL_DEFTTL 3 /* default TTL */ #ifdef notyet #define IPCTL_DEFMTU 4 /* default MTU */ #endif /* IPCTL_RTEXPIRE 5 deprecated */ /* IPCTL_RTMINEXPIRE 6 deprecated */ /* IPCTL_RTMAXCACHE 7 deprecated */ #define IPCTL_SOURCEROUTE 8 /* may perform source routes */ #define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */ #define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */ #define IPCTL_INTRQDROPS 11 /* number of netisr q drops */ #define IPCTL_STATS 12 /* ipstat structure */ #define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */ #define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */ /* 15, unused, was: IPCTL_KEEPFAITH */ #define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */ #endif /* __BSD_VISIBLE */ #ifdef _KERNEL struct ifnet; struct mbuf; /* forward declarations for Standard C */ int in_broadcast(struct in_addr, struct ifnet *); int in_canforward(struct in_addr); int in_localaddr(struct in_addr); int in_localip(struct in_addr); int in_ifhasaddr(struct ifnet *, struct in_addr); int inet_aton(const char *, struct in_addr *); /* in libkern */ char *inet_ntoa(struct in_addr); /* in libkern */ char *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */ char *inet_ntop(int, const void *, char *, socklen_t); /* in libkern */ int inet_pton(int af, const char *, void *); /* in libkern */ void in_ifdetach(struct ifnet *); #define in_hosteq(s, t) ((s).s_addr == (t).s_addr) #define in_nullhost(x) ((x).s_addr == INADDR_ANY) #define in_allhosts(x) ((x).s_addr == htonl(INADDR_ALLHOSTS_GROUP)) #define satosin(sa) ((struct sockaddr_in *)(sa)) #define sintosa(sin) ((struct sockaddr *)(sin)) #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) #endif /* _KERNEL */ /* INET6 stuff */ #if __POSIX_VISIBLE >= 200112 #define __KAME_NETINET_IN_H_INCLUDED_ #include #undef __KAME_NETINET_IN_H_INCLUDED_ #endif #endif /* !_NETINET_IN_H_*/ /*- * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * Portions of this software were developed by Robert N. M. Watson under * contract to Juniper Networks, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)in_pcb.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NETINET_IN_PCB_H_ #define _NETINET_IN_PCB_H_ #include #include #include #include #ifdef _KERNEL #include #include #include #include #endif #define in6pcb inpcb /* for KAME src sync over BSD*'s */ #define in6p_sp inp_sp /* for KAME src sync over BSD*'s */ struct inpcbpolicy; /* * struct inpcb is the common protocol control block structure used in most * IP transport protocols. * * Pointers to local and foreign host table entries, local and foreign socket * numbers, and pointers up (to a socket structure) and down (to a * protocol-specific control block) are stored here. */ LIST_HEAD(inpcbhead, inpcb); LIST_HEAD(inpcbporthead, inpcbport); typedef u_quad_t inp_gen_t; /* * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet. * So, AF_INET6 null laddr is also used as AF_INET null laddr, by utilizing * the following structure. */ struct in_addr_4in6 { u_int32_t ia46_pad32[3]; struct in_addr ia46_addr4; }; /* * NOTE: ipv6 addrs should be 64-bit aligned, per RFC 2553. in_conninfo has * some extra padding to accomplish this. * NOTE 2: tcp_syncache.c uses first 5 32-bit words, which identify fport, * lport, faddr to generate hash, so these fields shouldn't be moved. */ struct in_endpoints { u_int16_t ie_fport; /* foreign port */ u_int16_t ie_lport; /* local port */ /* protocol dependent part, local and foreign addr */ union { /* foreign host table entry */ struct in_addr_4in6 ie46_foreign; struct in6_addr ie6_foreign; } ie_dependfaddr; union { /* local host table entry */ struct in_addr_4in6 ie46_local; struct in6_addr ie6_local; } ie_dependladdr; u_int32_t ie6_zoneid; /* scope zone id */ }; #define ie_faddr ie_dependfaddr.ie46_foreign.ia46_addr4 #define ie_laddr ie_dependladdr.ie46_local.ia46_addr4 #define ie6_faddr ie_dependfaddr.ie6_foreign #define ie6_laddr ie_dependladdr.ie6_local /* * XXX The defines for inc_* are hacks and should be changed to direct * references. */ struct in_conninfo { u_int8_t inc_flags; u_int8_t inc_len; u_int16_t inc_fibnum; /* XXX was pad, 16 bits is plenty */ /* protocol dependent part */ struct in_endpoints inc_ie; }; /* * Flags for inc_flags. */ #define INC_ISIPV6 0x01 #define inc_isipv6 inc_flags /* temp compatability */ #define inc_fport inc_ie.ie_fport #define inc_lport inc_ie.ie_lport #define inc_faddr inc_ie.ie_faddr #define inc_laddr inc_ie.ie_laddr #define inc6_faddr inc_ie.ie6_faddr #define inc6_laddr inc_ie.ie6_laddr #define inc6_zoneid inc_ie.ie6_zoneid struct icmp6_filter; /*- * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and * IPv6 sockets. In the case of TCP and UDP, further per-connection state is * hung off of inp_ppcb most of the time. Almost all fields of struct inpcb * are static after creation or protected by a per-inpcb rwlock, inp_lock. A * few fields are protected by multiple locks as indicated in the locking notes * below. For these fields, all of the listed locks must be write-locked for * any modifications. However, these fields can be safely read while any one of * the listed locks are read-locked. This model can permit greater concurrency * for read operations. For example, connections can be looked up while only * holding a read lock on the global pcblist lock. This is important for * performance when attempting to find the connection for a packet given its IP * and port tuple. * * One noteworthy exception is that the global pcbinfo lock follows a different * set of rules in relation to the inp_list field. Rather than being * write-locked for modifications and read-locked for list iterations, it must * be read-locked during modifications and write-locked during list iterations. * This ensures that the relatively rare global list iterations safely walk a * stable snapshot of connections while allowing more common list modifications * to safely grab the pcblist lock just while adding or removing a connection * from the global list. * * Key: * (c) - Constant after initialization * (g) - Protected by the pcbgroup lock * (i) - Protected by the inpcb lock * (p) - Protected by the pcbinfo lock for the inpcb * (l) - Protected by the pcblist lock for the inpcb * (h) - Protected by the pcbhash lock for the inpcb * (s) - Protected by another subsystem's locks * (x) - Undefined locking * * A few other notes: * * When a read lock is held, stability of the field is guaranteed; to write * to a field, a write lock must generally be held. * * netinet/netinet6-layer code should not assume that the inp_socket pointer * is safe to dereference without inp_lock being held, even for protocols * other than TCP (where the inpcb persists during TIMEWAIT even after the * socket has been freed), or there may be close(2)-related races. * * The inp_vflag field is overloaded, and would otherwise ideally be (c). * * TODO: Currently only the TCP stack is leveraging the global pcbinfo lock * read-lock usage during modification, this model can be applied to other * protocols (especially SCTP). */ struct inpcb { LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */ LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */ LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ /* (p[w]) for list iteration */ /* (p[r]/l) for addition/removal */ void *inp_ppcb; /* (i) pointer to per-protocol pcb */ struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */ LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */ struct socket *inp_socket; /* (i) back pointer to socket */ struct ucred *inp_cred; /* (c) cache of socket cred */ u_int32_t inp_flow; /* (i) IPv6 flow information */ int inp_flags; /* (i) generic IP/datagram flags */ int inp_flags2; /* (i) generic IP/datagram flags #2*/ u_char inp_vflag; /* (i) IP version flag (v4/v6) */ u_char inp_ip_ttl; /* (i) time to live proto */ u_char inp_ip_p; /* (c) protocol proto */ u_char inp_ip_minttl; /* (i) minimum TTL or drop */ uint32_t inp_flowid; /* (x) flow id / queue id */ u_int inp_refcount; /* (i) refcount */ void *inp_pspare[5]; /* (x) route caching / general use */ uint32_t inp_flowtype; /* (x) M_HASHTYPE value */ uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */ u_int inp_ispare[4]; /* (x) route caching / user cookie / * general use */ /* Local and foreign ports, local and foreign addr. */ struct in_conninfo inp_inc; /* (i) list for PCB's local port */ /* MAC and IPSEC policy information. */ struct label *inp_label; /* (i) MAC label */ struct inpcbpolicy *inp_sp; /* (s) for IPSEC */ /* Protocol-dependent part; options. */ struct { u_char inp4_ip_tos; /* (i) type of service proto */ struct mbuf *inp4_options; /* (i) IP options */ struct ip_moptions *inp4_moptions; /* (i) IP mcast options */ } inp_depend4; struct { /* (i) IP options */ struct mbuf *inp6_options; /* (i) IP6 options for outgoing packets */ struct ip6_pktopts *inp6_outputopts; /* (i) IP multicast options */ struct ip6_moptions *inp6_moptions; /* (i) ICMPv6 code type filter */ struct icmp6_filter *inp6_icmp6filt; /* (i) IPV6_CHECKSUM setsockopt */ int inp6_cksum; short inp6_hops; } inp_depend6; LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */ struct inpcbport *inp_phd; /* (i/h) head of this list */ #define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* (c) generation count */ struct llentry *inp_lle; /* cached L2 information */ struct rtentry *inp_rt; /* cached L3 information */ struct rwlock inp_lock; }; #define inp_fport inp_inc.inc_fport #define inp_lport inp_inc.inc_lport #define inp_faddr inp_inc.inc_faddr #define inp_laddr inp_inc.inc_laddr #define inp_ip_tos inp_depend4.inp4_ip_tos #define inp_options inp_depend4.inp4_options #define inp_moptions inp_depend4.inp4_moptions #define in6p_faddr inp_inc.inc6_faddr #define in6p_laddr inp_inc.inc6_laddr #define in6p_zoneid inp_inc.inc6_zoneid #define in6p_hops inp_depend6.inp6_hops /* default hop limit */ #define in6p_flowinfo inp_flow #define in6p_options inp_depend6.inp6_options #define in6p_outputopts inp_depend6.inp6_outputopts #define in6p_moptions inp_depend6.inp6_moptions #define in6p_icmp6filt inp_depend6.inp6_icmp6filt #define in6p_cksum inp_depend6.inp6_cksum #define inp_vnet inp_pcbinfo->ipi_vnet /* * The range of the generation count, as used in this implementation, is 9e19. * We would have to create 300 billion connections per second for this number * to roll over in a year. This seems sufficiently unlikely that we simply * don't concern ourselves with that possibility. */ /* * Interface exported to userland by various protocols which use inpcbs. Hack * alert -- only define if struct xsocket is in scope. */ #ifdef _SYS_SOCKETVAR_H_ struct xinpcb { size_t xi_len; /* length of this structure */ struct inpcb xi_inp; struct xsocket xi_socket; u_quad_t xi_alignment_hack; }; struct xinpgen { size_t xig_len; /* length of this structure */ u_int xig_count; /* number of PCBs at this time */ inp_gen_t xig_gen; /* generation count at this time */ so_gen_t xig_sogen; /* socket generation count at this time */ }; #endif /* _SYS_SOCKETVAR_H_ */ struct inpcbport { LIST_ENTRY(inpcbport) phd_hash; struct inpcbhead phd_pcblist; u_short phd_port; }; /*- * Global data structure for each high-level protocol (UDP, TCP, ...) in both * IPv4 and IPv6. Holds inpcb lists and information for managing them. * * Each pcbinfo is protected by three locks: ipi_lock, ipi_hash_lock and * ipi_list_lock: * - ipi_lock covering the global pcb list stability during loop iteration, * - ipi_hash_lock covering the hashed lookup tables, * - ipi_list_lock covering mutable global fields (such as the global * pcb list) * * The lock order is: * * ipi_lock (before) * inpcb locks (before) * ipi_list locks (before) * {ipi_hash_lock, pcbgroup locks} * * Locking key: * * (c) Constant or nearly constant after initialisation * (g) Locked by ipi_lock * (l) Locked by ipi_list_lock * (h) Read using either ipi_hash_lock or inpcb lock; write requires both * (p) Protected by one or more pcbgroup locks * (x) Synchronisation properties poorly defined */ struct inpcbinfo { /* * Global lock protecting full inpcb list traversal */ struct rwlock ipi_lock; /* * Global list of inpcbs on the protocol. */ struct inpcbhead *ipi_listhead; /* (g/l) */ u_int ipi_count; /* (l) */ /* * Generation count -- incremented each time a connection is allocated * or freed. */ u_quad_t ipi_gencnt; /* (l) */ /* * Fields associated with port lookup and allocation. */ u_short ipi_lastport; /* (x) */ u_short ipi_lastlow; /* (x) */ u_short ipi_lasthi; /* (x) */ /* * UMA zone from which inpcbs are allocated for this protocol. */ struct uma_zone *ipi_zone; /* (c) */ /* * Connection groups associated with this protocol. These fields are * constant, but pcbgroup structures themselves are protected by * per-pcbgroup locks. */ struct inpcbgroup *ipi_pcbgroups; /* (c) */ u_int ipi_npcbgroups; /* (c) */ u_int ipi_hashfields; /* (c) */ /* * Global lock protecting non-pcbgroup hash lookup tables. */ struct rwlock ipi_hash_lock; /* * Global hash of inpcbs, hashed by local and foreign addresses and * port numbers. */ struct inpcbhead *ipi_hashbase; /* (h) */ u_long ipi_hashmask; /* (h) */ /* * Global hash of inpcbs, hashed by only local port number. */ struct inpcbporthead *ipi_porthashbase; /* (h) */ u_long ipi_porthashmask; /* (h) */ /* * List of wildcard inpcbs for use with pcbgroups. In the past, was * per-pcbgroup but is now global. All pcbgroup locks must be held * to modify the list, so any is sufficient to read it. */ struct inpcbhead *ipi_wildbase; /* (p) */ u_long ipi_wildmask; /* (p) */ /* * Pointer to network stack instance */ struct vnet *ipi_vnet; /* (c) */ /* * general use 2 */ void *ipi_pspare[2]; /* * Global lock protecting global inpcb list, inpcb count, etc. */ struct rwlock ipi_list_lock; }; #ifdef _KERNEL /* * Connection groups hold sets of connections that have similar CPU/thread * affinity. Each connection belongs to exactly one connection group. */ struct inpcbgroup { /* * Per-connection group hash of inpcbs, hashed by local and foreign * addresses and port numbers. */ struct inpcbhead *ipg_hashbase; /* (c) */ u_long ipg_hashmask; /* (c) */ /* * Notional affinity of this pcbgroup. */ u_int ipg_cpu; /* (p) */ /* * Per-connection group lock, not to be confused with ipi_lock. * Protects the hash table hung off the group, but also the global * wildcard list in inpcbinfo. */ struct mtx ipg_lock; } __aligned(CACHE_LINE_SIZE); #define INP_LOCK_INIT(inp, d, t) \ rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK) #define INP_LOCK_DESTROY(inp) rw_destroy(&(inp)->inp_lock) #define INP_RLOCK(inp) rw_rlock(&(inp)->inp_lock) #define INP_WLOCK(inp) rw_wlock(&(inp)->inp_lock) #define INP_TRY_RLOCK(inp) rw_try_rlock(&(inp)->inp_lock) #define INP_TRY_WLOCK(inp) rw_try_wlock(&(inp)->inp_lock) #define INP_RUNLOCK(inp) rw_runlock(&(inp)->inp_lock) #define INP_WUNLOCK(inp) rw_wunlock(&(inp)->inp_lock) #define INP_TRY_UPGRADE(inp) rw_try_upgrade(&(inp)->inp_lock) #define INP_DOWNGRADE(inp) rw_downgrade(&(inp)->inp_lock) #define INP_WLOCKED(inp) rw_wowned(&(inp)->inp_lock) #define INP_LOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_LOCKED) #define INP_RLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_RLOCKED) #define INP_WLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_WLOCKED) #define INP_UNLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_UNLOCKED) /* * These locking functions are for inpcb consumers outside of sys/netinet, * more specifically, they were added for the benefit of TOE drivers. The * macros are reserved for use by the stack. */ void inp_wlock(struct inpcb *); void inp_wunlock(struct inpcb *); void inp_rlock(struct inpcb *); void inp_runlock(struct inpcb *); #ifdef INVARIANTS void inp_lock_assert(struct inpcb *); void inp_unlock_assert(struct inpcb *); #else static __inline void inp_lock_assert(struct inpcb *inp __unused) { } static __inline void inp_unlock_assert(struct inpcb *inp __unused) { } #endif void inp_apply_all(void (*func)(struct inpcb *, void *), void *arg); int inp_ip_tos_get(const struct inpcb *inp); void inp_ip_tos_set(struct inpcb *inp, int val); struct socket * inp_inpcbtosocket(struct inpcb *inp); struct tcpcb * inp_inpcbtotcpcb(struct inpcb *inp); void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp, uint32_t *faddr, uint16_t *fp); short inp_so_options(const struct inpcb *inp); #endif /* _KERNEL */ #define INP_INFO_LOCK_INIT(ipi, d) \ rw_init_flags(&(ipi)->ipi_lock, (d), RW_RECURSE) #define INP_INFO_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_lock) #define INP_INFO_RLOCK(ipi) rw_rlock(&(ipi)->ipi_lock) #define INP_INFO_WLOCK(ipi) rw_wlock(&(ipi)->ipi_lock) #define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock) #define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock) #define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock) #define INP_INFO_WLOCKED(ipi) rw_wowned(&(ipi)->ipi_lock) #define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock) #define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock) #define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED) #define INP_INFO_RLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_RLOCKED) #define INP_INFO_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_WLOCKED) #define INP_INFO_UNLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_UNLOCKED) #define INP_LIST_LOCK_INIT(ipi, d) \ rw_init_flags(&(ipi)->ipi_list_lock, (d), 0) #define INP_LIST_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_list_lock) #define INP_LIST_RLOCK(ipi) rw_rlock(&(ipi)->ipi_list_lock) #define INP_LIST_WLOCK(ipi) rw_wlock(&(ipi)->ipi_list_lock) #define INP_LIST_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_list_lock) #define INP_LIST_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_list_lock) #define INP_LIST_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_list_lock) #define INP_LIST_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_list_lock) #define INP_LIST_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_list_lock) #define INP_LIST_LOCK_ASSERT(ipi) \ rw_assert(&(ipi)->ipi_list_lock, RA_LOCKED) #define INP_LIST_RLOCK_ASSERT(ipi) \ rw_assert(&(ipi)->ipi_list_lock, RA_RLOCKED) #define INP_LIST_WLOCK_ASSERT(ipi) \ rw_assert(&(ipi)->ipi_list_lock, RA_WLOCKED) #define INP_LIST_UNLOCK_ASSERT(ipi) \ rw_assert(&(ipi)->ipi_list_lock, RA_UNLOCKED) #define INP_HASH_LOCK_INIT(ipi, d) \ rw_init_flags(&(ipi)->ipi_hash_lock, (d), 0) #define INP_HASH_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_hash_lock) #define INP_HASH_RLOCK(ipi) rw_rlock(&(ipi)->ipi_hash_lock) #define INP_HASH_WLOCK(ipi) rw_wlock(&(ipi)->ipi_hash_lock) #define INP_HASH_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_hash_lock) #define INP_HASH_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_hash_lock) #define INP_HASH_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \ RA_LOCKED) #define INP_HASH_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \ RA_WLOCKED) #define INP_GROUP_LOCK_INIT(ipg, d) mtx_init(&(ipg)->ipg_lock, (d), NULL, \ MTX_DEF | MTX_DUPOK) #define INP_GROUP_LOCK_DESTROY(ipg) mtx_destroy(&(ipg)->ipg_lock) #define INP_GROUP_LOCK(ipg) mtx_lock(&(ipg)->ipg_lock) #define INP_GROUP_LOCK_ASSERT(ipg) mtx_assert(&(ipg)->ipg_lock, MA_OWNED) #define INP_GROUP_UNLOCK(ipg) mtx_unlock(&(ipg)->ipg_lock) #define INP_PCBHASH(faddr, lport, fport, mask) \ (((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask)) #define INP_PCBPORTHASH(lport, mask) \ (ntohs((lport)) & (mask)) #define INP6_PCBHASHKEY(faddr) ((faddr)->s6_addr32[3]) /* * Flags for inp_vflags -- historically version flags only */ #define INP_IPV4 0x1 #define INP_IPV6 0x2 #define INP_IPV6PROTO 0x4 /* opened under IPv6 protocol */ /* * Flags for inp_flags. */ #define INP_RECVOPTS 0x00000001 /* receive incoming IP options */ #define INP_RECVRETOPTS 0x00000002 /* receive IP options for reply */ #define INP_RECVDSTADDR 0x00000004 /* receive IP dst address */ #define INP_HDRINCL 0x00000008 /* user supplies entire IP header */ #define INP_HIGHPORT 0x00000010 /* user wants "high" port binding */ #define INP_LOWPORT 0x00000020 /* user wants "low" port binding */ #define INP_ANONPORT 0x00000040 /* port chosen for user */ #define INP_RECVIF 0x00000080 /* receive incoming interface */ #define INP_MTUDISC 0x00000100 /* user can do MTU discovery */ /* 0x000200 unused: was INP_FAITH */ #define INP_RECVTTL 0x00000400 /* receive incoming IP TTL */ #define INP_DONTFRAG 0x00000800 /* don't fragment packet */ #define INP_BINDANY 0x00001000 /* allow bind to any address */ #define INP_INHASHLIST 0x00002000 /* in_pcbinshash() has been called */ #define INP_RECVTOS 0x00004000 /* receive incoming IP TOS */ #define IN6P_IPV6_V6ONLY 0x00008000 /* restrict AF_INET6 socket for v6 */ #define IN6P_PKTINFO 0x00010000 /* receive IP6 dst and I/F */ #define IN6P_HOPLIMIT 0x00020000 /* receive hoplimit */ #define IN6P_HOPOPTS 0x00040000 /* receive hop-by-hop options */ #define IN6P_DSTOPTS 0x00080000 /* receive dst options after rthdr */ #define IN6P_RTHDR 0x00100000 /* receive routing header */ #define IN6P_RTHDRDSTOPTS 0x00200000 /* receive dstoptions before rthdr */ #define IN6P_TCLASS 0x00400000 /* receive traffic class value */ #define IN6P_AUTOFLOWLABEL 0x00800000 /* attach flowlabel automatically */ #define INP_TIMEWAIT 0x01000000 /* in TIMEWAIT, ppcb is tcptw */ #define INP_ONESBCAST 0x02000000 /* send all-ones broadcast */ #define INP_DROPPED 0x04000000 /* protocol drop flag */ #define INP_SOCKREF 0x08000000 /* strong socket reference */ #define INP_RESERVED_0 0x10000000 /* reserved field */ #define INP_RESERVED_1 0x20000000 /* reserved field */ #define IN6P_RFC2292 0x40000000 /* used RFC2292 API on the socket */ #define IN6P_MTU 0x80000000 /* receive path MTU */ #define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\ INP_RECVIF|INP_RECVTTL|INP_RECVTOS|\ IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\ IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\ IN6P_MTU) /* * Flags for inp_flags2. */ #define INP_LLE_VALID 0x00000001 /* cached lle is valid */ #define INP_RT_VALID 0x00000002 /* cached rtentry is valid */ #define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */ #define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */ #define INP_FREED 0x00000010 /* inp itself is not valid */ #define INP_REUSEADDR 0x00000020 /* SO_REUSEADDR option is set */ #define INP_BINDMULTI 0x00000040 /* IP_BINDMULTI option is set */ #define INP_RSS_BUCKET_SET 0x00000080 /* IP_RSS_LISTEN_BUCKET is set */ #define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */ #define INP_RECVRSSBUCKETID 0x00000200 /* populate recv datagram with bucket id */ /* * Flags passed to in_pcblookup*() functions. */ #define INPLOOKUP_WILDCARD 0x00000001 /* Allow wildcard sockets. */ #define INPLOOKUP_RLOCKPCB 0x00000002 /* Return inpcb read-locked. */ #define INPLOOKUP_WLOCKPCB 0x00000004 /* Return inpcb write-locked. */ #define INPLOOKUP_MASK (INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB | \ INPLOOKUP_WLOCKPCB) #define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb) #define sotoin6pcb(so) sotoinpcb(so) /* for KAME src sync over BSD*'s */ #define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family #define INP_CHECK_SOCKAF(so, af) (INP_SOCKAF(so) == af) /* * Constants for pcbinfo.ipi_hashfields. */ #define IPI_HASHFIELDS_NONE 0 #define IPI_HASHFIELDS_2TUPLE 1 #define IPI_HASHFIELDS_4TUPLE 2 #ifdef _KERNEL VNET_DECLARE(int, ipport_reservedhigh); VNET_DECLARE(int, ipport_reservedlow); VNET_DECLARE(int, ipport_lowfirstauto); VNET_DECLARE(int, ipport_lowlastauto); VNET_DECLARE(int, ipport_firstauto); VNET_DECLARE(int, ipport_lastauto); VNET_DECLARE(int, ipport_hifirstauto); VNET_DECLARE(int, ipport_hilastauto); VNET_DECLARE(int, ipport_randomized); VNET_DECLARE(int, ipport_randomcps); VNET_DECLARE(int, ipport_randomtime); VNET_DECLARE(int, ipport_stoprandom); VNET_DECLARE(int, ipport_tcpallocs); #define V_ipport_reservedhigh VNET(ipport_reservedhigh) #define V_ipport_reservedlow VNET(ipport_reservedlow) #define V_ipport_lowfirstauto VNET(ipport_lowfirstauto) #define V_ipport_lowlastauto VNET(ipport_lowlastauto) #define V_ipport_firstauto VNET(ipport_firstauto) #define V_ipport_lastauto VNET(ipport_lastauto) #define V_ipport_hifirstauto VNET(ipport_hifirstauto) #define V_ipport_hilastauto VNET(ipport_hilastauto) #define V_ipport_randomized VNET(ipport_randomized) #define V_ipport_randomcps VNET(ipport_randomcps) #define V_ipport_randomtime VNET(ipport_randomtime) #define V_ipport_stoprandom VNET(ipport_stoprandom) #define V_ipport_tcpallocs VNET(ipport_tcpallocs) void in_pcbinfo_destroy(struct inpcbinfo *); void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *, int, int, char *, uma_init, uma_fini, uint32_t, u_int); int in_pcbbind_check_bindmulti(const struct inpcb *ni, const struct inpcb *oi); struct inpcbgroup * in_pcbgroup_byhash(struct inpcbinfo *, u_int, uint32_t); struct inpcbgroup * in_pcbgroup_byinpcb(struct inpcb *); struct inpcbgroup * in_pcbgroup_bytuple(struct inpcbinfo *, struct in_addr, u_short, struct in_addr, u_short); void in_pcbgroup_destroy(struct inpcbinfo *); int in_pcbgroup_enabled(struct inpcbinfo *); void in_pcbgroup_init(struct inpcbinfo *, u_int, int); void in_pcbgroup_remove(struct inpcb *); void in_pcbgroup_update(struct inpcb *); void in_pcbgroup_update_mbuf(struct inpcb *, struct mbuf *); void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *); int in_pcballoc(struct socket *, struct inpcbinfo *); int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *); int in_pcb_lport(struct inpcb *, struct in_addr *, u_short *, struct ucred *, int); int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *, u_short *, struct ucred *); int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *); int in_pcbconnect_mbuf(struct inpcb *, struct sockaddr *, struct ucred *, struct mbuf *); int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *, u_short *, in_addr_t *, u_short *, struct inpcb **, struct ucred *); void in_pcbdetach(struct inpcb *); void in_pcbdisconnect(struct inpcb *); void in_pcbdrop(struct inpcb *); void in_pcbfree(struct inpcb *); int in_pcbinshash(struct inpcb *); int in_pcbinshash_nopcbgroup(struct inpcb *); int in_pcbladdr(struct inpcb *, struct in_addr *, struct in_addr *, struct ucred *); struct inpcb * in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_short, int, struct ucred *); struct inpcb * in_pcblookup(struct inpcbinfo *, struct in_addr, u_int, struct in_addr, u_int, int, struct ifnet *); struct inpcb * in_pcblookup_mbuf(struct inpcbinfo *, struct in_addr, u_int, struct in_addr, u_int, int, struct ifnet *, struct mbuf *); void in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr, int, struct inpcb *(*)(struct inpcb *, int)); void in_pcbref(struct inpcb *); void in_pcbrehash(struct inpcb *); void in_pcbrehash_mbuf(struct inpcb *, struct mbuf *); int in_pcbrele(struct inpcb *); int in_pcbrele_rlocked(struct inpcb *); int in_pcbrele_wlocked(struct inpcb *); void in_pcbsetsolabel(struct socket *so); int in_getpeeraddr(struct socket *so, struct sockaddr **nam); int in_getsockaddr(struct socket *so, struct sockaddr **nam); struct sockaddr * in_sockaddr(in_port_t port, struct in_addr *addr); void in_pcbsosetlabel(struct socket *so); #endif /* _KERNEL */ #endif /* !_NETINET_IN_PCB_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)in_systm.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NETINET_IN_SYSTM_H_ #define _NETINET_IN_SYSTM_H_ /* * Miscellaneous internetwork * definitions for kernel. */ /* * Network types. * * Internally the system keeps counters in the headers with the bytes * swapped so that VAX instructions will work on them. It reverses * the bytes before transmission at each protocol level. The n_ types * represent the types with the bytes in ``high-ender'' order. Network * byte order is usually referered to as big-endian these days rather * than high-ender, which sadly invokes an Orson Scott Card novel, or * worse, the movie. */ typedef u_int16_t n_short; /* short as received from the net */ typedef u_int32_t n_long; /* long as received from the net */ typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */ #ifdef _KERNEL uint32_t iptime(void); #endif #endif /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ip.h 8.2 (Berkeley) 6/1/94 * $FreeBSD$ */ #ifndef _NETINET_IP_H_ #define _NETINET_IP_H_ #include /* * Definitions for internet protocol version 4. * * Per RFC 791, September 1981. */ #define IPVERSION 4 /* * Structure of an internet header, naked of options. */ struct ip { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #endif u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ } __packed __aligned(2); #define IP_MAXPACKET 65535 /* maximum packet size */ /* * Definitions for IP type of service (ip_tos). */ #define IPTOS_LOWDELAY 0x10 #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 /* * Definitions for IP precedence (also in ip_tos) (deprecated). */ #define IPTOS_PREC_NETCONTROL IPTOS_DSCP_CS7 #define IPTOS_PREC_INTERNETCONTROL IPTOS_DSCP_CS6 #define IPTOS_PREC_CRITIC_ECP IPTOS_DSCP_CS5 #define IPTOS_PREC_FLASHOVERRIDE IPTOS_DSCP_CS4 #define IPTOS_PREC_FLASH IPTOS_DSCP_CS3 #define IPTOS_PREC_IMMEDIATE IPTOS_DSCP_CS2 #define IPTOS_PREC_PRIORITY IPTOS_DSCP_CS1 #define IPTOS_PREC_ROUTINE IPTOS_DSCP_CS0 /* * Definitions for DiffServ Codepoints as per RFC2474 and RFC5865. */ #define IPTOS_DSCP_CS0 0x00 #define IPTOS_DSCP_CS1 0x20 #define IPTOS_DSCP_AF11 0x28 #define IPTOS_DSCP_AF12 0x30 #define IPTOS_DSCP_AF13 0x38 #define IPTOS_DSCP_CS2 0x40 #define IPTOS_DSCP_AF21 0x48 #define IPTOS_DSCP_AF22 0x50 #define IPTOS_DSCP_AF23 0x58 #define IPTOS_DSCP_CS3 0x60 #define IPTOS_DSCP_AF31 0x68 #define IPTOS_DSCP_AF32 0x70 #define IPTOS_DSCP_AF33 0x78 #define IPTOS_DSCP_CS4 0x80 #define IPTOS_DSCP_AF41 0x88 #define IPTOS_DSCP_AF42 0x90 #define IPTOS_DSCP_AF43 0x98 #define IPTOS_DSCP_CS5 0xa0 #define IPTOS_DSCP_VA 0xb0 #define IPTOS_DSCP_EF 0xb8 #define IPTOS_DSCP_CS6 0xc0 #define IPTOS_DSCP_CS7 0xe0 /* * ECN (Explicit Congestion Notification) codepoints in RFC3168 mapped to the * lower 2 bits of the TOS field. */ #define IPTOS_ECN_NOTECT 0x00 /* not-ECT */ #define IPTOS_ECN_ECT1 0x01 /* ECN-capable transport (1) */ #define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */ #define IPTOS_ECN_CE 0x03 /* congestion experienced */ #define IPTOS_ECN_MASK 0x03 /* ECN field mask */ /* * Definitions for options. */ #define IPOPT_COPIED(o) ((o)&0x80) #define IPOPT_CLASS(o) ((o)&0x60) #define IPOPT_NUMBER(o) ((o)&0x1f) #define IPOPT_CONTROL 0x00 #define IPOPT_RESERVED1 0x20 #define IPOPT_DEBMEAS 0x40 #define IPOPT_RESERVED2 0x60 #define IPOPT_EOL 0 /* end of option list */ #define IPOPT_NOP 1 /* no operation */ #define IPOPT_RR 7 /* record packet route */ #define IPOPT_TS 68 /* timestamp */ #define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ #define IPOPT_LSRR 131 /* loose source route */ #define IPOPT_ESO 133 /* extended security */ #define IPOPT_CIPSO 134 /* commerical security */ #define IPOPT_SATID 136 /* satnet id */ #define IPOPT_SSRR 137 /* strict source route */ #define IPOPT_RA 148 /* router alert */ /* * Offsets to fields in options other than EOL and NOP. */ #define IPOPT_OPTVAL 0 /* option ID */ #define IPOPT_OLEN 1 /* option length */ #define IPOPT_OFFSET 2 /* offset within option */ #define IPOPT_MINOFF 4 /* min value of above */ /* * Time stamp option structure. */ struct ip_timestamp { u_char ipt_code; /* IPOPT_TS */ u_char ipt_len; /* size of structure (variable) */ u_char ipt_ptr; /* index of current entry */ #if BYTE_ORDER == LITTLE_ENDIAN u_char ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #endif union ipt_timestamp { uint32_t ipt_time[1]; /* network format */ struct ipt_ta { struct in_addr ipt_addr; uint32_t ipt_time; /* network format */ } ipt_ta[1]; } ipt_timestamp; }; /* Flag bits for ipt_flg. */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ /* Bits for security (not byte swapped). */ #define IPOPT_SECUR_UNCLASS 0x0000 #define IPOPT_SECUR_CONFID 0xf135 #define IPOPT_SECUR_EFTO 0x789a #define IPOPT_SECUR_MMMM 0xbc4d #define IPOPT_SECUR_RESTR 0xaf13 #define IPOPT_SECUR_SECRET 0xd788 #define IPOPT_SECUR_TOPSECRET 0x6bc5 /* * Internet implementation parameters. */ #define MAXTTL 255 /* maximum time to live (seconds) */ #define IPDEFTTL 64 /* default ttl, from RFC 1340 */ #define IPFRAGTTL 60 /* time to live for frags, slowhz */ #define IPTTLDEC 1 /* subtracted when forwarding */ #define IP_MSS 576 /* default maximum segment size */ /* * This is the real IPv4 pseudo header, used for computing the TCP and UDP * checksums. For the Internet checksum, struct ipovly can be used instead. * For stronger checksums, the real thing must be used. */ struct ippseudo { struct in_addr ippseudo_src; /* source internet address */ struct in_addr ippseudo_dst; /* destination internet address */ u_char ippseudo_pad; /* pad, must be zero */ u_char ippseudo_p; /* protocol */ u_short ippseudo_len; /* protocol length */ }; #endif /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ip_var.h 8.2 (Berkeley) 1/9/95 * $FreeBSD$ */ #ifndef _NETINET_IP_VAR_H_ #define _NETINET_IP_VAR_H_ #include /* * Overlay for ip header used by other protocols (tcp, udp). */ struct ipovly { u_char ih_x1[9]; /* (unused) */ u_char ih_pr; /* protocol */ u_short ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ }; #ifdef _KERNEL /* * Ip reassembly queue structure. Each fragment * being reassembled is attached to one of these structures. * They are timed out after ipq_ttl drops to 0, and may also * be reclaimed if memory becomes tight. */ struct ipq { TAILQ_ENTRY(ipq) ipq_list; /* to other reass headers */ u_char ipq_ttl; /* time for reass q to live */ u_char ipq_p; /* protocol of this fragment */ u_short ipq_id; /* sequence id for reassembly */ struct mbuf *ipq_frags; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; u_char ipq_nfrags; /* # frags in this packet */ struct label *ipq_label; /* MAC label */ }; #endif /* _KERNEL */ /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. * The actual length of the options (including ipopt_dst) * is in m_len. */ #define MAX_IPOPTLEN 40 struct ipoption { struct in_addr ipopt_dst; /* first-hop dst if source routed */ char ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; /* * Structure attached to inpcb.ip_moptions and * passed to ip_output when IP multicast options are in use. * This structure is lazy-allocated. */ struct ip_moptions { struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */ struct in_addr imo_multicast_addr; /* ifindex/addr on MULTICAST_IF */ u_long imo_multicast_vif; /* vif num outgoing multicasts */ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */ u_char imo_multicast_loop; /* 1 => hear sends if a member */ u_short imo_num_memberships; /* no. memberships this socket */ u_short imo_max_memberships; /* max memberships this socket */ struct in_multi **imo_membership; /* group memberships */ struct in_mfilter *imo_mfilters; /* source filters */ STAILQ_ENTRY(ip_moptions) imo_link; }; struct ipstat { uint64_t ips_total; /* total packets received */ uint64_t ips_badsum; /* checksum bad */ uint64_t ips_tooshort; /* packet too short */ uint64_t ips_toosmall; /* not enough data */ uint64_t ips_badhlen; /* ip header length < data size */ uint64_t ips_badlen; /* ip length < ip header length */ uint64_t ips_fragments; /* fragments received */ uint64_t ips_fragdropped; /* frags dropped (dups, out of space) */ uint64_t ips_fragtimeout; /* fragments timed out */ uint64_t ips_forward; /* packets forwarded */ uint64_t ips_fastforward; /* packets fast forwarded */ uint64_t ips_cantforward; /* packets rcvd for unreachable dest */ uint64_t ips_redirectsent; /* packets forwarded on same net */ uint64_t ips_noproto; /* unknown or unsupported protocol */ uint64_t ips_delivered; /* datagrams delivered to upper level*/ uint64_t ips_localout; /* total ip packets generated here */ uint64_t ips_odropped; /* lost packets due to nobufs, etc. */ uint64_t ips_reassembled; /* total packets reassembled ok */ uint64_t ips_fragmented; /* datagrams successfully fragmented */ uint64_t ips_ofragments; /* output fragments created */ uint64_t ips_cantfrag; /* don't fragment flag was set, etc. */ uint64_t ips_badoptions; /* error in option processing */ uint64_t ips_noroute; /* packets discarded due to no route */ uint64_t ips_badvers; /* ip version != 4 */ uint64_t ips_rawout; /* total raw ip packets generated */ uint64_t ips_toolong; /* ip length > max ip packet size */ uint64_t ips_notmember; /* multicasts for unregistered grps */ uint64_t ips_nogif; /* no match gif found */ uint64_t ips_badaddr; /* invalid address on header */ }; #ifdef _KERNEL #include #include VNET_PCPUSTAT_DECLARE(struct ipstat, ipstat); /* * In-kernel consumers can use these accessor macros directly to update * stats. */ #define IPSTAT_ADD(name, val) \ VNET_PCPUSTAT_ADD(struct ipstat, ipstat, name, (val)) #define IPSTAT_SUB(name, val) IPSTAT_ADD(name, -(val)) #define IPSTAT_INC(name) IPSTAT_ADD(name, 1) #define IPSTAT_DEC(name) IPSTAT_SUB(name, 1) /* * Kernel module consumers must use this accessor macro. */ void kmod_ipstat_inc(int statnum); #define KMOD_IPSTAT_INC(name) \ kmod_ipstat_inc(offsetof(struct ipstat, name) / sizeof(uint64_t)) void kmod_ipstat_dec(int statnum); #define KMOD_IPSTAT_DEC(name) \ kmod_ipstat_dec(offsetof(struct ipstat, name) / sizeof(uint64_t)) /* flags passed to ip_output as last parameter */ #define IP_FORWARDING 0x1 /* most of ip header exists */ #define IP_RAWOUTPUT 0x2 /* raw ip header exists */ #define IP_SENDONES 0x4 /* send all-ones broadcast */ #define IP_SENDTOIF 0x8 /* send on specific ifnet */ #define IP_ROUTETOIF SO_DONTROUTE /* 0x10 bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* 0x20 can send broadcast packets */ #define IP_NODEFAULTFLOWID 0x40 /* Don't set the flowid from inp */ #ifdef __NO_STRICT_ALIGNMENT #define IP_HDR_ALIGNED_P(ip) 1 #else #define IP_HDR_ALIGNED_P(ip) ((((intptr_t) (ip)) & 3) == 0) #endif struct ip; struct inpcb; struct route; struct sockopt; VNET_DECLARE(int, ip_defttl); /* default IP ttl */ VNET_DECLARE(int, ipforwarding); /* ip forwarding */ #ifdef IPSTEALTH VNET_DECLARE(int, ipstealth); /* stealth forwarding */ #endif extern u_char ip_protox[]; VNET_DECLARE(struct socket *, ip_rsvpd); /* reservation protocol daemon*/ VNET_DECLARE(struct socket *, ip_mrouter); /* multicast routing daemon */ extern int (*legal_vif_num)(int); extern u_long (*ip_mcast_src)(int); VNET_DECLARE(int, rsvp_on); VNET_DECLARE(int, drop_redirect); extern struct pr_usrreqs rip_usrreqs; #define V_ip_id VNET(ip_id) #define V_ip_defttl VNET(ip_defttl) #define V_ipforwarding VNET(ipforwarding) #ifdef IPSTEALTH #define V_ipstealth VNET(ipstealth) #endif #define V_ip_rsvpd VNET(ip_rsvpd) #define V_ip_mrouter VNET(ip_mrouter) #define V_rsvp_on VNET(rsvp_on) #define V_drop_redirect VNET(drop_redirect) void inp_freemoptions(struct ip_moptions *); int inp_getmoptions(struct inpcb *, struct sockopt *); int inp_setmoptions(struct inpcb *, struct sockopt *); int ip_ctloutput(struct socket *, struct sockopt *sopt); void ip_drain(void); int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, u_long if_hwassist_flags); void ip_forward(struct mbuf *m, int srcrt); void ip_init(void); #ifdef VIMAGE void ip_destroy(void); #endif extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, struct ip_moptions *); int ip_output(struct mbuf *, struct mbuf *, struct route *, int, struct ip_moptions *, struct inpcb *); int ipproto_register(short); int ipproto_unregister(short); struct mbuf * ip_reass(struct mbuf *); struct in_ifaddr * ip_rtaddr(struct in_addr, u_int fibnum); void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *, struct mbuf *); void ip_slowtimo(void); void ip_fillid(struct ip *); int rip_ctloutput(struct socket *, struct sockopt *); void rip_ctlinput(int, struct sockaddr *, void *); void rip_init(void); #ifdef VIMAGE void rip_destroy(void); #endif int rip_input(struct mbuf **, int *, int); int rip_output(struct mbuf *, struct socket *, ...); int ipip_input(struct mbuf **, int *, int); int rsvp_input(struct mbuf **, int *, int); int ip_rsvp_init(struct socket *); int ip_rsvp_done(void); extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *); extern void (*ip_rsvp_force_done)(struct socket *); extern int (*rsvp_input_p)(struct mbuf **, int *, int); VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */ #define V_inet_pfil_hook VNET(inet_pfil_hook) void in_delayed_cksum(struct mbuf *m); /* Hooks for ipfw, dummynet, divert etc. Most are declared in raw_ip.c */ /* * Reference to an ipfw or packet filter rule that can be carried * outside critical sections. * A rule is identified by rulenum:rule_id which is ordered. * In version chain_id the rule can be found in slot 'slot', so * we don't need a lookup if chain_id == chain->id. * * On exit from the firewall this structure refers to the rule after * the matching one (slot points to the new rule; rulenum:rule_id-1 * is the matching rule), and additional info (e.g. info often contains * the insn argument or tablearg in the low 16 bits, in host format). * On entry, the structure is valid if slot>0, and refers to the starting * rules. 'info' contains the reason for reinject, e.g. divert port, * divert direction, and so on. */ struct ipfw_rule_ref { uint32_t slot; /* slot for matching rule */ uint32_t rulenum; /* matching rule number */ uint32_t rule_id; /* matching rule id */ uint32_t chain_id; /* ruleset id */ uint32_t info; /* see below */ }; enum { IPFW_INFO_MASK = 0x0000ffff, IPFW_INFO_OUT = 0x00000000, /* outgoing, just for convenience */ IPFW_INFO_IN = 0x80000000, /* incoming, overloads dir */ IPFW_ONEPASS = 0x40000000, /* One-pass, do not reinject */ IPFW_IS_MASK = 0x30000000, /* which source ? */ IPFW_IS_DIVERT = 0x20000000, IPFW_IS_DUMMYNET =0x10000000, IPFW_IS_PIPE = 0x08000000, /* pipe=1, queue = 0 */ }; #define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */ #define MTAG_IPFW_RULE 1262273568 /* rule reference */ #define MTAG_IPFW_CALL 1308397630 /* call stack */ struct ip_fw_args; typedef int (*ip_fw_chk_ptr_t)(struct ip_fw_args *args); typedef int (*ip_fw_ctl_ptr_t)(struct sockopt *); VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr); #define V_ip_fw_ctl_ptr VNET(ip_fw_ctl_ptr) /* Divert hooks. */ extern void (*ip_divert_ptr)(struct mbuf *m, int incoming); /* ng_ipfw hooks -- XXX make it the same as divert and dummynet */ extern int (*ng_ipfw_input_p)(struct mbuf **, int, struct ip_fw_args *, int); extern int (*ip_dn_ctl_ptr)(struct sockopt *); extern int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *); #endif /* _KERNEL */ #endif /* !_NETINET_IP_VAR_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)udp.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NETINET_UDP_H_ #define _NETINET_UDP_H_ /* * UDP protocol header. * Per RFC 768, September, 1981. */ struct udphdr { u_short uh_sport; /* source port */ u_short uh_dport; /* destination port */ u_short uh_ulen; /* udp length */ u_short uh_sum; /* udp checksum */ }; /* * User-settable options (used with setsockopt). */ #define UDP_ENCAP 1 /* Start of reserved space for third-party user-settable options. */ #define UDP_VENDOR SO_VENDOR /* * UDP Encapsulation of IPsec Packets options. */ /* Encapsulation types. */ #define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ #define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-02+ */ /* Default ESP in UDP encapsulation port. */ #define UDP_ENCAP_ESPINUDP_PORT 500 /* Maximum UDP fragment size for ESP over UDP. */ #define UDP_ENCAP_ESPINUDP_MAXFRAGLEN 552 #endif /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)udp_var.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _NETINET_UDP_VAR_H_ #define _NETINET_UDP_VAR_H_ /* * UDP kernel structures and variables. */ struct udpiphdr { struct ipovly ui_i; /* overlaid ip structure */ struct udphdr ui_u; /* udp header */ }; #define ui_x1 ui_i.ih_x1 #define ui_v ui_i.ih_x1[0] #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len #define ui_src ui_i.ih_src #define ui_dst ui_i.ih_dst #define ui_sport ui_u.uh_sport #define ui_dport ui_u.uh_dport #define ui_ulen ui_u.uh_ulen #define ui_sum ui_u.uh_sum struct inpcb; struct mbuf; typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *, const struct sockaddr *, void *); /* * UDP control block; one per udp. */ struct udpcb { udp_tun_func_t u_tun_func; /* UDP kernel tunneling callback. */ u_int u_flags; /* Generic UDP flags. */ uint16_t u_rxcslen; /* Coverage for incoming datagrams. */ uint16_t u_txcslen; /* Coverage for outgoing datagrams. */ void *u_tun_ctx; /* Tunneling callback context. */ }; #define intoudpcb(ip) ((struct udpcb *)(ip)->inp_ppcb) #define sotoudpcb(so) (intoudpcb(sotoinpcb(so))) /* IPsec: ESP in UDP tunneling: */ #define UF_ESPINUDP_NON_IKE 0x00000001 /* w/ non-IKE marker .. */ /* .. per draft-ietf-ipsec-nat-t-ike-0[01], * and draft-ietf-ipsec-udp-encaps-(00/)01.txt */ #define UF_ESPINUDP 0x00000002 /* w/ non-ESP marker. */ struct udpstat { /* input statistics: */ uint64_t udps_ipackets; /* total input packets */ uint64_t udps_hdrops; /* packet shorter than header */ uint64_t udps_badsum; /* checksum error */ uint64_t udps_nosum; /* no checksum */ uint64_t udps_badlen; /* data length larger than packet */ uint64_t udps_noport; /* no socket on port */ uint64_t udps_noportbcast; /* of above, arrived as broadcast */ uint64_t udps_fullsock; /* not delivered, input socket full */ uint64_t udpps_pcbcachemiss; /* input packets missing pcb cache */ uint64_t udpps_pcbhashmiss; /* input packets not for hashed pcb */ /* output statistics: */ uint64_t udps_opackets; /* total output packets */ uint64_t udps_fastout; /* output packets on fast path */ /* of no socket on port, arrived as multicast */ uint64_t udps_noportmcast; uint64_t udps_filtermcast; /* blocked by multicast filter */ }; #ifdef _KERNEL #include VNET_PCPUSTAT_DECLARE(struct udpstat, udpstat); /* * In-kernel consumers can use these accessor macros directly to update * stats. */ #define UDPSTAT_ADD(name, val) \ VNET_PCPUSTAT_ADD(struct udpstat, udpstat, name, (val)) #define UDPSTAT_INC(name) UDPSTAT_ADD(name, 1) /* * Kernel module consumers must use this accessor macro. */ void kmod_udpstat_inc(int statnum); #define KMOD_UDPSTAT_INC(name) \ kmod_udpstat_inc(offsetof(struct udpstat, name) / sizeof(uint64_t)) #endif /* * Identifiers for UDP sysctl nodes. */ #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ #define UDPCTL_STATS 2 /* statistics (read-only) */ #define UDPCTL_MAXDGRAM 3 /* max datagram size */ #define UDPCTL_RECVSPACE 4 /* default receive buffer space */ #define UDPCTL_PCBLIST 5 /* list of PCBs for UDP sockets */ #ifdef _KERNEL #include SYSCTL_DECL(_net_inet_udp); extern struct pr_usrreqs udp_usrreqs; VNET_DECLARE(struct inpcbhead, udb); VNET_DECLARE(struct inpcbinfo, udbinfo); VNET_DECLARE(struct inpcbhead, ulitecb); VNET_DECLARE(struct inpcbinfo, ulitecbinfo); #define V_udb VNET(udb) #define V_udbinfo VNET(udbinfo) #define V_ulitecb VNET(ulitecb) #define V_ulitecbinfo VNET(ulitecbinfo) extern u_long udp_sendspace; extern u_long udp_recvspace; VNET_DECLARE(int, udp_cksum); VNET_DECLARE(int, udp_blackhole); #define V_udp_cksum VNET(udp_cksum) #define V_udp_blackhole VNET(udp_blackhole) extern int udp_log_in_vain; static __inline struct inpcbinfo * udp_get_inpcbinfo(int protocol) { return (protocol == IPPROTO_UDP) ? &V_udbinfo : &V_ulitecbinfo; } static __inline struct inpcbhead * udp_get_pcblist(int protocol) { return (protocol == IPPROTO_UDP) ? &V_udb : &V_ulitecb; } int udp_newudpcb(struct inpcb *); void udp_discardcb(struct udpcb *); void udp_ctlinput(int, struct sockaddr *, void *); void udplite_ctlinput(int, struct sockaddr *, void *); int udp_ctloutput(struct socket *, struct sockopt *); void udp_init(void); void udplite_init(void); #ifdef VIMAGE void udp_destroy(void); void udplite_destroy(void); #endif int udp_input(struct mbuf **, int *, int); void udplite_input(struct mbuf *, int); struct inpcb *udp_notify(struct inpcb *inp, int errno); int udp_shutdown(struct socket *so); int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, void *ctx); #endif /* _KERNEL */ #endif /* _NETINET_UDP_VAR_H_ */ /*- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * 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. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. * * $KAME: in6.h,v 1.89 2001/05/27 13:28:35 itojun Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)in.h 8.3 (Berkeley) 1/3/94 * $FreeBSD$ */ #ifndef __KAME_NETINET_IN_H_INCLUDED_ #error "do not include netinet6/in6.h directly, include netinet/in.h. see RFC2553" #endif #ifndef _NETINET6_IN6_H_ #define _NETINET6_IN6_H_ /* * Identification of the network protocol stack * for *BSD-current/release: http://www.kame.net/dev/cvsweb.cgi/kame/COVERAGE * has the table of implementation/integration differences. */ #define __KAME__ #define __KAME_VERSION "FreeBSD" /* * IPv6 port allocation rules should mirror the IPv4 rules and are controlled * by the net.inet.ip.portrange sysctl tree. The following defines exist * for compatibility with userland applications that need them. */ #if __BSD_VISIBLE #define IPV6PORT_RESERVED 1024 #define IPV6PORT_ANONMIN 49152 #define IPV6PORT_ANONMAX 65535 #define IPV6PORT_RESERVEDMIN 600 #define IPV6PORT_RESERVEDMAX (IPV6PORT_RESERVED-1) #endif /* * IPv6 address */ struct in6_addr { union { uint8_t __u6_addr8[16]; uint16_t __u6_addr16[8]; uint32_t __u6_addr32[4]; } __u6_addr; /* 128-bit IP6 address */ }; #define s6_addr __u6_addr.__u6_addr8 #ifdef _KERNEL /* XXX nonstandard */ #define s6_addr8 __u6_addr.__u6_addr8 #define s6_addr16 __u6_addr.__u6_addr16 #define s6_addr32 __u6_addr.__u6_addr32 #endif #define INET6_ADDRSTRLEN 46 /* * XXX missing POSIX.1-2001 macro IPPROTO_IPV6. */ /* * Socket address for IPv6 */ #if __BSD_VISIBLE #define SIN6_LEN #endif struct sockaddr_in6 { uint8_t sin6_len; /* length of this struct */ sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* Transport layer port # */ uint32_t sin6_flowinfo; /* IP6 flow information */ struct in6_addr sin6_addr; /* IP6 address */ uint32_t sin6_scope_id; /* scope zone index */ }; /* * Local definition for masks */ #ifdef _KERNEL /* XXX nonstandard */ #define IN6MASK0 {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}} #define IN6MASK32 {{{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}} #define IN6MASK64 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}} #define IN6MASK96 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}} #define IN6MASK128 {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}} #endif #ifdef _KERNEL extern const struct sockaddr_in6 sa6_any; extern const struct in6_addr in6mask0; extern const struct in6_addr in6mask32; extern const struct in6_addr in6mask64; extern const struct in6_addr in6mask96; extern const struct in6_addr in6mask128; #endif /* _KERNEL */ /* * Macros started with IPV6_ADDR is KAME local */ #ifdef _KERNEL /* XXX nonstandard */ #if _BYTE_ORDER == _BIG_ENDIAN #define IPV6_ADDR_INT32_ONE 1 #define IPV6_ADDR_INT32_TWO 2 #define IPV6_ADDR_INT32_MNL 0xff010000 #define IPV6_ADDR_INT32_MLL 0xff020000 #define IPV6_ADDR_INT32_SMP 0x0000ffff #define IPV6_ADDR_INT16_ULL 0xfe80 #define IPV6_ADDR_INT16_USL 0xfec0 #define IPV6_ADDR_INT16_MLL 0xff02 #elif _BYTE_ORDER == _LITTLE_ENDIAN #define IPV6_ADDR_INT32_ONE 0x01000000 #define IPV6_ADDR_INT32_TWO 0x02000000 #define IPV6_ADDR_INT32_MNL 0x000001ff #define IPV6_ADDR_INT32_MLL 0x000002ff #define IPV6_ADDR_INT32_SMP 0xffff0000 #define IPV6_ADDR_INT16_ULL 0x80fe #define IPV6_ADDR_INT16_USL 0xc0fe #define IPV6_ADDR_INT16_MLL 0x02ff #endif #endif /* * Definition of some useful macros to handle IP6 addresses */ #if __BSD_VISIBLE #define IN6ADDR_ANY_INIT \ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}} #define IN6ADDR_LOOPBACK_INIT \ {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} #define IN6ADDR_NODELOCAL_ALLNODES_INIT \ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} #define IN6ADDR_INTFACELOCAL_ALLNODES_INIT \ {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} #define IN6ADDR_LINKLOCAL_ALLNODES_INIT \ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} #define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}} #define IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT \ {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 }}} #endif extern const struct in6_addr in6addr_any; extern const struct in6_addr in6addr_loopback; #if __BSD_VISIBLE extern const struct in6_addr in6addr_nodelocal_allnodes; extern const struct in6_addr in6addr_linklocal_allnodes; extern const struct in6_addr in6addr_linklocal_allrouters; extern const struct in6_addr in6addr_linklocal_allv2routers; #endif /* * Equality * NOTE: Some of kernel programming environment (for example, openbsd/sparc) * does not supply memcmp(). For userland memcmp() is preferred as it is * in ANSI standard. */ #ifdef _KERNEL #define IN6_ARE_ADDR_EQUAL(a, b) \ (bcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0) #else #if __BSD_VISIBLE #define IN6_ARE_ADDR_EQUAL(a, b) \ (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0) #endif #endif /* * Unspecified */ #define IN6_IS_ADDR_UNSPECIFIED(a) \ ((a)->__u6_addr.__u6_addr32[0] == 0 && \ (a)->__u6_addr.__u6_addr32[1] == 0 && \ (a)->__u6_addr.__u6_addr32[2] == 0 && \ (a)->__u6_addr.__u6_addr32[3] == 0) /* * Loopback */ #define IN6_IS_ADDR_LOOPBACK(a) \ ((a)->__u6_addr.__u6_addr32[0] == 0 && \ (a)->__u6_addr.__u6_addr32[1] == 0 && \ (a)->__u6_addr.__u6_addr32[2] == 0 && \ (a)->__u6_addr.__u6_addr32[3] == ntohl(1)) /* * IPv4 compatible */ #define IN6_IS_ADDR_V4COMPAT(a) \ ((a)->__u6_addr.__u6_addr32[0] == 0 && \ (a)->__u6_addr.__u6_addr32[1] == 0 && \ (a)->__u6_addr.__u6_addr32[2] == 0 && \ (a)->__u6_addr.__u6_addr32[3] != 0 && \ (a)->__u6_addr.__u6_addr32[3] != ntohl(1)) /* * Mapped */ #define IN6_IS_ADDR_V4MAPPED(a) \ ((a)->__u6_addr.__u6_addr32[0] == 0 && \ (a)->__u6_addr.__u6_addr32[1] == 0 && \ (a)->__u6_addr.__u6_addr32[2] == ntohl(0x0000ffff)) /* * KAME Scope Values */ #ifdef _KERNEL /* XXX nonstandard */ #define IPV6_ADDR_SCOPE_NODELOCAL 0x01 #define IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 #define IPV6_ADDR_SCOPE_LINKLOCAL 0x02 #define IPV6_ADDR_SCOPE_SITELOCAL 0x05 #define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ #define IPV6_ADDR_SCOPE_GLOBAL 0x0e #else #define __IPV6_ADDR_SCOPE_NODELOCAL 0x01 #define __IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 #define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02 #define __IPV6_ADDR_SCOPE_SITELOCAL 0x05 #define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ #define __IPV6_ADDR_SCOPE_GLOBAL 0x0e #endif /* * Unicast Scope * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373). */ #define IN6_IS_ADDR_LINKLOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) #define IN6_IS_ADDR_SITELOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) /* * Multicast */ #define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) #ifdef _KERNEL /* XXX nonstandard */ #define IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) #else #define __IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) #endif /* * Multicast Scope */ #ifdef _KERNEL /* refers nonstandard items */ #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL)) #define IN6_IS_ADDR_MC_INTFACELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_INTFACELOCAL)) #define IN6_IS_ADDR_MC_LINKLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL)) #define IN6_IS_ADDR_MC_SITELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL)) #define IN6_IS_ADDR_MC_ORGLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL)) #define IN6_IS_ADDR_MC_GLOBAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL)) #else #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL)) #define IN6_IS_ADDR_MC_LINKLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL)) #define IN6_IS_ADDR_MC_SITELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL)) #define IN6_IS_ADDR_MC_ORGLOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL)) #define IN6_IS_ADDR_MC_GLOBAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && \ (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL)) #endif #ifdef _KERNEL /* nonstandard */ /* * KAME Scope */ #define IN6_IS_SCOPE_LINKLOCAL(a) \ ((IN6_IS_ADDR_LINKLOCAL(a)) || \ (IN6_IS_ADDR_MC_LINKLOCAL(a))) #define IN6_IS_SCOPE_EMBED(a) \ ((IN6_IS_ADDR_LINKLOCAL(a)) || \ (IN6_IS_ADDR_MC_LINKLOCAL(a)) || \ (IN6_IS_ADDR_MC_INTFACELOCAL(a))) #define IFA6_IS_DEPRECATED(a) \ ((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \ (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \ (a)->ia6_lifetime.ia6t_pltime) #define IFA6_IS_INVALID(a) \ ((a)->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME && \ (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \ (a)->ia6_lifetime.ia6t_vltime) #endif /* _KERNEL */ /* * IP6 route structure */ #if __BSD_VISIBLE struct route_in6 { struct rtentry *ro_rt; struct llentry *ro_lle; struct in6_addr *ro_ia6; int ro_flags; struct sockaddr_in6 ro_dst; }; #endif /* * Options for use with [gs]etsockopt at the IPV6 level. * First word of comment is data type; bool is stored in int. */ /* no hdrincl */ #if 0 /* the followings are relic in IPv4 and hence are disabled */ #define IPV6_OPTIONS 1 /* buf/ip6_opts; set/get IP6 options */ #define IPV6_RECVOPTS 5 /* bool; receive all IP6 opts w/dgram */ #define IPV6_RECVRETOPTS 6 /* bool; receive IP6 opts for response */ #define IPV6_RECVDSTADDR 7 /* bool; receive IP6 dst addr w/dgram */ #define IPV6_RETOPTS 8 /* ip6_opts; set/get IP6 options */ #endif #define IPV6_SOCKOPT_RESERVED1 3 /* reserved for future use */ #define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */ #define IPV6_MULTICAST_IF 9 /* u_int; set/get IP6 multicast i/f */ #define IPV6_MULTICAST_HOPS 10 /* int; set/get IP6 multicast hops */ #define IPV6_MULTICAST_LOOP 11 /* u_int; set/get IP6 multicast loopback */ #define IPV6_JOIN_GROUP 12 /* ipv6_mreq; join a group membership */ #define IPV6_LEAVE_GROUP 13 /* ipv6_mreq; leave a group membership */ #define IPV6_PORTRANGE 14 /* int; range to choose for unspec port */ #define ICMP6_FILTER 18 /* icmp6_filter; icmp6 filter */ /* RFC2292 options */ #ifdef _KERNEL #define IPV6_2292PKTINFO 19 /* bool; send/recv if, src/dst addr */ #define IPV6_2292HOPLIMIT 20 /* bool; hop limit */ #define IPV6_2292NEXTHOP 21 /* bool; next hop addr */ #define IPV6_2292HOPOPTS 22 /* bool; hop-by-hop option */ #define IPV6_2292DSTOPTS 23 /* bool; destinaion option */ #define IPV6_2292RTHDR 24 /* bool; routing header */ #define IPV6_2292PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */ #endif #define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */ #define IPV6_V6ONLY 27 /* bool; make AF_INET6 sockets v6 only */ #ifndef _KERNEL #define IPV6_BINDV6ONLY IPV6_V6ONLY #endif #if 1 /* IPSEC */ #define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */ #endif /* IPSEC */ /* 29; unused; was IPV6_FAITH */ #if 1 /* IPV6FIREWALL */ #define IPV6_FW_ADD 30 /* add a firewall rule to chain */ #define IPV6_FW_DEL 31 /* delete a firewall rule from chain */ #define IPV6_FW_FLUSH 32 /* flush firewall rule chain */ #define IPV6_FW_ZERO 33 /* clear single/all firewall counter(s) */ #define IPV6_FW_GET 34 /* get entire firewall rule chain */ #endif /* new socket options introduced in RFC3542 */ #define IPV6_RTHDRDSTOPTS 35 /* ip6_dest; send dst option before rthdr */ #define IPV6_RECVPKTINFO 36 /* bool; recv if, dst addr */ #define IPV6_RECVHOPLIMIT 37 /* bool; recv hop limit */ #define IPV6_RECVRTHDR 38 /* bool; recv routing header */ #define IPV6_RECVHOPOPTS 39 /* bool; recv hop-by-hop option */ #define IPV6_RECVDSTOPTS 40 /* bool; recv dst option after rthdr */ #ifdef _KERNEL #define IPV6_RECVRTHDRDSTOPTS 41 /* bool; recv dst option before rthdr */ #endif #define IPV6_USE_MIN_MTU 42 /* bool; send packets at the minimum MTU */ #define IPV6_RECVPATHMTU 43 /* bool; notify an according MTU */ #define IPV6_PATHMTU 44 /* mtuinfo; get the current path MTU (sopt), 4 bytes int; MTU notification (cmsg) */ #if 0 /*obsoleted during 2292bis -> 3542*/ #define IPV6_REACHCONF 45 /* no data; ND reachability confirm (cmsg only/not in of RFC3542) */ #endif /* more new socket options introduced in RFC3542 */ #define IPV6_PKTINFO 46 /* in6_pktinfo; send if, src addr */ #define IPV6_HOPLIMIT 47 /* int; send hop limit */ #define IPV6_NEXTHOP 48 /* sockaddr; next hop addr */ #define IPV6_HOPOPTS 49 /* ip6_hbh; send hop-by-hop option */ #define IPV6_DSTOPTS 50 /* ip6_dest; send dst option befor rthdr */ #define IPV6_RTHDR 51 /* ip6_rthdr; send routing header */ #if 0 #define IPV6_PKTOPTIONS 52 /* buf/cmsghdr; set/get IPv6 options */ /* obsoleted by RFC3542 */ #endif #define IPV6_RECVTCLASS 57 /* bool; recv traffic class values */ #define IPV6_AUTOFLOWLABEL 59 /* bool; attach flowlabel automagically */ #define IPV6_TCLASS 61 /* int; send traffic class value */ #define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */ #define IPV6_PREFER_TEMPADDR 63 /* int; prefer temporary addresses as * the source address. */ #define IPV6_BINDANY 64 /* bool: allow bind to any address */ #define IPV6_BINDMULTI 65 /* bool; allow multibind to same addr/port */ #define IPV6_RSS_LISTEN_BUCKET 66 /* int; set RSS listen bucket */ #define IPV6_FLOWID 67 /* int; flowid of given socket */ #define IPV6_FLOWTYPE 68 /* int; flowtype of given socket */ #define IPV6_RSSBUCKETID 69 /* int; RSS bucket ID of given socket */ #define IPV6_RECVFLOWID 70 /* bool; receive IP6 flowid/flowtype w/ datagram */ #define IPV6_RECVRSSBUCKETID 71 /* bool; receive IP6 RSS bucket id w/ datagram */ /* * The following option is private; do not use it from user applications. * It is deliberately defined to the same value as IP_MSFILTER. */ #define IPV6_MSFILTER 74 /* struct __msfilterreq; * set/get multicast source filter list. */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ #define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */ #define IPV6_RTHDR_STRICT 1 /* this hop must be a neighbor. XXX old spec */ #define IPV6_RTHDR_TYPE_0 0 /* IPv6 routing header type 0 */ /* * Defaults and limits for options */ #define IPV6_DEFAULT_MULTICAST_HOPS 1 /* normally limit m'casts to 1 hop */ #define IPV6_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ /* * The im6o_membership vector for each socket is now dynamically allocated at * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized * according to a power-of-two increment. */ #define IPV6_MIN_MEMBERSHIPS 31 #define IPV6_MAX_MEMBERSHIPS 4095 /* * Default resource limits for IPv6 multicast source filtering. * These may be modified by sysctl. */ #define IPV6_MAX_GROUP_SRC_FILTER 512 /* sources per group */ #define IPV6_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */ /* * Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP. */ struct ipv6_mreq { struct in6_addr ipv6mr_multiaddr; unsigned int ipv6mr_interface; }; /* * IPV6_PKTINFO: Packet information(RFC2292 sec 5) */ struct in6_pktinfo { struct in6_addr ipi6_addr; /* src/dst IPv6 address */ unsigned int ipi6_ifindex; /* send/recv interface index */ }; /* * Control structure for IPV6_RECVPATHMTU socket option. */ struct ip6_mtuinfo { struct sockaddr_in6 ip6m_addr; /* or sockaddr_storage? */ uint32_t ip6m_mtu; }; /* * Argument for IPV6_PORTRANGE: * - which range to search when port is unspecified at bind() or connect() */ #define IPV6_PORTRANGE_DEFAULT 0 /* default range */ #define IPV6_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */ #define IPV6_PORTRANGE_LOW 2 /* "low" - vouchsafe security */ #if __BSD_VISIBLE /* * Definitions for inet6 sysctl operations. * * Third level is protocol number. * Fourth level is desired variable within that protocol. */ #define IPV6PROTO_MAXID (IPPROTO_PIM + 1) /* don't list to IPV6PROTO_MAX */ /* * Names for IP sysctl objects */ #define IPV6CTL_FORWARDING 1 /* act as router */ #define IPV6CTL_SENDREDIRECTS 2 /* may send redirects when forwarding*/ #define IPV6CTL_DEFHLIM 3 /* default Hop-Limit */ #ifdef notyet #define IPV6CTL_DEFMTU 4 /* default MTU */ #endif #define IPV6CTL_FORWSRCRT 5 /* forward source-routed dgrams */ #define IPV6CTL_STATS 6 /* stats */ #define IPV6CTL_MRTSTATS 7 /* multicast forwarding stats */ #define IPV6CTL_MRTPROTO 8 /* multicast routing protocol */ #define IPV6CTL_MAXFRAGPACKETS 9 /* max packets reassembly queue */ #define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */ #define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */ #define IPV6CTL_ACCEPT_RTADV 12 /* 13; unused; was: IPV6CTL_KEEPFAITH */ #define IPV6CTL_LOG_INTERVAL 14 #define IPV6CTL_HDRNESTLIMIT 15 #define IPV6CTL_DAD_COUNT 16 #define IPV6CTL_AUTO_FLOWLABEL 17 #define IPV6CTL_DEFMCASTHLIM 18 #define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */ #define IPV6CTL_KAME_VERSION 20 #define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */ #define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */ #if 0 /* obsolete */ #define IPV6CTL_MAPPED_ADDR 23 #endif #define IPV6CTL_V6ONLY 24 /* IPV6CTL_RTEXPIRE 25 deprecated */ /* IPV6CTL_RTMINEXPIRE 26 deprecated */ /* IPV6CTL_RTMAXCACHE 27 deprecated */ #define IPV6CTL_USETEMPADDR 32 /* use temporary addresses (RFC3041) */ #define IPV6CTL_TEMPPLTIME 33 /* preferred lifetime for tmpaddrs */ #define IPV6CTL_TEMPVLTIME 34 /* valid lifetime for tmpaddrs */ #define IPV6CTL_AUTO_LINKLOCAL 35 /* automatic link-local addr assign */ #define IPV6CTL_RIP6STATS 36 /* raw_ip6 stats */ #define IPV6CTL_PREFER_TEMPADDR 37 /* prefer temporary addr as src */ #define IPV6CTL_ADDRCTLPOLICY 38 /* get/set address selection policy */ #define IPV6CTL_USE_DEFAULTZONE 39 /* use default scope zone */ #define IPV6CTL_MAXFRAGS 41 /* max fragments */ #if 0 #define IPV6CTL_IFQ 42 /* ip6intrq node */ #define IPV6CTL_ISATAPRTR 43 /* isatap router */ #endif #define IPV6CTL_MCAST_PMTU 44 /* enable pMTU discovery for multicast? */ /* New entries should be added here from current IPV6CTL_MAXID value. */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ #define IPV6CTL_STEALTH 45 #define ICMPV6CTL_ND6_ONLINKNSRFC4861 47 #define IPV6CTL_NO_RADR 48 /* No defroute from RA */ #define IPV6CTL_NORBIT_RAIF 49 /* Disable R-bit in NA on RA * receiving IF. */ #define IPV6CTL_RFC6204W3 50 /* Accept defroute even when forwarding enabled */ #define IPV6CTL_MAXID 51 #endif /* __BSD_VISIBLE */ /* * Since both netinet/ and netinet6/ call into netipsec/ and netpfil/, * the protocol specific mbuf flags are shared between them. */ #define M_FASTFWD_OURS M_PROTO1 /* changed dst to local */ #define M_IP6_NEXTHOP M_PROTO2 /* explicit ip nexthop */ #define M_IP_NEXTHOP M_PROTO2 /* explicit ip nexthop */ #define M_SKIP_FIREWALL M_PROTO3 /* skip firewall processing */ #define M_AUTHIPHDR M_PROTO4 #define M_DECRYPTED M_PROTO5 #define M_LOOP M_PROTO6 #define M_AUTHIPDGM M_PROTO7 #define M_RTALERT_MLD M_PROTO8 #ifdef _KERNEL struct cmsghdr; struct ip6_hdr; int in6_cksum_pseudo(struct ip6_hdr *, uint32_t, uint8_t, uint16_t); int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t); int in6_cksum_partial(struct mbuf *, u_int8_t, u_int32_t, u_int32_t, u_int32_t); int in6_localaddr(struct in6_addr *); int in6_localip(struct in6_addr *); int in6_ifhasaddr(struct ifnet *, struct in6_addr *); int in6_addrscope(const struct in6_addr *); char *ip6_sprintf(char *, const struct in6_addr *); struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *); extern void in6_if_up(struct ifnet *); struct sockaddr; extern u_char ip6_protox[]; void in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6); void in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6); void in6_sin6_2_sin_in_sock(struct sockaddr *nam); void in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam); extern void addrsel_policy_init(void); #define satosin6(sa) ((struct sockaddr_in6 *)(sa)) #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) #define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) #endif /* _KERNEL */ #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif #if __BSD_VISIBLE __BEGIN_DECLS struct cmsghdr; extern int inet6_option_space(int); extern int inet6_option_init(void *, struct cmsghdr **, int); extern int inet6_option_append(struct cmsghdr *, const uint8_t *, int, int); extern uint8_t *inet6_option_alloc(struct cmsghdr *, int, int, int); extern int inet6_option_next(const struct cmsghdr *, uint8_t **); extern int inet6_option_find(const struct cmsghdr *, uint8_t **, int); extern size_t inet6_rthdr_space(int, int); extern struct cmsghdr *inet6_rthdr_init(void *, int); extern int inet6_rthdr_add(struct cmsghdr *, const struct in6_addr *, unsigned int); extern int inet6_rthdr_lasthop(struct cmsghdr *, unsigned int); #if 0 /* not implemented yet */ extern int inet6_rthdr_reverse(const struct cmsghdr *, struct cmsghdr *); #endif extern int inet6_rthdr_segments(const struct cmsghdr *); extern struct in6_addr *inet6_rthdr_getaddr(struct cmsghdr *, int); extern int inet6_rthdr_getflags(const struct cmsghdr *, int); extern int inet6_opt_init(void *, socklen_t); extern int inet6_opt_append(void *, socklen_t, int, uint8_t, socklen_t, uint8_t, void **); extern int inet6_opt_finish(void *, socklen_t, int); extern int inet6_opt_set_val(void *, int, void *, socklen_t); extern int inet6_opt_next(void *, socklen_t, int, uint8_t *, socklen_t *, void **); extern int inet6_opt_find(void *, socklen_t, int, uint8_t, socklen_t *, void **); extern int inet6_opt_get_val(void *, int, void *, socklen_t); extern socklen_t inet6_rth_space(int, int); extern void *inet6_rth_init(void *, socklen_t, int, int); extern int inet6_rth_add(void *, const struct in6_addr *); extern int inet6_rth_reverse(const void *, void *); extern int inet6_rth_segments(const void *); extern struct in6_addr *inet6_rth_getaddr(const void *, int); __END_DECLS #endif /* __BSD_VISIBLE */ #endif /* !_NETINET6_IN6_H_ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)nlist.h 8.2 (Berkeley) 1/21/94 * * $FreeBSD$ */ #ifndef _NLIST_H_ #define _NLIST_H_ #include #include __BEGIN_DECLS int nlist(const char *, struct nlist *); __END_DECLS #endif /* !_NLIST_H_ */ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)runetype.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _RUNETYPE_H_ #define _RUNETYPE_H_ #include #include #define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */ #define _CRMASK (~(_CACHED_RUNES - 1)) /* * The lower 8 bits of runetype[] contain the digit value of the rune. */ typedef struct { __rune_t __min; /* First rune of the range */ __rune_t __max; /* Last rune (inclusive) of the range */ __rune_t __map; /* What first maps to in maps */ unsigned long *__types; /* Array of types in range */ } _RuneEntry; typedef struct { int __nranges; /* Number of ranges stored */ _RuneEntry *__ranges; /* Pointer to the ranges */ } _RuneRange; typedef struct { char __magic[8]; /* Magic saying what version we are */ char __encoding[32]; /* ASCII name of this encoding */ __rune_t (*__sgetrune)(const char *, __size_t, char const **); int (*__sputrune)(__rune_t, char *, __size_t, char **); __rune_t __invalid_rune; unsigned long __runetype[_CACHED_RUNES]; __rune_t __maplower[_CACHED_RUNES]; __rune_t __mapupper[_CACHED_RUNES]; /* * The following are to deal with Runes larger than _CACHED_RUNES - 1. * Their data is actually contiguous with this structure so as to make * it easier to read/write from/to disk. */ _RuneRange __runetype_ext; _RuneRange __maplower_ext; _RuneRange __mapupper_ext; void *__variable; /* Data which depends on the encoding */ int __variable_len; /* how long that data is */ } _RuneLocale; #define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */ __BEGIN_DECLS extern const _RuneLocale _DefaultRuneLocale; extern const _RuneLocale *_CurrentRuneLocale; #if defined(__NO_TLS) || defined(__RUNETYPE_INTERNAL) extern const _RuneLocale *__getCurrentRuneLocale(void); #else extern _Thread_local const _RuneLocale *_ThreadRuneLocale; static __inline const _RuneLocale *__getCurrentRuneLocale(void) { if (_ThreadRuneLocale) return _ThreadRuneLocale; if (_CurrentRuneLocale) return _CurrentRuneLocale; return &_DefaultRuneLocale; } #endif /* __NO_TLS || __RUNETYPE_INTERNAL */ #define _CurrentRuneLocale (__getCurrentRuneLocale()) __END_DECLS #endif /* !_RUNETYPE_H_ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)setjmp.h 8.2 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _SETJMP_H_ #define _SETJMP_H_ #include /* The size of the jmp_buf is machine dependent: */ #include __BEGIN_DECLS #if __XSI_VISIBLE >= 600 void _longjmp(jmp_buf, int) __dead2; int _setjmp(jmp_buf) __returns_twice; #endif void longjmp(jmp_buf, int) __dead2; #if __BSD_VISIBLE void longjmperror(void); #endif int setjmp(jmp_buf) __returns_twice; #if __POSIX_VISIBLE || __XSI_VISIBLE void siglongjmp(sigjmp_buf, int) __dead2; int sigsetjmp(sigjmp_buf, int) __returns_twice; #endif __END_DECLS #endif /* !_SETJMP_H_ */ /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /* * Copyright (c) 2000 Jeroen Ruigrok van der Werven * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef __bool_true_false_are_defined #define __bool_true_false_are_defined 1 #ifndef __cplusplus #define false 0 #define true 1 #define bool _Bool #if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER) typedef int _Bool; #endif #endif /* !__cplusplus */ #endif /* __bool_true_false_are_defined */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stddef.h 8.1 (Berkeley) 6/2/93 * * $FreeBSD$ */ #ifndef _STDDEF_H_ #define _STDDEF_H_ #include #include #include #ifndef _PTRDIFF_T_DECLARED typedef __ptrdiff_t ptrdiff_t; #define _PTRDIFF_T_DECLARED #endif #if __BSD_VISIBLE #ifndef _RUNE_T_DECLARED typedef __rune_t rune_t; #define _RUNE_T_DECLARED #endif #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef ___wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif #define offsetof(type, member) __offsetof(type, member) #endif /* _STDDEF_H_ */ /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2022 Toomas Soome */ #ifndef _STDINT_H #define _STDINT_H #include #endif /* _STDINT_H */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stdio.h 8.5 (Berkeley) 4/29/95 * $FreeBSD$ */ #ifndef _STDIO_H_ #define _STDIO_H_ #include #include #include typedef __off_t fpos_t; #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #if __POSIX_VISIBLE >= 200809 #ifndef _OFF_T_DECLARED #define _OFF_T_DECLARED typedef __off_t off_t; #endif #ifndef _SSIZE_T_DECLARED #define _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #endif #endif #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #ifndef _VA_LIST_DECLARED typedef __va_list va_list; #define _VA_LIST_DECLARED #endif #endif #define _FSTDIO /* Define for new stdio with functions. */ /* * NB: to fit things in six character monocase externals, the stdio * code uses the prefix `__s' for stdio objects, typically followed * by a three-character attempt at a mnemonic. */ /* stdio buffers */ struct __sbuf { unsigned char *_base; int _size; }; /* * stdio state variables. * * The following always hold: * * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), * _lbfsize is -_bf._size, else _lbfsize is 0 * if _flags&__SRD, _w is 0 * if _flags&__SWR, _r is 0 * * This ensures that the getc and putc macros (or inline functions) never * try to write or read from a file that is in `read' or `write' mode. * (Moreover, they can, and do, automatically switch from read mode to * write mode, and back, on "r+" and "w+" files.) * * _lbfsize is used only to make the inline line-buffered output stream * code as compact as possible. * * _ub, _up, and _ur are used when ungetc() pushes back more characters * than fit in the current _bf, or when ungetc() pushes back a character * that does not match the previous one in _bf. When this happens, * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. * * Certain members of __sFILE are accessed directly via macros or * inline functions. To preserve ABI compat, these members must not * be disturbed. These members are marked below with (*). */ struct __sFILE { unsigned char *_p; /* (*) current position in (some) buffer */ int _r; /* (*) read space left for getc() */ int _w; /* (*) write space left for putc() */ short _flags; /* (*) flags, below; this FILE is free if 0 */ short _file; /* (*) fileno, if Unix descriptor, else -1 */ struct __sbuf _bf; /* (*) the buffer (at least 1 byte, if !NULL) */ int _lbfsize; /* (*) 0 or -_bf._size, for inline putc */ /* operations */ void *_cookie; /* (*) cookie passed to io functions */ int (*_close)(void *); int (*_read)(void *, char *, int); fpos_t (*_seek)(void *, fpos_t, int); int (*_write)(void *, const char *, int); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ unsigned char *_up; /* saved _p when _p is doing ungetc data */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ unsigned char _nbuf[1]; /* guarantee a getc() buffer */ /* separate buffer for fgetln() when line crosses buffer boundary */ struct __sbuf _lb; /* buffer for fgetln() */ /* Unix stdio files get aligned to block boundaries on fseek() */ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset */ struct pthread_mutex *_fl_mutex; /* used for MT-safety */ struct pthread *_fl_owner; /* current owner */ int _fl_count; /* recursive lock count */ int _orientation; /* orientation for fwide() */ __mbstate_t _mbstate; /* multibyte conversion state */ int _flags2; /* additional flags */ }; #ifndef _STDFILE_DECLARED #define _STDFILE_DECLARED typedef struct __sFILE FILE; #endif #ifndef _STDSTREAM_DECLARED __BEGIN_DECLS extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; __END_DECLS #define _STDSTREAM_DECLARED #endif #define __SLBF 0x0001 /* line buffered */ #define __SNBF 0x0002 /* unbuffered */ #define __SRD 0x0004 /* OK to read */ #define __SWR 0x0008 /* OK to write */ /* RD and WR are never simultaneously asserted */ #define __SRW 0x0010 /* open for reading & writing */ #define __SEOF 0x0020 /* found EOF */ #define __SERR 0x0040 /* found error */ #define __SMBF 0x0080 /* _bf._base is from malloc */ #define __SAPP 0x0100 /* fdopen()ed in append mode */ #define __SSTR 0x0200 /* this is an sprintf/snprintf string */ #define __SOPT 0x0400 /* do fseek() optimization */ #define __SNPT 0x0800 /* do not do fseek() optimization */ #define __SOFF 0x1000 /* set iff _offset is in fact correct */ #define __SMOD 0x2000 /* true => fgetln modified _p text */ #define __SALC 0x4000 /* allocate string space dynamically */ #define __SIGN 0x8000 /* ignore this file in _fwalk */ #define __S2OAP 0x0001 /* O_APPEND mode is set */ /* * The following three definitions are for ANSI C, which took them * from System V, which brilliantly took internal interface macros and * made them official arguments to setvbuf(), without renaming them. * Hence, these ugly _IOxxx names are *supposed* to appear in user code. * * Although numbered as their counterparts above, the implementation * does not rely on this. */ #define _IOFBF 0 /* setvbuf should set fully buffered */ #define _IOLBF 1 /* setvbuf should set line buffered */ #define _IONBF 2 /* setvbuf should set unbuffered */ #define BUFSIZ 1024 /* size of buffer used by setbuf */ #define EOF (-1) /* * FOPEN_MAX is a minimum maximum, and is the number of streams that * stdio can provide without attempting to allocate further resources * (which could fail). Do not use this for anything. */ /* must be == _POSIX_STREAM_MAX */ #ifndef FOPEN_MAX #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ #endif #define FILENAME_MAX 1024 /* must be <= PATH_MAX */ /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ #if __XSI_VISIBLE #define P_tmpdir "/tmp/" #endif #define L_tmpnam 1024 /* XXX must be == PATH_MAX */ #define TMP_MAX 308915776 #ifndef SEEK_SET #define SEEK_SET 0 /* set file offset to offset */ #endif #ifndef SEEK_CUR #define SEEK_CUR 1 /* set file offset to current plus offset */ #endif #ifndef SEEK_END #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif #define stdin __stdinp #define stdout __stdoutp #define stderr __stderrp __BEGIN_DECLS #ifdef _XLOCALE_H_ #include #endif /* * Functions defined in ANSI C standard. */ void clearerr(FILE *); int fclose(FILE *); int feof(FILE *); int ferror(FILE *); int fflush(FILE *); int fgetc(FILE *); int fgetpos(FILE * __restrict, fpos_t * __restrict); char *fgets(char * __restrict, int, FILE * __restrict); FILE *fopen(const char * __restrict, const char * __restrict); int fprintf(FILE * __restrict, const char * __restrict, ...); int fputc(int, FILE *); int fputs(const char * __restrict, FILE * __restrict); size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); FILE *freopen(const char * __restrict, const char * __restrict, FILE * __restrict); int fscanf(FILE * __restrict, const char * __restrict, ...); int fseek(FILE *, long, int); int fsetpos(FILE *, const fpos_t *); long ftell(FILE *); size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict); int getc(FILE *); int getchar(void); char *gets(char *); void perror(const char *); int printf(const char * __restrict, ...); int putc(int, FILE *); int putchar(int); int puts(const char *); int remove(const char *); int rename(const char *, const char *); void rewind(FILE *); int scanf(const char * __restrict, ...); void setbuf(FILE * __restrict, char * __restrict); int setvbuf(FILE * __restrict, char * __restrict, int, size_t); int sprintf(char * __restrict, const char * __restrict, ...); int sscanf(const char * __restrict, const char * __restrict, ...); FILE *tmpfile(void); char *tmpnam(char *); int ungetc(int, FILE *); int vfprintf(FILE * __restrict, const char * __restrict, __va_list); int vprintf(const char * __restrict, __va_list); int vsprintf(char * __restrict, const char * __restrict, __va_list); #if __ISO_C_VISIBLE >= 1999 int snprintf(char * __restrict, size_t, const char * __restrict, ...) __printflike(3, 4); int vfscanf(FILE * __restrict, const char * __restrict, __va_list) __scanflike(2, 0); int vscanf(const char * __restrict, __va_list) __scanflike(1, 0); int vsnprintf(char * __restrict, size_t, const char * __restrict, __va_list) __printflike(3, 0); int vsscanf(const char * __restrict, const char * __restrict, __va_list) __scanflike(2, 0); #endif /* * Functions defined in all versions of POSIX 1003.1. */ #if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 199506) #define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, legacy */ #endif #if __POSIX_VISIBLE #define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */ char *ctermid(char *); FILE *fdopen(int, const char *); int fileno(FILE *); #endif /* __POSIX_VISIBLE */ #if __POSIX_VISIBLE >= 199209 int pclose(FILE *); FILE *popen(const char *, const char *); #endif #if __POSIX_VISIBLE >= 199506 int ftrylockfile(FILE *); void flockfile(FILE *); void funlockfile(FILE *); /* * These are normally used through macros as defined below, but POSIX * requires functions as well. */ int getc_unlocked(FILE *); int getchar_unlocked(void); int putc_unlocked(int, FILE *); int putchar_unlocked(int); #endif #if __BSD_VISIBLE void clearerr_unlocked(FILE *); int feof_unlocked(FILE *); int ferror_unlocked(FILE *); int fileno_unlocked(FILE *); #endif #if __POSIX_VISIBLE >= 200112 int fseeko(FILE *, __off_t, int); __off_t ftello(FILE *); #endif #if __BSD_VISIBLE || __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600 int getw(FILE *); int putw(int, FILE *); #endif /* BSD or X/Open before issue 6 */ #if __XSI_VISIBLE char *tempnam(const char *, const char *); #endif #if __POSIX_VISIBLE >= 200809 FILE *fmemopen(void * __restrict, size_t, const char * __restrict); ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * __restrict); FILE *open_memstream(char **, size_t *); int renameat(int, const char *, int, const char *); int vdprintf(int, const char * __restrict, __va_list); /* * Every programmer and his dog wrote functions called getline() and dprintf() * before POSIX.1-2008 came along and decided to usurp the names, so we * don't prototype them by default unless one of the following is true: * a) the app has requested them specifically by defining _WITH_GETLINE or * _WITH_DPRINTF, respectively * b) the app has requested a POSIX.1-2008 environment via _POSIX_C_SOURCE * c) the app defines a GNUism such as _BSD_SOURCE or _GNU_SOURCE */ #ifndef _WITH_GETLINE #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) #define _WITH_GETLINE #elif defined(_POSIX_C_SOURCE) #if _POSIX_C_SOURCE >= 200809 #define _WITH_GETLINE #endif #endif #endif #ifdef _WITH_GETLINE ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict); #endif #ifndef _WITH_DPRINTF #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) #define _WITH_DPRINTF #elif defined(_POSIX_C_SOURCE) #if _POSIX_C_SOURCE >= 200809 #define _WITH_DPRINTF #endif #endif #endif #ifdef _WITH_DPRINTF int (dprintf)(int, const char * __restrict, ...); #endif #endif /* __POSIX_VISIBLE >= 200809 */ /* * Routines that are purely local. */ #if __BSD_VISIBLE int asprintf(char **, const char *, ...) __printflike(2, 3); char *ctermid_r(char *); void fcloseall(void); int fdclose(FILE *, int *); char *fgetln(FILE *, size_t *); const char *fmtcheck(const char *, const char *) __format_arg(2); int fpurge(FILE *); void setbuffer(FILE *, char *, int); int setlinebuf(FILE *); int vasprintf(char **, const char *, __va_list) __printflike(2, 0); /* * The system error table contains messages for the first sys_nerr * positive errno values. Use strerror() or strerror_r() from * instead. */ extern const int sys_nerr; extern const char * const sys_errlist[]; /* * Stdio function-access interface. */ FILE *funopen(const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), int (*)(void *)); #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) /* * Portability hacks. See . */ #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate(int, __off_t); #endif #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED __off_t lseek(int, __off_t, int); #endif #ifndef _MMAP_DECLARED #define _MMAP_DECLARED void *mmap(void *, size_t, int, int, int, __off_t); #endif #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate(const char *, __off_t); #endif #endif /* __BSD_VISIBLE */ /* * Functions internal to the implementation. */ int __srget(FILE *); int __swbuf(int, FILE *); /* * The __sfoo macros are here so that we can * define function versions in the C library. */ #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) #if defined(__GNUC__) && defined(__STDC__) static __inline int __sputc(int _c, FILE *_p) { if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) return (*_p->_p++ = _c); else return (__swbuf(_c, _p)); } #else /* * This has been tuned to generate reasonable code on the vax using pcc. */ #define __sputc(c, p) \ (--(p)->_w < 0 ? \ (p)->_w >= (p)->_lbfsize ? \ (*(p)->_p = (c)), *(p)->_p != '\n' ? \ (int)*(p)->_p++ : \ __swbuf('\n', p) : \ __swbuf((int)(c), p) : \ (*(p)->_p = (c), (int)*(p)->_p++)) #endif extern int __isthreaded; #ifndef __cplusplus #define __sfeof(p) (((p)->_flags & __SEOF) != 0) #define __sferror(p) (((p)->_flags & __SERR) != 0) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) #define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p)) #define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p)) #define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p)) #if __POSIX_VISIBLE #define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p)) #endif #define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) #define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp)) #define getchar() getc(stdin) #define putchar(x) putc(x, stdout) #if __BSD_VISIBLE /* * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12 * B.8.2.7 for the rationale behind the *_unlocked() macros. */ #define feof_unlocked(p) __sfeof(p) #define ferror_unlocked(p) __sferror(p) #define clearerr_unlocked(p) __sclearerr(p) #define fileno_unlocked(p) __sfileno(p) #endif #if __POSIX_VISIBLE >= 199506 #define getc_unlocked(fp) __sgetc(fp) #define putc_unlocked(x, fp) __sputc(x, fp) #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) #endif #endif /* __cplusplus */ __END_DECLS #endif /* !_STDIO_H_ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 * $FreeBSD$ */ #ifndef _STDLIB_H_ #define _STDLIB_H_ #include #include #include #if __BSD_VISIBLE #ifndef _RUNE_T_DECLARED typedef __rune_t rune_t; #define _RUNE_T_DECLARED #endif #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef ___wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif typedef struct { int quot; /* quotient */ int rem; /* remainder */ } div_t; typedef struct { long quot; long rem; } ldiv_t; #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 #define RAND_MAX 0x7ffffffd __BEGIN_DECLS #ifdef _XLOCALE_H_ #include #endif extern int __mb_cur_max; extern int ___mb_cur_max(void); #define MB_CUR_MAX (___mb_cur_max()) _Noreturn void abort(void); int abs(int) __pure2; int atexit(void (*)(void)); double atof(const char *); int atoi(const char *); long atol(const char *); void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); void *calloc(size_t, size_t) __malloc_like __result_use_check __alloc_size2(1, 2); div_t div(int, int) __pure2; _Noreturn void exit(int); void free(void *); char *getenv(const char *); long labs(long) __pure2; ldiv_t ldiv(long, long) __pure2; void *malloc(size_t) __malloc_like __result_use_check __alloc_size(1); int mblen(const char *, size_t); size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); void *realloc(void *, size_t) __result_use_check __alloc_size(2); void srand(unsigned); double strtod(const char * __restrict, char ** __restrict); float strtof(const char * __restrict, char ** __restrict); long strtol(const char * __restrict, char ** __restrict, int); long double strtold(const char * __restrict, char ** __restrict); unsigned long strtoul(const char * __restrict, char ** __restrict, int); int system(const char *); int wctomb(char *, wchar_t); size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); /* * Functions added in C99 which we make conditionally available in the * BSD^C89 namespace if the compiler supports `long long'. * The #if test is more complicated than it ought to be because * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long' * is not supported in the compilation environment (which therefore means * that it can't really be ISO C99). * * (The only other extension made by C99 in thie header is _Exit().) */ #if __ISO_C_VISIBLE >= 1999 #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ typedef struct { long long quot; long long rem; } lldiv_t; /* LONGLONG */ long long atoll(const char *); /* LONGLONG */ long long llabs(long long) __pure2; /* LONGLONG */ lldiv_t lldiv(long long, long long) __pure2; /* LONGLONG */ long long strtoll(const char * __restrict, char ** __restrict, int); /* LONGLONG */ unsigned long long strtoull(const char * __restrict, char ** __restrict, int); #endif /* __LONG_LONG_SUPPORTED */ _Noreturn void _Exit(int); #endif /* __ISO_C_VISIBLE >= 1999 */ /* * If we're in a mode greater than C99, expose C11 functions. */ #if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L void * aligned_alloc(size_t, size_t) __malloc_like __alloc_align(1) __alloc_size(2); int at_quick_exit(void (*)(void)); _Noreturn void quick_exit(int); #endif /* __ISO_C_VISIBLE >= 2011 */ /* * Extensions made by POSIX relative to C. */ #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE char *realpath(const char * __restrict, char * __restrict); #endif #if __POSIX_VISIBLE >= 199506 int rand_r(unsigned *); /* (TSF) */ #endif #if __POSIX_VISIBLE >= 200112 int posix_memalign(void **, size_t, size_t); /* (ADV) */ int setenv(const char *, const char *, int); int unsetenv(const char *); #endif #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE int getsubopt(char **, char *const *, char **); #ifndef _MKDTEMP_DECLARED char *mkdtemp(char *); #define _MKDTEMP_DECLARED #endif #ifndef _MKSTEMP_DECLARED int mkstemp(char *); #define _MKSTEMP_DECLARED #endif #endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ /* * The only changes to the XSI namespace in revision 6 were the deletion * of the ttyslot() and valloc() functions, which FreeBSD never declared * in this header. For revision 7, ecvt(), fcvt(), and gcvt(), which * FreeBSD also does not have, and mktemp(), are to be deleted. */ #if __XSI_VISIBLE /* XXX XSI requires pollution from here. We'd rather not. */ long a64l(const char *); double drand48(void); /* char *ecvt(double, int, int * __restrict, int * __restrict); */ double erand48(unsigned short[3]); /* char *fcvt(double, int, int * __restrict, int * __restrict); */ /* char *gcvt(double, int, int * __restrict, int * __restrict); */ int grantpt(int); char *initstate(unsigned long /* XSI requires u_int */, char *, long); long jrand48(unsigned short[3]); char *l64a(long); void lcong48(unsigned short[7]); long lrand48(void); #if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600) char *mktemp(char *); #define _MKTEMP_DECLARED #endif long mrand48(void); long nrand48(unsigned short[3]); int posix_openpt(int); char *ptsname(int); int putenv(char *); long random(void); unsigned short *seed48(unsigned short[3]); #ifndef _SETKEY_DECLARED int setkey(const char *); #define _SETKEY_DECLARED #endif char *setstate(/* const */ char *); void srand48(long); void srandom(unsigned long); int unlockpt(int); #endif /* __XSI_VISIBLE */ #if __BSD_VISIBLE extern const char *malloc_conf; extern void (*malloc_message)(void *, const char *); /* * The alloca() function can't be implemented in C, and on some * platforms it can't be implemented at all as a callable function. * The GNU C compiler provides a built-in alloca() which we can use; * in all other cases, provide a prototype, mainly to pacify various * incarnations of lint. On platforms where alloca() is not in libc, * programs which use it will fail to link when compiled with non-GNU * compilers. */ #if __GNUC__ >= 2 || defined(__INTEL_COMPILER) #undef alloca /* some GNU bits try to get cute and define this on their own */ #define alloca(sz) __builtin_alloca(sz) #elif defined(lint) void *alloca(size_t); #endif void abort2(const char *, int, void **) __dead2; __uint32_t arc4random(void); void arc4random_addrandom(unsigned char *, int); void arc4random_buf(void *, size_t); void arc4random_stir(void); __uint32_t arc4random_uniform(__uint32_t); #ifdef __BLOCKS__ int atexit_b(void (^)(void)); void *bsearch_b(const void *, const void *, size_t, size_t, int (^)(const void *, const void *)); #endif char *getbsize(int *, long *); /* getcap(3) functions */ char *cgetcap(char *, const char *, int); int cgetclose(void); int cgetent(char **, char **, const char *); int cgetfirst(char **, char **); int cgetmatch(const char *, const char *); int cgetnext(char **, char **); int cgetnum(char *, const char *, long *); int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); int daemon(int, int); char *devname(__dev_t, __mode_t); char *devname_r(__dev_t, __mode_t, char *, int); char *fdevname(int); char *fdevname_r(int, char *, int); int getloadavg(double [], int); const char * getprogname(void); int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); #ifdef __BLOCKS__ int heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *)); void qsort_b(void *, size_t, size_t, int (^)(const void *, const void *)); #endif int l64a_r(long, char *, int); int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); #ifdef __BLOCKS__ int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *)); #endif int mkostemp(char *, int); int mkostemps(char *, int, int); void qsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *)); int radixsort(const unsigned char **, int, const unsigned char *, unsigned); void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size2(2, 3); void *reallocf(void *, size_t) __alloc_size(2); int rpmatch(const char *); void setprogname(const char *); int sradixsort(const unsigned char **, int, const unsigned char *, unsigned); void sranddev(void); void srandomdev(void); long long strtonum(const char *, long long, long long, const char **); /* Deprecated interfaces, to be removed in FreeBSD 6.0. */ __int64_t strtoq(const char *, char **, int); __uint64_t strtouq(const char *, char **, int); extern char *suboptarg; /* getsubopt(3) external variable */ #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_STDLIB_H_ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)string.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _STRING_H_ #define _STRING_H_ #include #include #include /* * Prototype functions which were historically defined in , but * are required by POSIX to be prototyped in . */ #if __BSD_VISIBLE #include #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif __BEGIN_DECLS #if __XSI_VISIBLE >= 600 void *memccpy(void * __restrict, const void * __restrict, int, size_t); #endif void *memchr(const void *, int, size_t) __pure; #if __BSD_VISIBLE void *memrchr(const void *, int, size_t) __pure; #endif int memcmp(const void *, const void *, size_t) __pure; void *memcpy(void * __restrict, const void * __restrict, size_t); #if __BSD_VISIBLE void *memmem(const void *, size_t, const void *, size_t) __pure; #endif void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); #if __POSIX_VISIBLE >= 200809 char *stpcpy(char * __restrict, const char * __restrict); char *stpncpy(char * __restrict, const char * __restrict, size_t); #endif #if __BSD_VISIBLE char *strcasestr(const char *, const char *) __pure; #endif char *strcat(char * __restrict, const char * __restrict); char *strchr(const char *, int) __pure; #if __BSD_VISIBLE char *strchrnul(const char*, int) __pure; #endif int strcmp(const char *, const char *) __pure; int strcoll(const char *, const char *); char *strcpy(char * __restrict, const char * __restrict); size_t strcspn(const char *, const char *) __pure; #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE char *strdup(const char *) __malloc_like; #endif char *strerror(int); #if __POSIX_VISIBLE >= 200112 int strerror_r(int, char *, size_t); #endif #if __BSD_VISIBLE size_t strlcat(char * __restrict, const char * __restrict, size_t); size_t strlcpy(char * __restrict, const char * __restrict, size_t); #endif size_t strlen(const char *) __pure; #if __BSD_VISIBLE void strmode(int, char *); #endif char *strncat(char * __restrict, const char * __restrict, size_t); int strncmp(const char *, const char *, size_t) __pure; char *strncpy(char * __restrict, const char * __restrict, size_t); #if __POSIX_VISIBLE >= 200809 char *strndup(const char *, size_t) __malloc_like; size_t strnlen(const char *, size_t) __pure; #endif #if __BSD_VISIBLE char *strnstr(const char *, const char *, size_t) __pure; #endif char *strpbrk(const char *, const char *) __pure; char *strrchr(const char *, int) __pure; #if __BSD_VISIBLE char *strsep(char **, const char *); #endif #if __POSIX_VISIBLE >= 200809 char *strsignal(int); #endif size_t strspn(const char *, const char *) __pure; char *strstr(const char *, const char *) __pure; char *strtok(char * __restrict, const char * __restrict); #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500 char *strtok_r(char *, const char *, char **); #endif size_t strxfrm(char * __restrict, const char * __restrict, size_t); #if __BSD_VISIBLE #ifndef _SWAB_DECLARED #define _SWAB_DECLARED #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif /* _SIZE_T_DECLARED */ void swab(const void * __restrict, void * __restrict, ssize_t); #endif /* _SWAB_DECLARED */ #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #include #endif __END_DECLS #endif /* _STRING_H_ */ /*- * Copyright (c) 2002 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _STRINGS_H_ #define _STRINGS_H_ #include #include #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif __BEGIN_DECLS #if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */ void bcopy(const void *, void *, size_t); /* LEGACY */ void bzero(void *, size_t); /* LEGACY */ #endif #if __BSD_VISIBLE void explicit_bzero(void *, size_t); #endif #if __XSI_VISIBLE int ffs(int) __pure2; #endif #if __BSD_VISIBLE int ffsl(long) __pure2; int ffsll(long long) __pure2; int fls(int) __pure2; int flsl(long) __pure2; int flsll(long long) __pure2; #endif #if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 char *index(const char *, int) __pure; /* LEGACY */ char *rindex(const char *, int) __pure; /* LEGACY */ #endif int strcasecmp(const char *, const char *) __pure; int strncasecmp(const char *, const char *, size_t) __pure; #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #include #endif __END_DECLS #endif /* _STRINGS_H_ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)time.h 8.3 (Berkeley) 1/21/94 */ /* * $FreeBSD$ */ #ifndef _TIME_H_ #define _TIME_H_ #include #include #include #if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE /* * Frequency of the clock ticks reported by times(). Deprecated - use * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.) */ #define CLK_TCK 128 #endif /* Frequency of the clock ticks reported by clock(). */ #define CLOCKS_PER_SEC 128 #ifndef _CLOCK_T_DECLARED typedef __clock_t clock_t; #define _CLOCK_T_DECLARED #endif #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #if __POSIX_VISIBLE >= 199309 /* * New in POSIX 1003.1b-1993. */ #ifndef _CLOCKID_T_DECLARED typedef __clockid_t clockid_t; #define _CLOCKID_T_DECLARED #endif #ifndef _TIMER_T_DECLARED typedef __timer_t timer_t; #define _TIMER_T_DECLARED #endif #include #endif /* __POSIX_VISIBLE >= 199309 */ #if __POSIX_VISIBLE >= 200112 #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif #endif /* These macros are also in sys/time.h. */ #if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 #define CLOCK_REALTIME 0 #ifdef __BSD_VISIBLE #define CLOCK_VIRTUAL 1 #define CLOCK_PROF 2 #endif #define CLOCK_MONOTONIC 4 #define CLOCK_UPTIME 5 /* FreeBSD-specific. */ #define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */ #define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */ #define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */ #define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */ #define CLOCK_SECOND 13 /* FreeBSD-specific. */ #define CLOCK_THREAD_CPUTIME_ID 14 #define CLOCK_PROCESS_CPUTIME_ID 15 #endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */ #if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 #if __BSD_VISIBLE #define TIMER_RELTIME 0x0 /* relative timer */ #endif #define TIMER_ABSTIME 0x1 /* absolute timer */ #endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */ struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from UTC in seconds */ char *tm_zone; /* timezone abbreviation */ }; #if __POSIX_VISIBLE extern char *tzname[]; #endif __BEGIN_DECLS char *asctime(const struct tm *); clock_t clock(void); char *ctime(const time_t *); double difftime(time_t, time_t); /* XXX missing: getdate() */ struct tm *gmtime(const time_t *); struct tm *localtime(const time_t *); time_t mktime(struct tm *); size_t strftime(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict); time_t time(time_t *); #if __POSIX_VISIBLE >= 200112 struct sigevent; int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict); int timer_delete(timer_t); int timer_gettime(timer_t, struct itimerspec *); int timer_getoverrun(timer_t); int timer_settime(timer_t, int, const struct itimerspec *__restrict, struct itimerspec *__restrict); #endif #if __POSIX_VISIBLE void tzset(void); #endif #if __POSIX_VISIBLE >= 199309 int clock_getres(clockid_t, struct timespec *); int clock_gettime(clockid_t, struct timespec *); int clock_settime(clockid_t, const struct timespec *); /* XXX missing: clock_nanosleep() */ int nanosleep(const struct timespec *, struct timespec *); #endif /* __POSIX_VISIBLE >= 199309 */ #if __POSIX_VISIBLE >= 200112 int clock_getcpuclockid(pid_t, clockid_t *); #endif #if __POSIX_VISIBLE >= 199506 char *asctime_r(const struct tm *, char *); char *ctime_r(const time_t *, char *); struct tm *gmtime_r(const time_t *, struct tm *); struct tm *localtime_r(const time_t *, struct tm *); #endif #if __XSI_VISIBLE char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict); #endif #if __BSD_VISIBLE char *timezone(int, int); /* XXX XSI conflict */ void tzsetwall(void); time_t timelocal(struct tm * const); time_t timegm(struct tm * const); #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #include #endif __END_DECLS #endif /* !_TIME_H_ */ /*- * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Marshall * Kirk McKusick and Network Associates Laboratories, the Security * Research Division of Network Associates, Inc. under DARPA/SPAWAR * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS * research program * * 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. * * 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. * * Copyright (c) 1982, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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 names of the authors 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. * * @(#)dinode.h 8.3 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _UFS_UFS_DINODE_H_ #define _UFS_UFS_DINODE_H_ /* * The root inode is the root of the filesystem. Inode 0 can't be used for * normal purposes and historically bad blocks were linked to inode 1, thus * the root inode is 2. (Inode 1 is no longer used for this purpose, however * numerous dump tapes make this assumption, so we are stuck with it). */ #define ROOTINO ((ino_t)2) /* * The Whiteout inode# is a dummy non-zero inode number which will * never be allocated to a real file. It is used as a place holder * in the directory entry which has been tagged as a DT_WHT entry. * See the comments about ROOTINO above. */ #define WINO ((ino_t)1) /* * The size of physical and logical block numbers and time fields in UFS. */ typedef int32_t ufs1_daddr_t; typedef int64_t ufs2_daddr_t; typedef int64_t ufs_lbn_t; typedef int64_t ufs_time_t; /* File permissions. */ #define IEXEC 0000100 /* Executable. */ #define IWRITE 0000200 /* Writeable. */ #define IREAD 0000400 /* Readable. */ #define ISVTX 0001000 /* Sticky bit. */ #define ISGID 0002000 /* Set-gid. */ #define ISUID 0004000 /* Set-uid. */ /* File types. */ #define IFMT 0170000 /* Mask of file type. */ #define IFIFO 0010000 /* Named pipe (fifo). */ #define IFCHR 0020000 /* Character device. */ #define IFDIR 0040000 /* Directory file. */ #define IFBLK 0060000 /* Block device. */ #define IFREG 0100000 /* Regular file. */ #define IFLNK 0120000 /* Symbolic link. */ #define IFSOCK 0140000 /* UNIX domain socket. */ #define IFWHT 0160000 /* Whiteout. */ /* * A dinode contains all the meta-data associated with a UFS2 file. * This structure defines the on-disk format of a dinode. Since * this structure describes an on-disk structure, all its fields * are defined by types with precise widths. */ #define NXADDR 2 /* External addresses in inode. */ #define NDADDR 12 /* Direct addresses in inode. */ #define NIADDR 3 /* Indirect addresses in inode. */ struct ufs2_dinode { u_int16_t di_mode; /* 0: IFMT, permissions; see below. */ int16_t di_nlink; /* 2: File link count. */ u_int32_t di_uid; /* 4: File owner. */ u_int32_t di_gid; /* 8: File group. */ u_int32_t di_blksize; /* 12: Inode blocksize. */ u_int64_t di_size; /* 16: File byte count. */ u_int64_t di_blocks; /* 24: Blocks actually held. */ ufs_time_t di_atime; /* 32: Last access time. */ ufs_time_t di_mtime; /* 40: Last modified time. */ ufs_time_t di_ctime; /* 48: Last inode change time. */ ufs_time_t di_birthtime; /* 56: Inode creation time. */ int32_t di_mtimensec; /* 64: Last modified time. */ int32_t di_atimensec; /* 68: Last access time. */ int32_t di_ctimensec; /* 72: Last inode change time. */ int32_t di_birthnsec; /* 76: Inode creation time. */ u_int32_t di_gen; /* 80: Generation number. */ u_int32_t di_kernflags; /* 84: Kernel flags. */ u_int32_t di_flags; /* 88: Status flags (chflags). */ u_int32_t di_extsize; /* 92: External attributes size. */ ufs2_daddr_t di_extb[NXADDR];/* 96: External attributes block. */ ufs2_daddr_t di_db[NDADDR]; /* 112: Direct disk blocks. */ ufs2_daddr_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */ u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */ uint32_t di_freelink; /* 240: SUJ: Next unlinked inode. */ uint32_t di_spare[3]; /* 244: Reserved; currently unused */ }; /* * The di_db fields may be overlaid with other information for * file types that do not have associated disk storage. Block * and character devices overlay the first data block with their * dev_t value. Short symbolic links place their path in the * di_db area. */ #define di_rdev di_db[0] /* * A UFS1 dinode contains all the meta-data associated with a UFS1 file. * This structure defines the on-disk format of a UFS1 dinode. Since * this structure describes an on-disk structure, all its fields * are defined by types with precise widths. */ struct ufs1_dinode { u_int16_t di_mode; /* 0: IFMT, permissions; see below. */ int16_t di_nlink; /* 2: File link count. */ u_int16_t di_suid; /* 4: File owner. */ u_int16_t di_sgid; /* 6: File group. */ u_int64_t di_size; /* 8: File byte count. */ int32_t di_atime; /* 16: Last access time. */ int32_t di_atimensec; /* 20: Last access time. */ int32_t di_mtime; /* 24: Last modified time. */ int32_t di_mtimensec; /* 28: Last modified time. */ int32_t di_ctime; /* 32: Last inode change time. */ int32_t di_ctimensec; /* 36: Last inode change time. */ ufs1_daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */ ufs1_daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */ u_int32_t di_flags; /* 100: Status flags (chflags). */ u_int32_t di_blocks; /* 104: Blocks actually held. */ u_int32_t di_gen; /* 108: Generation number. */ u_int32_t di_shadow; /* 112: shadow inode */ u_int32_t di_uid; /* 116: long EFT version of uid */ u_int32_t di_gid; /* 120: long EFT version of gid */ u_int32_t di_oeftflag; /* 124: extended attr directory ino, 0 = none */ }; #endif /* _UFS_UFS_DINODE_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)dir.h 8.2 (Berkeley) 1/21/94 */ #ifndef _UFS_UFS_DIR_H_ #define _UFS_UFS_DIR_H_ /* * Theoretically, directories can be more than 2Gb in length, however, in * practice this seems unlikely. So, we define the type doff_t as a 32-bit * quantity to keep down the cost of doing lookup on a 32-bit machine. */ #define doff_t int32_t #define MAXDIRSIZE (0x7fffffff) /* * A directory consists of some number of blocks of DIRBLKSIZ * bytes, where DIRBLKSIZ is chosen such that it can be transferred * to disk in a single atomic operation (e.g. 512 bytes on most machines). * * Each DIRBLKSIZ byte block contains some number of directory entry * structures, which are of variable length. Each directory entry has * a struct direct at the front of it, containing its inode number, * the length of the entry, and the length of the name contained in * the entry. These are followed by the name padded to a 4 byte boundary * with null bytes. All names are guaranteed null terminated. * The maximum length of a name in a directory is UFS_MAXNAMLEN. * * The macro DIRSIZ(fmt, dp) gives the amount of space required to represent * a directory entry. Free space in a directory is represented by * entries which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes * in a directory block are claimed by the directory entries. This * usually results in the last entry in a directory having a large * dp->d_reclen. When entries are deleted from a directory, the * space is returned to the previous entry in the same directory * block by increasing its dp->d_reclen. If the first entry of * a directory block is free, then its dp->d_ino is set to 0. * Entries other than the first in a directory do not normally have * dp->d_ino set to 0. */ #define DIRBLKSIZ DEV_BSIZE #define UFS_MAXNAMLEN 255 struct direct { u_int32_t d_ino; /* inode number of entry */ u_int16_t d_reclen; /* length of this record */ u_int16_t d_namlen; /* length of string in d_name */ char d_name[UFS_MAXNAMLEN + 1]; /* name with length <= UFS_MAXNAMLEN */ }; /* * File types */ #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 #define DT_DIR 4 #define DT_BLK 6 #define DT_REG 8 #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 /* * Convert between stat structure types and directory types. */ #define IFTODT(mode) (((mode) & 0170000) >> 12) #define DTTOIF(dirtype) ((dirtype) << 12) /* * The DIRSIZ macro gives the minimum record length which will hold * the directory entry. This requires the amount of space in struct direct * without the d_name field, plus enough space for the name with a terminating * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. * * */ #define DIRECTSIZ(namlen) \ ((__offsetof(struct direct, d_name) + \ ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3) #if (BYTE_ORDER == LITTLE_ENDIAN) #define DIRSIZ(oldfmt, dp) \ ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen)) #else #define DIRSIZ(oldfmt, dp) \ DIRECTSIZ((dp)->d_namlen) #endif #define OLDDIRFMT 1 #define NEWDIRFMT 0 /* * Template for manipulating directories. Should use struct direct's, * but the name field is UFS_MAXNAMLEN - 1, and this just won't do. */ struct dirtemplate { u_int32_t dot_ino; int16_t dot_reclen; u_int8_t dot_type; u_int8_t dot_namlen; char dot_name[4]; /* must be multiple of 4 */ u_int32_t dotdot_ino; int16_t dotdot_reclen; u_int8_t dotdot_type; u_int8_t dotdot_namlen; char dotdot_name[4]; /* ditto */ }; /* * This is the old format of directories, sanz type element. */ struct odirtemplate { u_int32_t dot_ino; int16_t dot_reclen; u_int16_t dot_namlen; char dot_name[4]; /* must be multiple of 4 */ u_int32_t dotdot_ino; int16_t dotdot_reclen; u_int16_t dotdot_namlen; char dotdot_name[4]; /* ditto */ }; #endif /* !_DIR_H_ */ /*- * Copyright (c) 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)unistd.h 8.12 (Berkeley) 4/27/95 * $FreeBSD$ */ #ifndef _UNISTD_H_ #define _UNISTD_H_ #include #include /* XXX adds too much pollution. */ #include #include #include #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED #endif #ifndef _OFF_T_DECLARED typedef __off_t off_t; #define _OFF_T_DECLARED #endif #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif #ifndef _UID_T_DECLARED typedef __uid_t uid_t; #define _UID_T_DECLARED #endif #ifndef _USECONDS_T_DECLARED typedef __useconds_t useconds_t; #define _USECONDS_T_DECLARED #endif #define STDIN_FILENO 0 /* standard input file descriptor */ #define STDOUT_FILENO 1 /* standard output file descriptor */ #define STDERR_FILENO 2 /* standard error file descriptor */ #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112 #define F_ULOCK 0 /* unlock locked section */ #define F_LOCK 1 /* lock a section for exclusive use */ #define F_TLOCK 2 /* test and lock a section for exclusive use */ #define F_TEST 3 /* test a section for locks by other procs */ #endif /* * POSIX options and option groups we unconditionally do or don't * implement. This list includes those options which are exclusively * implemented (or not) in user mode. Please keep this list in * alphabetical order. * * Anything which is defined as zero below **must** have an * implementation for the corresponding sysconf() which is able to * determine conclusively whether or not the feature is supported. * Anything which is defined as other than -1 below **must** have * complete headers, types, and function declarations as specified by * the POSIX standard; however, if the relevant sysconf() function * returns -1, the functions may be stubbed out. */ #define _POSIX_BARRIERS 200112L #define _POSIX_CPUTIME 200112L #define _POSIX_READER_WRITER_LOCKS 200112L #define _POSIX_REGEXP 1 #define _POSIX_SHELL 1 #define _POSIX_SPAWN 200112L #define _POSIX_SPIN_LOCKS 200112L #define _POSIX_THREAD_ATTR_STACKADDR 200112L #define _POSIX_THREAD_ATTR_STACKSIZE 200112L #define _POSIX_THREAD_CPUTIME 200112L #define _POSIX_THREAD_PRIO_INHERIT 200112L #define _POSIX_THREAD_PRIO_PROTECT 200112L #define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L #define _POSIX_THREAD_PROCESS_SHARED -1 #define _POSIX_THREAD_SAFE_FUNCTIONS -1 #define _POSIX_THREAD_SPORADIC_SERVER -1 #define _POSIX_THREADS 200112L #define _POSIX_TRACE -1 #define _POSIX_TRACE_EVENT_FILTER -1 #define _POSIX_TRACE_INHERIT -1 #define _POSIX_TRACE_LOG -1 #define _POSIX2_C_BIND 200112L /* mandatory */ #define _POSIX2_C_DEV -1 /* need c99 utility */ #define _POSIX2_CHAR_TERM 1 #define _POSIX2_FORT_DEV -1 /* need fort77 utility */ #define _POSIX2_FORT_RUN 200112L #define _POSIX2_LOCALEDEF -1 #define _POSIX2_PBS -1 #define _POSIX2_PBS_ACCOUNTING -1 #define _POSIX2_PBS_CHECKPOINT -1 #define _POSIX2_PBS_LOCATE -1 #define _POSIX2_PBS_MESSAGE -1 #define _POSIX2_PBS_TRACK -1 #define _POSIX2_SW_DEV -1 /* XXX ??? */ #define _POSIX2_UPE 200112L #define _V6_ILP32_OFF32 -1 #define _V6_ILP32_OFFBIG 0 #define _V6_LP64_OFF64 0 #define _V6_LPBIG_OFFBIG -1 #if __XSI_VISIBLE #define _XOPEN_CRYPT -1 /* XXX ??? */ #define _XOPEN_ENH_I18N -1 /* mandatory in XSI */ #define _XOPEN_LEGACY -1 #define _XOPEN_REALTIME -1 #define _XOPEN_REALTIME_THREADS -1 #define _XOPEN_UNIX -1 #endif /* Define the POSIX.2 version we target for compliance. */ #define _POSIX2_VERSION 199212L /* * POSIX-style system configuration variable accessors (for the * sysconf function). The kernel does not directly implement the * sysconf() interface; rather, a C library stub translates references * to sysconf() into calls to sysctl() using a giant switch statement. * Those that are marked `user' are implemented entirely in the C * library and never query the kernel. pathconf() is implemented * directly by the kernel so those are not defined here. */ #define _SC_ARG_MAX 1 #define _SC_CHILD_MAX 2 #define _SC_CLK_TCK 3 #define _SC_NGROUPS_MAX 4 #define _SC_OPEN_MAX 5 #define _SC_JOB_CONTROL 6 #define _SC_SAVED_IDS 7 #define _SC_VERSION 8 #define _SC_BC_BASE_MAX 9 /* user */ #define _SC_BC_DIM_MAX 10 /* user */ #define _SC_BC_SCALE_MAX 11 /* user */ #define _SC_BC_STRING_MAX 12 /* user */ #define _SC_COLL_WEIGHTS_MAX 13 /* user */ #define _SC_EXPR_NEST_MAX 14 /* user */ #define _SC_LINE_MAX 15 /* user */ #define _SC_RE_DUP_MAX 16 /* user */ #define _SC_2_VERSION 17 /* user */ #define _SC_2_C_BIND 18 /* user */ #define _SC_2_C_DEV 19 /* user */ #define _SC_2_CHAR_TERM 20 /* user */ #define _SC_2_FORT_DEV 21 /* user */ #define _SC_2_FORT_RUN 22 /* user */ #define _SC_2_LOCALEDEF 23 /* user */ #define _SC_2_SW_DEV 24 /* user */ #define _SC_2_UPE 25 /* user */ #define _SC_STREAM_MAX 26 /* user */ #define _SC_TZNAME_MAX 27 /* user */ #if __POSIX_VISIBLE >= 199309 #define _SC_ASYNCHRONOUS_IO 28 #define _SC_MAPPED_FILES 29 #define _SC_MEMLOCK 30 #define _SC_MEMLOCK_RANGE 31 #define _SC_MEMORY_PROTECTION 32 #define _SC_MESSAGE_PASSING 33 #define _SC_PRIORITIZED_IO 34 #define _SC_PRIORITY_SCHEDULING 35 #define _SC_REALTIME_SIGNALS 36 #define _SC_SEMAPHORES 37 #define _SC_FSYNC 38 #define _SC_SHARED_MEMORY_OBJECTS 39 #define _SC_SYNCHRONIZED_IO 40 #define _SC_TIMERS 41 #define _SC_AIO_LISTIO_MAX 42 #define _SC_AIO_MAX 43 #define _SC_AIO_PRIO_DELTA_MAX 44 #define _SC_DELAYTIMER_MAX 45 #define _SC_MQ_OPEN_MAX 46 #define _SC_PAGESIZE 47 #define _SC_RTSIG_MAX 48 #define _SC_SEM_NSEMS_MAX 49 #define _SC_SEM_VALUE_MAX 50 #define _SC_SIGQUEUE_MAX 51 #define _SC_TIMER_MAX 52 #endif #if __POSIX_VISIBLE >= 200112 #define _SC_2_PBS 59 /* user */ #define _SC_2_PBS_ACCOUNTING 60 /* user */ #define _SC_2_PBS_CHECKPOINT 61 /* user */ #define _SC_2_PBS_LOCATE 62 /* user */ #define _SC_2_PBS_MESSAGE 63 /* user */ #define _SC_2_PBS_TRACK 64 /* user */ #define _SC_ADVISORY_INFO 65 #define _SC_BARRIERS 66 /* user */ #define _SC_CLOCK_SELECTION 67 #define _SC_CPUTIME 68 #define _SC_FILE_LOCKING 69 #define _SC_GETGR_R_SIZE_MAX 70 /* user */ #define _SC_GETPW_R_SIZE_MAX 71 /* user */ #define _SC_HOST_NAME_MAX 72 #define _SC_LOGIN_NAME_MAX 73 #define _SC_MONOTONIC_CLOCK 74 #define _SC_MQ_PRIO_MAX 75 #define _SC_READER_WRITER_LOCKS 76 /* user */ #define _SC_REGEXP 77 /* user */ #define _SC_SHELL 78 /* user */ #define _SC_SPAWN 79 /* user */ #define _SC_SPIN_LOCKS 80 /* user */ #define _SC_SPORADIC_SERVER 81 #define _SC_THREAD_ATTR_STACKADDR 82 /* user */ #define _SC_THREAD_ATTR_STACKSIZE 83 /* user */ #define _SC_THREAD_CPUTIME 84 /* user */ #define _SC_THREAD_DESTRUCTOR_ITERATIONS 85 /* user */ #define _SC_THREAD_KEYS_MAX 86 /* user */ #define _SC_THREAD_PRIO_INHERIT 87 /* user */ #define _SC_THREAD_PRIO_PROTECT 88 /* user */ #define _SC_THREAD_PRIORITY_SCHEDULING 89 /* user */ #define _SC_THREAD_PROCESS_SHARED 90 /* user */ #define _SC_THREAD_SAFE_FUNCTIONS 91 /* user */ #define _SC_THREAD_SPORADIC_SERVER 92 /* user */ #define _SC_THREAD_STACK_MIN 93 /* user */ #define _SC_THREAD_THREADS_MAX 94 /* user */ #define _SC_TIMEOUTS 95 /* user */ #define _SC_THREADS 96 /* user */ #define _SC_TRACE 97 /* user */ #define _SC_TRACE_EVENT_FILTER 98 /* user */ #define _SC_TRACE_INHERIT 99 /* user */ #define _SC_TRACE_LOG 100 /* user */ #define _SC_TTY_NAME_MAX 101 /* user */ #define _SC_TYPED_MEMORY_OBJECTS 102 #define _SC_V6_ILP32_OFF32 103 /* user */ #define _SC_V6_ILP32_OFFBIG 104 /* user */ #define _SC_V6_LP64_OFF64 105 /* user */ #define _SC_V6_LPBIG_OFFBIG 106 /* user */ #define _SC_IPV6 118 #define _SC_RAW_SOCKETS 119 #define _SC_SYMLOOP_MAX 120 #endif #if __XSI_VISIBLE #define _SC_ATEXIT_MAX 107 /* user */ #define _SC_IOV_MAX 56 #define _SC_PAGE_SIZE _SC_PAGESIZE #define _SC_XOPEN_CRYPT 108 /* user */ #define _SC_XOPEN_ENH_I18N 109 /* user */ #define _SC_XOPEN_LEGACY 110 /* user */ #define _SC_XOPEN_REALTIME 111 #define _SC_XOPEN_REALTIME_THREADS 112 #define _SC_XOPEN_SHM 113 #define _SC_XOPEN_STREAMS 114 #define _SC_XOPEN_UNIX 115 #define _SC_XOPEN_VERSION 116 #define _SC_XOPEN_XCU_VERSION 117 /* user */ #endif #if __BSD_VISIBLE #define _SC_NPROCESSORS_CONF 57 #define _SC_NPROCESSORS_ONLN 58 #define _SC_CPUSET_SIZE 122 #endif /* Extensions found in Solaris and Linux. */ #define _SC_PHYS_PAGES 121 /* Keys for the confstr(3) function. */ #if __POSIX_VISIBLE >= 199209 #define _CS_PATH 1 /* default value of PATH */ #endif #if __POSIX_VISIBLE >= 200112 #define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 #define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 #define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 #define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 #define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6 #define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7 #define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8 #define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9 #define _CS_POSIX_V6_LP64_OFF64_LIBS 10 #define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11 #define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 #define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 #endif __BEGIN_DECLS /* 1003.1-1990 */ void _exit(int) __dead2; int access(const char *, int); unsigned int alarm(unsigned int); int chdir(const char *); int chown(const char *, uid_t, gid_t); int close(int); void closefrom(int); int dup(int); int dup2(int, int); int execl(const char *, const char *, ...) __null_sentinel; int execle(const char *, const char *, ...); int execlp(const char *, const char *, ...) __null_sentinel; int execv(const char *, char * const *); int execve(const char *, char * const *, char * const *); int execvp(const char *, char * const *); pid_t fork(void); long fpathconf(int, int); char *getcwd(char *, size_t); gid_t getegid(void); uid_t geteuid(void); gid_t getgid(void); int getgroups(int, gid_t []); char *getlogin(void); pid_t getpgrp(void); pid_t getpid(void); pid_t getppid(void); uid_t getuid(void); int isatty(int); int link(const char *, const char *); #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED off_t lseek(int, off_t, int); #endif long pathconf(const char *, int); int pause(void); int pipe(int *); ssize_t read(int, void *, size_t); int rmdir(const char *); int setgid(gid_t); int setpgid(pid_t, pid_t); pid_t setsid(void); int setuid(uid_t); unsigned int sleep(unsigned int); long sysconf(int); pid_t tcgetpgrp(int); int tcsetpgrp(int, pid_t); char *ttyname(int); int ttyname_r(int, char *, size_t); int unlink(const char *); ssize_t write(int, const void *, size_t); /* 1003.2-1992 */ #if __POSIX_VISIBLE >= 199209 || __XSI_VISIBLE size_t confstr(int, char *, size_t); #ifndef _GETOPT_DECLARED #define _GETOPT_DECLARED int getopt(int, char * const [], const char *); extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt; #endif /* _GETOPT_DECLARED */ #endif /* ISO/IEC 9945-1: 1996 */ #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE int fsync(int); /* * ftruncate() was in the POSIX Realtime Extension (it's used for shared * memory), but truncate() was not. */ #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate(int, off_t); #endif #endif #if __POSIX_VISIBLE >= 199506 int getlogin_r(char *, int); #endif /* 1003.1-2001 */ #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE int fchown(int, uid_t, gid_t); ssize_t readlink(const char * __restrict, char * __restrict, size_t); #endif #if __POSIX_VISIBLE >= 200112 int gethostname(char *, size_t); int setegid(gid_t); int seteuid(uid_t); #endif /* 1003.1-2008 */ #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE int getsid(pid_t _pid); int fchdir(int); int getpgid(pid_t _pid); int lchown(const char *, uid_t, gid_t); ssize_t pread(int, void *, size_t, off_t); ssize_t pwrite(int, const void *, size_t, off_t); /* See comment at ftruncate() above. */ #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate(const char *, off_t); #endif #endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ #if __POSIX_VISIBLE >= 200809 int faccessat(int, const char *, int, int); int fchownat(int, const char *, uid_t, gid_t, int); int fexecve(int, char *const [], char *const []); int linkat(int, const char *, int, const char *, int); ssize_t readlinkat(int, const char * __restrict, char * __restrict, size_t); int symlinkat(const char *, int, const char *); int unlinkat(int, const char *, int); #endif /* __POSIX_VISIBLE >= 200809 */ /* * symlink() was originally in POSIX.1a, which was withdrawn after * being overtaken by events (1003.1-2001). It was in XPG4.2, and of * course has been in BSD since 4.2. */ #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 402 int symlink(const char * __restrict, const char * __restrict); #endif /* X/Open System Interfaces */ #if __XSI_VISIBLE char *crypt(const char *, const char *); /* char *ctermid(char *); */ /* XXX ??? */ int encrypt(char *, int); long gethostid(void); int lockf(int, int, off_t); int nice(int); int setregid(gid_t, gid_t); int setreuid(uid_t, uid_t); #ifndef _SWAB_DECLARED #define _SWAB_DECLARED void swab(const void * __restrict, void * __restrict, ssize_t); #endif /* _SWAB_DECLARED */ void sync(void); #endif /* __XSI_VISIBLE */ #if (__XSI_VISIBLE && __XSI_VISIBLE <= 500) || __BSD_VISIBLE int brk(const void *); int chroot(const char *); int getdtablesize(void); int getpagesize(void) __pure2; char *getpass(const char *); void *sbrk(intptr_t); #endif #if (__XSI_VISIBLE && __XSI_VISIBLE <= 600) || __BSD_VISIBLE char *getwd(char *); /* obsoleted by getcwd() */ useconds_t ualarm(useconds_t, useconds_t); int usleep(useconds_t); pid_t vfork(void) __returns_twice; #endif #if __BSD_VISIBLE struct timeval; /* select(2) */ int acct(const char *); int async_daemon(void); int check_utility_compat(const char *); const char * crypt_get_format(void); int crypt_set_format(const char *); int des_cipher(const char *, char *, long, int); int des_setkey(const char *key); int dup3(int, int, int); int eaccess(const char *, int); void endusershell(void); int exect(const char *, char * const *, char * const *); int execvP(const char *, const char *, char * const *); int feature_present(const char *); char *fflagstostr(u_long); int getdomainname(char *, int); int getgrouplist(const char *, gid_t, gid_t *, int *); int getloginclass(char *, size_t); mode_t getmode(const void *, mode_t); int getosreldate(void); int getpeereid(int, uid_t *, gid_t *); int getresgid(gid_t *, gid_t *, gid_t *); int getresuid(uid_t *, uid_t *, uid_t *); char *getusershell(void); int initgroups(const char *, gid_t); int iruserok(unsigned long, int, const char *, const char *); int iruserok_sa(const void *, int, int, const char *, const char *); int issetugid(void); void __FreeBSD_libc_enter_restricted_mode(void); long lpathconf(const char *, int); #ifndef _MKDTEMP_DECLARED char *mkdtemp(char *); #define _MKDTEMP_DECLARED #endif #ifndef _MKNOD_DECLARED int mknod(const char *, mode_t, dev_t); #define _MKNOD_DECLARED #endif #ifndef _MKSTEMP_DECLARED int mkstemp(char *); #define _MKSTEMP_DECLARED #endif int mkstemps(char *, int); #ifndef _MKTEMP_DECLARED char *mktemp(char *); #define _MKTEMP_DECLARED #endif int nfssvc(int, void *); int nlm_syscall(int, int, int, char **); int pipe2(int *, int); int profil(char *, size_t, vm_offset_t, int); int rcmd(char **, int, const char *, const char *, const char *, int *); int rcmd_af(char **, int, const char *, const char *, const char *, int *, int); int rcmdsh(char **, int, const char *, const char *, const char *, const char *); char *re_comp(const char *); int re_exec(const char *); int reboot(int); int revoke(const char *); pid_t rfork(int); pid_t rfork_thread(int, void *, int (*)(void *), void *); int rresvport(int *); int rresvport_af(int *, int); int ruserok(const char *, int, const char *, const char *); #if __BSD_VISIBLE #ifndef _SELECT_DECLARED #define _SELECT_DECLARED int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); #endif #endif int setdomainname(const char *, int); int setgroups(int, const gid_t *); void sethostid(long); int sethostname(const char *, int); #ifndef _SETKEY_DECLARED int setkey(const char *); #define _SETKEY_DECLARED #endif int setlogin(const char *); int setloginclass(const char *); void *setmode(const char *); int setpgrp(pid_t, pid_t); /* obsoleted by setpgid() */ void setproctitle(const char *_fmt, ...) __printf0like(1, 2); int setresgid(gid_t, gid_t, gid_t); int setresuid(uid_t, uid_t, uid_t); int setrgid(gid_t); int setruid(uid_t); void setusershell(void); int strtofflags(char **, u_long *, u_long *); int swapon(const char *); int swapoff(const char *); int syscall(int, ...); off_t __syscall(quad_t, ...); int undelete(const char *); int unwhiteout(const char *); void *valloc(size_t); /* obsoleted by malloc() */ #ifndef _OPTRESET_DECLARED #define _OPTRESET_DECLARED extern int optreset; /* getopt(3) external variable */ #endif #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_UNISTD_H_ */ /*- * Copyright (c) 2002,2005 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _UUID_H_ #define _UUID_H_ #include #include /* * This implementation mostly conforms to the DCE 1.1 specification. * See Also: * uuidgen(1), uuidgen(2), uuid(3) */ /* Status codes returned by the functions. */ #define uuid_s_ok 0 #define uuid_s_bad_version 1 #define uuid_s_invalid_string_uuid 2 #define uuid_s_no_memory 3 __BEGIN_DECLS int32_t uuid_compare(const uuid_t *, const uuid_t *, uint32_t *); void uuid_create(uuid_t *, uint32_t *); void uuid_create_nil(uuid_t *, uint32_t *); int32_t uuid_equal(const uuid_t *, const uuid_t *, uint32_t *); void uuid_from_string(const char *, uuid_t *, uint32_t *); uint16_t uuid_hash(const uuid_t *, uint32_t *); int32_t uuid_is_nil(const uuid_t *, uint32_t *); void uuid_to_string(const uuid_t *, char **, uint32_t *); void uuid_enc_le(void *, const uuid_t *); void uuid_dec_le(const void *, uuid_t *); void uuid_enc_be(void *, const uuid_t *); void uuid_dec_be(const void *, uuid_t *); __END_DECLS #endif /* _UUID_H_ */ /*- * Copyright (c) 2011 The FreeBSD Foundation * All rights reserved. * * This software was developed by David Chisnall under sponsorship from * the FreeBSD Foundation. * * 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. * * 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. * * $FreeBSD$ */ #if (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \ (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) #ifdef _XLOCALE_WCTYPES #define _XLOCALE_WCTYPE_H #else #define _XLOCALE_CTYPE_H #endif #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif #ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED #define _XLOCALE_RUN_FUNCTIONS_DEFINED 1 unsigned long ___runetype_l(__ct_rune_t, locale_t) __pure; __ct_rune_t ___tolower_l(__ct_rune_t, locale_t) __pure; __ct_rune_t ___toupper_l(__ct_rune_t, locale_t) __pure; _RuneLocale *__runes_for_locale(locale_t, int*); #endif #ifndef _XLOCALE_INLINE #if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) /* GNU89 inline has nonstandard semantics. */ #define _XLOCALE_INLINE extern __inline #else /* Hack to work around people who define inline away */ #ifdef inline #define _XLOCALE_INLINE static __inline #else /* Define with C++ / C99 compatible semantics */ #define _XLOCALE_INLINE inline #endif #endif #endif /* _XLOCALE_INLINE */ #ifdef _XLOCALE_WCTYPES _XLOCALE_INLINE int __maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); _XLOCALE_INLINE int __istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); _XLOCALE_INLINE int __maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) { int __limit; _RuneLocale *runes = __runes_for_locale(__loc, &__limit); return ((__c < 0 || __c >= _CACHED_RUNES) ? ___runetype_l(__c, __loc) : runes->__runetype[__c]) & __f; } _XLOCALE_INLINE int __istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) { return (!!__maskrune_l(__c, __f, __loc)); } #define XLOCALE_ISCTYPE(fname, cat) \ _XLOCALE_INLINE int isw##fname##_l(int, locale_t);\ _XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\ { return __istype_l(__c, cat, __l); } #else _XLOCALE_INLINE int __sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); _XLOCALE_INLINE int __sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); _XLOCALE_INLINE int __sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) { int __limit; _RuneLocale *runes = __runes_for_locale(__loc, &__limit); return (__c < 0 || __c >= __limit) ? 0 : runes->__runetype[__c] & __f; } _XLOCALE_INLINE int __sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) { return (!!__sbmaskrune_l(__c, __f, __loc)); } #define XLOCALE_ISCTYPE(__fname, __cat) \ _XLOCALE_INLINE int is##__fname##_l(int, locale_t); \ _XLOCALE_INLINE int is##__fname##_l(int __c, locale_t __l)\ { return __sbistype_l(__c, __cat, __l); } #endif XLOCALE_ISCTYPE(alnum, _CTYPE_A|_CTYPE_D|_CTYPE_N) XLOCALE_ISCTYPE(alpha, _CTYPE_A) XLOCALE_ISCTYPE(blank, _CTYPE_B) XLOCALE_ISCTYPE(cntrl, _CTYPE_C) XLOCALE_ISCTYPE(digit, _CTYPE_D) XLOCALE_ISCTYPE(graph, _CTYPE_G) XLOCALE_ISCTYPE(hexnumber, _CTYPE_X) XLOCALE_ISCTYPE(ideogram, _CTYPE_I) XLOCALE_ISCTYPE(lower, _CTYPE_L) XLOCALE_ISCTYPE(number, _CTYPE_D|_CTYPE_N) XLOCALE_ISCTYPE(phonogram, _CTYPE_Q) XLOCALE_ISCTYPE(print, _CTYPE_R) XLOCALE_ISCTYPE(punct, _CTYPE_P) XLOCALE_ISCTYPE(rune, 0xFFFFFF00L) XLOCALE_ISCTYPE(space, _CTYPE_S) XLOCALE_ISCTYPE(special, _CTYPE_T) XLOCALE_ISCTYPE(upper, _CTYPE_U) XLOCALE_ISCTYPE(xdigit, _CTYPE_X) #undef XLOCALE_ISCTYPE #ifdef _XLOCALE_WCTYPES _XLOCALE_INLINE int towlower_l(int, locale_t); _XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t); _XLOCALE_INLINE int towupper_l(int, locale_t); _XLOCALE_INLINE int towlower_l(int __c, locale_t __l) { int __limit; _RuneLocale *__runes = __runes_for_locale(__l, &__limit); return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) : __runes->__maplower[__c]; } _XLOCALE_INLINE int towupper_l(int __c, locale_t __l) { int __limit; _RuneLocale *__runes = __runes_for_locale(__l, &__limit); return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) : __runes->__mapupper[__c]; } _XLOCALE_INLINE int __wcwidth_l(__ct_rune_t _c, locale_t __l) { unsigned int _x; if (_c == 0) return (0); _x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l); if ((_x & _CTYPE_SWM) != 0) return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); return ((_x & _CTYPE_R) != 0 ? 1 : -1); } int iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l); wctype_t wctype_l(const char *property, locale_t __l); wint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l); wint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l); wctrans_t wctrans_l(const char *__charclass, locale_t __l); #undef _XLOCALE_WCTYPES #else _XLOCALE_INLINE int digittoint_l(int, locale_t); _XLOCALE_INLINE int tolower_l(int, locale_t); _XLOCALE_INLINE int toupper_l(int, locale_t); _XLOCALE_INLINE int digittoint_l(int __c, locale_t __l) { return __sbmaskrune_l((__c), 0xFF, __l); } _XLOCALE_INLINE int tolower_l(int __c, locale_t __l) { int __limit; _RuneLocale *__runes = __runes_for_locale(__l, &__limit); return (__c < 0 || __c >= __limit) ? __c : __runes->__maplower[__c]; } _XLOCALE_INLINE int toupper_l(int __c, locale_t __l) { int __limit; _RuneLocale *__runes = __runes_for_locale(__l, &__limit); return (__c < 0 || __c >= __limit) ? __c : __runes->__mapupper[__c]; } #endif #endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \ (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) */ /*- * Copyright (c) 2011, 2012 The FreeBSD Foundation * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif /* * This file is included from both string.h and xlocale.h. We need to expose * the declarations unconditionally if we are included from xlocale.h, but only * if we are in POSIX2008 mode if included from string.h. */ #ifndef _XLOCALE_STRING1_H #define _XLOCALE_STRING1_H /* * POSIX2008 functions */ int strcoll_l(const char *, const char *, locale_t); size_t strxfrm_l(char *, const char *, size_t, locale_t); #endif /* _XLOCALE_STRING1_H */ /* * xlocale extensions */ #ifdef _XLOCALE_H_ #ifndef _XLOCALE_STRING2_H #define _XLOCALE_STRING2_H char *strcasestr_l(const char *, const char *, locale_t); #endif /* _XLOCALE_STRING2_H */ #endif /* _XLOCALE_H_ */ /*- * Copyright (c) 2011, 2012 The FreeBSD Foundation * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif /* * This file is included from both strings.h and xlocale.h. We need to expose * the declarations unconditionally if we are included from xlocale.h, but only * if we are in POSIX2008 mode if included from string.h. */ #ifndef _XLOCALE_STRINGS1_H #define _XLOCALE_STRINGS1_H /* * POSIX2008 functions */ int strcasecmp_l(const char *, const char *, locale_t); int strncasecmp_l(const char *, const char *, size_t, locale_t); #endif /* _XLOCALE_STRINGS1_H */ /*- * Copyright (c) 2011, 2012 The FreeBSD Foundation * All rights reserved. * * This software was developed by David Chisnall under sponsorship from * the FreeBSD Foundation. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif /* * This file is included from both locale.h and xlocale.h. We need to expose * the declarations unconditionally if we are included from xlocale.h, but only * if we are in POSIX2008 mode if included from locale.h. */ #ifndef _XLOCALE_LOCALE1_H #define _XLOCALE_LOCALE1_H size_t strftime_l(char * __restrict, size_t, const char * __restrict, const struct tm * __restrict, locale_t) __strftimelike(3, 0); #endif /* _XLOCALE_LOCALE1_H */ #ifdef _XLOCALE_H_ #ifndef _XLOCALE_LOCALE2_H #define _XLOCALE_LOCALE2_H char *strptime_l(const char * __restrict, const char * __restrict, struct tm * __restrict, locale_t); #endif /* _XLOCALE_LOCALE2_H */ #endif /* _XLOCALE_H_ */ # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # include $(SRC)/Makefile.master SUBDIRS = softcore $(MACH64) all : TARGET = all install : TARGET = install clean : TARGET = clean clobber : TARGET = clobber all install: $(SUBDIRS) clean clobber: $(SUBDIRS) $(MACH64): softcore .PARALLEL: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # include $(SRC)/boot/Makefile.inc FICLDIR= $(SRC)/common/ficl PNGLITE= $(SRC)/common/pnglite CPPFLAGS += -I. -I.. CPPFLAGS += -I../../sys CPPFLAGS += -I../../include CPPFLAGS += -I../../libsa CPPFLAGS += -I$(FICLDIR) -I../../common -I$(PNGLITE) # For multiboot2.h, must be last, to avoid conflicts CPPFLAGS += -I$(SRC)/uts/common OBJECTS= dictionary.o system.o fileaccess.o float.o double.o prefix.o search.o OBJECTS += softcore.o stack.o tools.o vm.o primitives.o unix.o utility.o OBJECTS += hash.o callback.o word.o loader.o HEADERS= $(FICLDIR)/ficl.h $(FICLDIR)/ficlplatform/unix.h ../ficllocal.h # # disable inner loop variable 'fw' check objs/vm.o : SMOFF += check_check_deref pics/vm.o : SMOFF += check_check_deref MAJOR = 4 MINOR = 1.0 machine: $(RM) machine $(SYMLINK) ../../sys/$(MACHINE)/include machine x86: $(RM) x86 $(SYMLINK) ../../sys/x86/include x86 objs/%.o: ../softcore/%.c $(HEADERS) $(COMPILE.c) -o $@ $< pics/%.o: ../softcore/%.c $(HEADERS) $(COMPILE.c) -o $@ $< objs/%.o: $(FICLDIR)/%.c $(HEADERS) $(COMPILE.c) -o $@ $< pics/%.o: $(FICLDIR)/%.c $(HEADERS) $(COMPILE.c) -o $@ $< objs/%.o: $(FICLDIR)/ficlplatform/%.c $(HEADERS) $(COMPILE.c) -o $@ $< pics/%.o: $(FICLDIR)/ficlplatform/%.c $(HEADERS) $(COMPILE.c) -o $@ $< # # generic cleanup code # clobber clean: FRC $(RM) $(CLEANFILES) machine x86 # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2016 RackTop Systems. # include $(SRC)/Makefile.master MACHINE= $(MACH64) DYNLIB= libficl_pics.a all install: $(DYNLIB) include ../Makefile.com CFLAGS += -m64 $(CFLAGS64) include $(BOOTSRC)/Makefile.lib FRC: /* ** ficllocal.h ** ** Put all local settings here. This file will always ship empty. ** */ /* ** no need for float in loader **/ #define FICL_WANT_FLOAT (0) # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2018 Toomas Soome # include $(SRC)/Makefile.master install all: softcore.c SOFTCORE= $(SRC)/common/ficl/softcore PROG= $(ONBLD_TOOLS)/bin/$(MACH)/makesoftcore # # not needed: file access # FR = softcore.fr ifbrack.fr prefix.fr ficl.fr jhlocal.fr marker.fr FR += freebsd.fr ficllocal.fr oo.fr classes.fr string.fr wordsets.fr SOURCES= $(FR:%=$(SOFTCORE)/%) softcore.c: $(SOURCES) $(PROG) $(SOURCES) clobber clean: $(RM) softcore.c # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2015 Toomas Soome # include $(SRC)/Makefile.master SUBDIRS = $(MACH64) all : TARGET = all clean : TARGET = clean clobber : TARGET = clobber install : TARGET = install .KEEP_STATE: all clean clobber install: $(SUBDIRS) .PARALLEL: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2019 Joyent, Inc. # include $(SRC)/boot/Makefile.inc CPPFLAGS += -I../../include -I$(SASRC) CPPFLAGS += -I../../sys -I. include $(SASRC)/Makefile.inc include $(CRYPTOSRC)/Makefile.inc include $(ZFSSRC)/Makefile.inc CPPFLAGS += -I$(SRC)/uts/common # 64-bit smatch false positive :/ SMOFF += uninitialized # needs work objs/printf.o : SMOFF += 64bit_shift pics/printf.o : SMOFF += 64bit_shift machine: $(RM) machine $(SYMLINK) ../../sys/$(MACHINE)/include machine x86: $(RM) x86 $(SYMLINK) ../../sys/x86/include x86 pics/%.o: %.c $(COMPILE.c) -o $@ $< objs/%.o: %.c $(COMPILE.c) -o $@ $< pics/%.o: $(SASRC)/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(SASRC)/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(SASRC)/string/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(SASRC)/string/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(SASRC)/uuid/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(SASRC)/uuid/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(ZLIB)/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(ZLIB)/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(LZ4)/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(LZ4)/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(SRC)/common/util/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(SRC)/common/util/%.c $(COMPILE.c) -o $@ $< clean: clobber clobber: $(RM) $(CLEANFILES) machine x86 # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2019 Joyent, Inc. # Copyright 2024 MNX Cloud, Inc. # # # Notes: # - We don't use the libc strerror/sys_errlist because the string table is # quite large. # # standalone components and stuff we have modified locally SRCS += $(ZLIB)/gzguts.h $(ZLIB)/zutil.h SRCS += $(SASRC)/__main.c $(SASRC)/abort.c $(SASRC)/assert.c SRCS += $(SASRC)/bcd.c $(SASRC)/environment.c SRCS += $(SASRC)/getopt.c $(SASRC)/random.c SRCS += $(SASRC)/sbrk.c $(SASRC)/twiddle.c SRCS += $(SASRC)/zalloc.c $(SASRC)/zalloc_malloc.c OBJECTS += __main.o abort.o assert.o bcd.o environment.o \ getopt.o gets.o globals.o pager.o panic.o printf.o \ strdup.o strerror.o strtol.o strtoll.o strtoul.o strtoull.o random.o \ sbrk.o twiddle.o zalloc.o zalloc_malloc.o # private (pruned) versions of libc string functions SRCS += $(SASRC)/strcasecmp.c OBJECTS += strcasecmp.o # from libc SRCS += $(SASRC)/ntoh.c OBJECTS += ntoh.o # string functions from libc SRCS += $(SASRC)/string/bcmp.c $(SASRC)/string/bcopy.c SRCS += $(SASRC)/string/bzero.c $(SASRC)/string/ffs.c SRCS += $(SASRC)/string/fls.c $(SASRC)/string/memccpy.c SRCS += $(SASRC)/string/memchr.c $(SASRC)/string/memcmp.c SRCS += $(SASRC)/string/memcpy.c $(SASRC)/string/memmove.c SRCS += $(SASRC)/string/memset.c $(SASRC)/string/strcat.c SRCS += $(SASRC)/string/strchr.c $(SASRC)/string/strcmp.c SRCS += $(SASRC)/string/strcpy.c $(SASRC)/string/stpcpy.c SRCS += $(SASRC)/string/stpncpy.c $(SASRC)/string/strcspn.c SRCS += $(SASRC)/string/strlcat.c $(SASRC)/string/strlcpy.c SRCS += $(SASRC)/string/strlen.c $(SASRC)/string/strncat.c SRCS += $(SASRC)/string/strncmp.c $(SASRC)/string/strncpy.c SRCS += $(SASRC)/string/strpbrk.c $(SASRC)/string/strrchr.c SRCS += $(SASRC)/string/strsep.c $(SASRC)/string/strspn.c SRCS += $(SASRC)/string/strstr.c $(SASRC)/string/strtok.c SRCS += $(SASRC)/string/swab.c $(SASRC)/string/strnlen.c SRCS += $(SASRC)/qdivrem.c OBJECTS += bcmp.o bcopy.o bzero.o ffs.o fls.o \ memccpy.o memchr.o memcmp.o memcpy.o memmove.o memset.o \ qdivrem.o strcat.o strchr.o strcmp.o strcpy.o stpcpy.o stpncpy.o \ strcspn.o strlcat.o strlcpy.o strlen.o strncat.o strncmp.o strncpy.o \ strpbrk.o strrchr.o strsep.o strspn.o strstr.o strtok.o swab.o \ strnlen.o # uuid functions from libc SRCS += $(SASRC)/uuid/uuid_create_nil.c SRCS += $(SASRC)/uuid/uuid_equal.c SRCS += $(SASRC)/uuid/uuid_is_nil.c SRCS += $(SASRC)/uuid_from_string.c SRCS += $(SASRC)/uuid_to_string.c OBJECTS += uuid_create_nil.o uuid_equal.o uuid_from_string.o uuid_is_nil.o \ uuid_to_string.o # too hairy objs/_inflate.o : SMATCH=off pics/_inflate.o : SMATCH=off # decompression functionality from zlib objs/adler32.o : CPPFLAGS += -I$(ZLIB) pics/adler32.o : CPPFLAGS += -I$(ZLIB) objs/crc32.o : CPPFLAGS += -I$(ZLIB) pics/crc32.o : CPPFLAGS += -I$(ZLIB) objs/_infback.o : CPPFLAGS += -I$(ZLIB) pics/_infback.o : CPPFLAGS += -I$(ZLIB) objs/_infback.o: libstand_zutil.h libstand_gzguts.h pics/_infback.o: libstand_zutil.h libstand_gzguts.h objs/_inffast.o : CPPFLAGS += -I$(ZLIB) pics/_inffast.o : CPPFLAGS += -I$(ZLIB) objs/_inffast.o: libstand_zutil.h libstand_gzguts.h pics/_inffast.o: libstand_zutil.h libstand_gzguts.h objs/_inflate.o : CPPFLAGS += -I$(ZLIB) pics/_inflate.o : CPPFLAGS += -I$(ZLIB) objs/_inflate.o: libstand_zutil.h libstand_gzguts.h pics/_inflate.o: libstand_zutil.h libstand_gzguts.h objs/_inftrees.o : CPPFLAGS += -I$(ZLIB) pics/_inftrees.o : CPPFLAGS += -I$(ZLIB) objs/_inftrees.o: libstand_zutil.h libstand_gzguts.h pics/_inftrees.o: libstand_zutil.h libstand_gzguts.h objs/_zutil.o : CPPFLAGS += -I$(ZLIB) pics/_zutil.o : CPPFLAGS += -I$(ZLIB) objs/_zutil.o: libstand_zutil.h libstand_gzguts.h pics/_zutil.o: libstand_zutil.h libstand_gzguts.h objs/gzipfs.o : CPPFLAGS += -I$(ZLIB) pics/gzipfs.o : CPPFLAGS += -I$(ZLIB) objs/gzip.o : CPPFLAGS += -I$(ZLIB) pics/gzip.o : CPPFLAGS += -I$(ZLIB) SRCS += $(ZLIB)/adler32.c $(ZLIB)/crc32.c \ libstand_zutil.h libstand_gzguts.h OBJECTS += adler32.o crc32.o _infback.c: $(ZLIB)/infback.c sed -e "s|zutil\.h|libstand_zutil.h|" \ -e "s|gzguts\.h|libstand_gzguts.h|" \ $^ > $@ _inffast.c: $(ZLIB)/inffast.c sed -e "s|zutil\.h|libstand_zutil.h|" \ -e "s|gzguts\.h|libstand_gzguts.h|" \ $^ > $@ _inflate.c: $(ZLIB)/inflate.c sed -e "s|zutil\.h|libstand_zutil.h|" \ -e "s|gzguts\.h|libstand_gzguts.h|" \ $^ > $@ _inftrees.c: $(ZLIB)/inftrees.c sed -e "s|zutil\.h|libstand_zutil.h|" \ -e "s|gzguts\.h|libstand_gzguts.h|" \ $^ > $@ _zutil.c: $(ZLIB)/zutil.c sed -e "s|zutil\.h|libstand_zutil.h|" \ -e "s|gzguts\.h|libstand_gzguts.h|" \ $^ > $@ SRCS += _infback.c _inffast.c _inflate.c _inftrees.c _zutil.c OBJECTS += _infback.o _inffast.o _inflate.o _inftrees.o _zutil.o CLEANFILES += _infback.c _inffast.c _inflate.c _inftrees.c _zutil.c # depend on stand.h being able to be included multiple times libstand_zutil.h: $(ZLIB)/zutil.h sed -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ $^ > $@ libstand_gzguts.h: $(ZLIB)/gzguts.h sed -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ -e 's||"stand.h"|' \ $^ > $@ CLEANFILES += libstand_zutil.h libstand_gzguts.h # lz4 decompression functionality pics/lz4.o : CPPFLAGS += -I$(LZ4) objs/lz4.o : CPPFLAGS += -I$(LZ4) SRCS += $(LZ4)/lz4.c OBJECTS += lz4.o # io routines SRCS += $(SASRC)/closeall.c $(SASRC)/dev.c \ $(SASRC)/ioctl.c $(SASRC)/nullfs.c \ $(SASRC)/stat.c $(SASRC)/fstat.c $(SASRC)/close.c \ $(SASRC)/lseek.c $(SASRC)/open.c $(SASRC)/read.c \ $(SASRC)/write.c $(SASRC)/readdir.c OBJECTS += closeall.o dev.o ioctl.o nullfs.o stat.o fstat.o close.o lseek.o \ open.o read.o write.o readdir.o # SMBios routines SRCS += smbios.c OBJECTS += smbios.o # Export serial numbers, UUID, and asset tag from loader. # Use little-endian UUID format as defined in SMBIOS 2.6. pics/smbios.o : CPPFLAGS += -DSMBIOS_SERIAL_NUMBERS -DSMBIOS_LITTLE_ENDIAN_UUID objs/smbios.o : CPPFLAGS += -DSMBIOS_SERIAL_NUMBERS -DSMBIOS_LITTLE_ENDIAN_UUID # network routines SRCS += $(SASRC)/arp.c $(SASRC)/ether.c $(SASRC)/ip.c \ $(SASRC)/inet_ntoa.c $(SASRC)/in_cksum.c \ $(SASRC)/net.c $(SASRC)/udp.c $(SASRC)/netif.c \ $(SASRC)/rpc.c OBJECTS += arp.o ether.o ip.o inet_ntoa.o in_cksum.o net.o udp.o netif.o rpc.o # network info services: SRCS += $(SASRC)/bootp.c $(SASRC)/rarp.c \ $(SASRC)/bootparam.c OBJECTS += bootp.o rarp.o bootparam.o # boot filesystems SRCS += $(SASRC)/ufs.c SRCS += $(SASRC)/nfs.c SRCS += $(SASRC)/cd9660.c SRCS += $(SASRC)/tftp.c SRCS += $(SASRC)/gzipfs.c SRCS += $(SASRC)/dosfs.c OBJECTS += ufs.o OBJECTS += nfs.o OBJECTS += cd9660.o OBJECTS += tftp.o OBJECTS += gzipfs.o OBJECTS += dosfs.o # utility SRCS += $(SRC)/common/util/explicit_bzero.c SRCS += $(SRC)/common/util/memmem.c OBJECTS += explicit_bzero.o OBJECTS += memmem.o /* $NetBSD: __main.c,v 1.4 1996/03/14 18:52:03 christos Exp $ */ /* * Copyright (c) 1993 Christopher G. Demetriou * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou. * 4. 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 ``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 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. */ #include __FBSDID("$FreeBSD$"); #include void __main(void); void __main(void) { } /* * Copyright (c) 2018 Netflix, 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. * * 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. */ #include #include void abort(void) { panic("Bootloader aborted by abort"); } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2016 Toomas Soome # Copyright 2016 RackTop Systems. # include $(SRC)/Makefile.master MACHINE= $(MACH64) DYNLIB= libsa_pics.a all install: $(DYNLIB) include ../Makefile.com .KEEP_STATE: ASFLAGS += $(amd64_XARCH) -I$(SRC)/uts/common -I$(ROOT)/usr/include -D_ASM ASFLAGS64 += $(amd64_XARCH) -I$(SRC)/uts/common -I$(ROOT)/usr/include -D_ASM CFLAGS += -m64 $(CFLAGS64) CCASFLAGS += -m64 # _setjmp/_longjmp SRCS += $(SASRC)/amd64/_setjmp.S OBJECTS += _setjmp.o SRCS += sha1-x86_64.S OBJECTS += sha1-x86_64.o SRCS += $(SASRC)/x86/hypervisor.c OBJECTS += hypervisor.o CLEANFILES += sha1-x86_64.S sha1-x86_64.s pics/%.o: $(SASRC)/amd64/%.S $(COMPILE.S) -o $@ $< pics/%.o: $(SASRC)/x86/%.c $(COMPILE.c) -o $@ $< include $(BOOTSRC)/Makefile.lib FRC: /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) .asciz "@(#)_setjmp.s 5.1 (Berkeley) 4/23/90" #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * C library -- _setjmp, _longjmp * * _longjmp(a,v) * will generate a "return(v)" from the last call to * _setjmp(a) * by restoring registers from the environment 'a'. * The previous signal state is NOT restored. */ ENTRY(_setjmp) movq %rdi,%rax movq 0(%rsp),%rdx /* retval */ movq %rdx, 0(%rax) /* 0; retval */ movq %rbx, 8(%rax) /* 1; rbx */ movq %rsp,16(%rax) /* 2; rsp */ movq %rbp,24(%rax) /* 3; rbp */ movq %r12,32(%rax) /* 4; r12 */ movq %r13,40(%rax) /* 5; r13 */ movq %r14,48(%rax) /* 6; r14 */ movq %r15,56(%rax) /* 7; r15 */ fnstcw 64(%rax) /* 8; fpu cw */ stmxcsr 68(%rax) /* and mxcsr */ xorq %rax,%rax ret END(_setjmp) .weak CNAME(_longjmp) ENTRY(_longjmp) movq %rdi,%rdx /* Restore the mxcsr, but leave exception flags intact. */ stmxcsr -4(%rsp) movl 68(%rdx),%eax andl $0xffffffc0,%eax movl -4(%rsp),%edi andl $0x3f,%edi xorl %eax,%edi movl %edi,-4(%rsp) ldmxcsr -4(%rsp) movq %rsi,%rax /* retval */ movq 0(%rdx),%rcx movq 8(%rdx),%rbx movq 16(%rdx),%rsp movq 24(%rdx),%rbp movq 32(%rdx),%r12 movq 40(%rdx),%r13 movq 48(%rdx),%r14 movq 56(%rdx),%r15 fldcw 64(%rdx) testq %rax,%rax jnz 1f incq %rax 1: movq %rcx,0(%rsp) ret END(_longjmp) /* $NetBSD: arp.c,v 1.18 1997/07/07 15:52:49 drochner Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) */ #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" /* Cache stuff */ #define ARP_NUM 8 /* need at most 3 arp entries */ struct arp_list { struct in_addr addr; uchar_t ea[6]; } arp_list[ARP_NUM] = { /* XXX - net order `INADDR_BROADCAST' must be a constant */ { {0xffffffff}, BA } }; int arp_num = 1; /* Local forwards */ static ssize_t arpsend(struct iodesc *, void *, size_t); static ssize_t arprecv(struct iodesc *, void **, void **, time_t, void *); /* Broadcast an ARP packet, asking who has addr on interface d */ uchar_t * arpwhohas(struct iodesc *d, struct in_addr addr) { int i; struct ether_arp *ah; struct arp_list *al; void *pkt; struct { struct ether_header eh; struct { struct ether_arp arp; uchar_t pad[18]; /* 60 - sizeof (...) */ } data; } wbuf; /* Try for cached answer first */ for (i = 0, al = arp_list; i < arp_num; ++i, ++al) if (addr.s_addr == al->addr.s_addr) return (al->ea); /* Don't overflow cache */ if (arp_num > ARP_NUM - 1) { arp_num = 1; /* recycle */ printf("arpwhohas: overflowed arp_list!\n"); } #ifdef ARP_DEBUG if (debug) printf("arpwhohas: send request for %s\n", inet_ntoa(addr)); #endif bzero((char *)&wbuf.data, sizeof (wbuf.data)); ah = &wbuf.data.arp; ah->arp_hrd = htons(ARPHRD_ETHER); ah->arp_pro = htons(ETHERTYPE_IP); ah->arp_hln = sizeof (ah->arp_sha); /* hardware address length */ ah->arp_pln = sizeof (ah->arp_spa); /* protocol address length */ ah->arp_op = htons(ARPOP_REQUEST); MACPY(d->myea, ah->arp_sha); bcopy(&d->myip, ah->arp_spa, sizeof (ah->arp_spa)); /* Leave zeros in arp_tha */ bcopy(&addr, ah->arp_tpa, sizeof (ah->arp_tpa)); /* Store ip address in cache (incomplete entry). */ al->addr = addr; pkt = NULL; ah = NULL; i = sendrecv(d, arpsend, &wbuf.data, sizeof (wbuf.data), arprecv, &pkt, (void **)&ah, NULL); if (i == -1) panic("arp: no response for %s", inet_ntoa(addr)); /* Store ethernet address in cache */ #ifdef ARP_DEBUG if (debug) { struct ether_header *eh; eh = (struct ether_header *)((uintptr_t)pkt + ETHER_ALIGN); printf("arp: response from %s\n", ether_sprintf(eh->ether_shost)); printf("arp: cacheing %s --> %s\n", inet_ntoa(addr), ether_sprintf(ah->arp_sha)); } #endif MACPY(ah->arp_sha, al->ea); ++arp_num; free(pkt); return (al->ea); } static ssize_t arpsend(struct iodesc *d, void *pkt, size_t len) { #ifdef ARP_DEBUG if (debug) printf("arpsend: called\n"); #endif return (sendether(d, pkt, len, bcea, ETHERTYPE_ARP)); } /* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ static ssize_t arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra __unused) { ssize_t n; struct ether_arp *ah; uint16_t etype; /* host order */ void *ptr; #ifdef ARP_DEBUG if (debug) printf("arprecv: "); #endif ptr = NULL; n = readether(d, &ptr, (void **)&ah, tleft, &etype); errno = 0; /* XXX */ if (n == -1 || n < sizeof (struct ether_arp)) { #ifdef ARP_DEBUG if (debug) printf("bad len=%d\n", n); #endif free(ptr); return (-1); } if (etype != ETHERTYPE_ARP) { #ifdef ARP_DEBUG if (debug) printf("not arp type=%d\n", etype); #endif free(ptr); return (-1); } /* Ethernet address now checked in readether() */ if (ah->arp_hrd != htons(ARPHRD_ETHER) || ah->arp_pro != htons(ETHERTYPE_IP) || ah->arp_hln != sizeof (ah->arp_sha) || ah->arp_pln != sizeof (ah->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); #endif free(ptr); return (-1); } if (ah->arp_op == htons(ARPOP_REQUEST)) { #ifdef ARP_DEBUG if (debug) printf("is request\n"); #endif arp_reply(d, ah); free(ptr); return (-1); } if (ah->arp_op != htons(ARPOP_REPLY)) { #ifdef ARP_DEBUG if (debug) printf("not ARP reply\n"); #endif free(ptr); return (-1); } /* Is the reply from the source we want? */ if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof (ah->arp_spa))) { #ifdef ARP_DEBUG if (debug) printf("unwanted address\n"); #endif free(ptr); return (-1); } /* We don't care who the reply was sent to. */ /* We have our answer. */ #ifdef ARP_DEBUG if (debug) printf("got it\n"); #endif *pkt = ptr; *payload = ah; return (n); } /* * Convert an ARP request into a reply and send it. * Notes: Re-uses buffer. Pad to length = 46. */ void arp_reply(struct iodesc *d, void *pkt) { struct ether_arp *arp = pkt; if (arp->arp_hrd != htons(ARPHRD_ETHER) || arp->arp_pro != htons(ETHERTYPE_IP) || arp->arp_hln != sizeof (arp->arp_sha) || arp->arp_pln != sizeof (arp->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("arp_reply: bad hrd/pro/hln/pln\n"); #endif return; } if (arp->arp_op != htons(ARPOP_REQUEST)) { #ifdef ARP_DEBUG if (debug) printf("arp_reply: not request!\n"); #endif return; } /* If we are not the target, ignore the request. */ if (bcmp(arp->arp_tpa, &d->myip, sizeof (arp->arp_tpa))) return; #ifdef ARP_DEBUG if (debug) { printf("arp_reply: to %s\n", ether_sprintf(arp->arp_sha)); } #endif arp->arp_op = htons(ARPOP_REPLY); /* source becomes target */ bcopy(arp->arp_sha, arp->arp_tha, sizeof (arp->arp_tha)); bcopy(arp->arp_spa, arp->arp_tpa, sizeof (arp->arp_tpa)); /* here becomes source */ bcopy(d->myea, arp->arp_sha, sizeof (arp->arp_sha)); bcopy(&d->myip, arp->arp_spa, sizeof (arp->arp_spa)); /* * No need to get fancy here. If the send fails, the * requestor will just ask again. */ (void) sendether(d, pkt, sizeof (*arp) + 18, arp->arp_tha, ETHERTYPE_ARP); } /* * Copyright (c) 1998 Michael Smith. * All rights reserved. * * 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. * * 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. */ #include #include #include "stand.h" void __assert(const char *func, const char *file, int line, const char *expression) { if (func == NULL) panic("Assertion failed: (%s), file %s, line %d.", expression, file, line); else panic("Assertion failed: (%s), function %s, file %s, line %d.", expression, func, file, line); } /* * Some data-tables that are often used. * Cannot be copyrighted. */ #include __FBSDID("$FreeBSD$"); #include u_char const bcd2bin_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; u_char const bin2bcd_data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 }; /* This is actually used with radix [2..36] */ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include #include #include #include #include #include #include #define BOOTP_DEBUGxx #define SUPPORT_DHCP #define DHCP_ENV_NOVENDOR 1 /* do not parse vendor options */ #define DHCP_ENV_PXE 10 /* assume pxe vendor options */ #define DHCP_ENV_FREEBSD 11 /* assume freebsd vendor options */ /* set DHCP_ENV to one of the values above to export dhcp options to kenv */ #define DHCP_ENV DHCP_ENV_NO_VENDOR #include "stand.h" #include "net.h" #include "netif.h" #include "bootp.h" struct in_addr servip; static time_t bot; static char vm_rfc1048[4] = VM_RFC1048; #ifdef BOOTP_VEND_CMU static char vm_cmu[4] = VM_CMU; #endif /* Local forwards */ static ssize_t bootpsend(struct iodesc *, void *, size_t); static ssize_t bootprecv(struct iodesc *, void **, void **, time_t, void *); static int vend_rfc1048(uchar_t *, uint_t); #ifdef BOOTP_VEND_CMU static void vend_cmu(uchar_t *); #endif #ifdef DHCP_ENV /* export the dhcp response to kenv */ struct dhcp_opt; static void setenv_(uchar_t *cp, uchar_t *ep, struct dhcp_opt *opts); #else #define setenv_(a, b, c) #endif #ifdef SUPPORT_DHCP static char expected_dhcpmsgtype = -1, dhcp_ok; struct in_addr dhcp_serverip; #endif struct bootp *bootp_response; size_t bootp_response_size; static void bootp_fill_request(unsigned char *bp_vend) { /* * We are booting from PXE, we want to send the string * 'PXEClient' to the DHCP server so you have the option of * only responding to PXE aware dhcp requests. */ bp_vend[0] = TAG_CLASSID; bp_vend[1] = 9; bcopy("PXEClient", &bp_vend[2], 9); bp_vend[11] = TAG_USER_CLASS; /* len of each user class + number of user class */ bp_vend[12] = 8; /* len of the first user class */ bp_vend[13] = 7; bcopy("illumos", &bp_vend[14], 7); bp_vend[21] = TAG_PARAM_REQ; bp_vend[22] = 7; bp_vend[23] = TAG_SUBNET_MASK; bp_vend[24] = TAG_GATEWAY; bp_vend[25] = TAG_HOSTNAME; bp_vend[26] = TAG_SWAPSERVER; bp_vend[27] = TAG_ROOTPATH; bp_vend[28] = TAG_INTF_MTU; bp_vend[29] = TAG_SERVERID; bp_vend[30] = TAG_END; } /* Fetch required bootp infomation */ void bootp(int sock) { void *pkt; struct iodesc *d; struct bootp *bp; struct { uchar_t header[HEADER_SIZE]; struct bootp wbootp; } wbuf; struct bootp *rbootp; #ifdef BOOTP_DEBUG if (debug) printf("bootp: socket=%d\n", sock); #endif if (!bot) bot = getsecs(); if (!(d = socktodesc(sock))) { printf("bootp: bad socket. %d\n", sock); return; } #ifdef BOOTP_DEBUG if (debug) printf("bootp: d=%lx\n", (long)d); #endif bp = &wbuf.wbootp; bzero(bp, sizeof (*bp)); bp->bp_op = BOOTREQUEST; bp->bp_htype = 1; /* 10Mb Ethernet (48 bits) */ bp->bp_hlen = 6; bp->bp_xid = htonl(d->xid); MACPY(d->myea, bp->bp_chaddr); strncpy(bp->bp_file, bootfile, sizeof (bp->bp_file)); bcopy(vm_rfc1048, bp->bp_vend, sizeof (vm_rfc1048)); #ifdef SUPPORT_DHCP bp->bp_vend[4] = TAG_DHCP_MSGTYPE; bp->bp_vend[5] = 1; bp->bp_vend[6] = DHCPDISCOVER; bootp_fill_request(&bp->bp_vend[7]); #else bp->bp_vend[4] = TAG_END; #endif d->myip.s_addr = INADDR_ANY; d->myport = htons(IPPORT_BOOTPC); d->destip.s_addr = INADDR_BROADCAST; d->destport = htons(IPPORT_BOOTPS); #ifdef SUPPORT_DHCP expected_dhcpmsgtype = DHCPOFFER; dhcp_ok = 0; #endif if (sendrecv(d, bootpsend, bp, sizeof (*bp), bootprecv, &pkt, (void **)&rbootp, NULL) == -1) { printf("bootp: no reply\n"); return; } #ifdef SUPPORT_DHCP if (dhcp_ok) { uint32_t leasetime; bp->bp_vend[6] = DHCPREQUEST; bp->bp_vend[7] = TAG_REQ_ADDR; bp->bp_vend[8] = 4; bcopy(&rbootp->bp_yiaddr, &bp->bp_vend[9], 4); bp->bp_vend[13] = TAG_SERVERID; bp->bp_vend[14] = 4; bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4); bp->bp_vend[19] = TAG_LEASETIME; bp->bp_vend[20] = 4; leasetime = htonl(300); bcopy(&leasetime, &bp->bp_vend[21], 4); bootp_fill_request(&bp->bp_vend[25]); expected_dhcpmsgtype = DHCPACK; free(pkt); if (sendrecv(d, bootpsend, bp, sizeof (*bp), bootprecv, &pkt, (void **)&rbootp, NULL) == -1) { printf("DHCPREQUEST failed\n"); return; } } #endif myip = d->myip = rbootp->bp_yiaddr; servip = rbootp->bp_siaddr; if (rootip.s_addr == INADDR_ANY) rootip = servip; bcopy(rbootp->bp_file, bootfile, sizeof (bootfile)); bootfile[sizeof (bootfile) - 1] = '\0'; if (!netmask) { if (IN_CLASSA(ntohl(myip.s_addr))) netmask = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(myip.s_addr))) netmask = htonl(IN_CLASSB_NET); else netmask = htonl(IN_CLASSC_NET); #ifdef BOOTP_DEBUG if (debug) printf("'native netmask' is %s\n", intoa(netmask)); #endif } #ifdef BOOTP_DEBUG if (debug) printf("mask: %s\n", intoa(netmask)); #endif /* We need a gateway if root is on a different net */ if (!SAMENET(myip, rootip, netmask)) { #ifdef BOOTP_DEBUG if (debug) printf("need gateway for root ip\n"); #endif } /* Toss gateway if on a different net */ if (!SAMENET(myip, gateip, netmask)) { #ifdef BOOTP_DEBUG if (debug) printf("gateway ip (%s) bad\n", inet_ntoa(gateip)); #endif gateip.s_addr = 0; } /* Bump xid so next request will be unique. */ ++d->xid; free(pkt); } /* Transmit a bootp request */ static ssize_t bootpsend(struct iodesc *d, void *pkt, size_t len) { struct bootp *bp; #ifdef BOOTP_DEBUG if (debug) printf("bootpsend: d=%lx called.\n", (long)d); #endif bp = pkt; bp->bp_secs = htons((ushort_t)(getsecs() - bot)); #ifdef BOOTP_DEBUG if (debug) printf("bootpsend: calling sendudp\n"); #endif return (sendudp(d, pkt, len)); } static ssize_t bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra __unused) { ssize_t n; struct bootp *bp; void *ptr; #ifdef BOOTP_DEBUG if (debug) printf("bootp_recvoffer: called\n"); #endif ptr = NULL; n = readudp(d, &ptr, (void **)&bp, tleft); if (n == -1 || n < sizeof (struct bootp) - BOOTP_VENDSIZE) goto bad; #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: checked. bp = %p, n = %zd\n", bp, n); #endif if (bp->bp_xid != htonl(d->xid)) { #ifdef BOOTP_DEBUG if (debug) { printf("bootprecv: expected xid 0x%lx, got 0x%x\n", d->xid, ntohl(bp->bp_xid)); } #endif goto bad; } #ifdef BOOTP_DEBUG if (debug) printf("bootprecv: got one!\n"); #endif /* Suck out vendor info */ if (bcmp(vm_rfc1048, bp->bp_vend, sizeof (vm_rfc1048)) == 0) { int vsize = n - offsetof(struct bootp, bp_vend); if (vend_rfc1048(bp->bp_vend, vsize) != 0) goto bad; /* Save copy of bootp reply or DHCP ACK message */ if (bp->bp_op == BOOTREPLY && ((dhcp_ok == 1 && expected_dhcpmsgtype == DHCPACK) || dhcp_ok == 0)) { free(bootp_response); bootp_response = malloc(n); if (bootp_response != NULL) { bootp_response_size = n; bcopy(bp, bootp_response, bootp_response_size); } } } #ifdef BOOTP_VEND_CMU else if (bcmp(vm_cmu, bp->bp_vend, sizeof (vm_cmu)) == 0) vend_cmu(bp->bp_vend); #endif else printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend); *pkt = ptr; *payload = bp; return (n); bad: free(ptr); errno = 0; return (-1); } static int vend_rfc1048(uchar_t *cp, uint_t len) { uchar_t *ep; int size; uchar_t tag; const char *val; #ifdef BOOTP_DEBUG if (debug) printf("vend_rfc1048 bootp info. len=%d\n", len); #endif ep = cp + len; /* Step over magic cookie */ cp += sizeof (int); setenv_(cp, ep, NULL); while (cp < ep) { tag = *cp++; size = *cp++; if (tag == TAG_END) break; if (tag == TAG_SUBNET_MASK) { bcopy(cp, &netmask, sizeof (netmask)); } if (tag == TAG_GATEWAY) { bcopy(cp, &gateip.s_addr, sizeof (gateip.s_addr)); } if (tag == TAG_SWAPSERVER) { /* let it override bp_siaddr */ bcopy(cp, &rootip.s_addr, sizeof (rootip.s_addr)); } if (tag == TAG_ROOTPATH) { if ((val = getenv("dhcp.root-path")) == NULL) val = (const char *)cp; strlcpy(rootpath, val, sizeof (rootpath)); } if (tag == TAG_HOSTNAME) { if ((val = getenv("dhcp.host-name")) == NULL) val = (const char *)cp; strlcpy(hostname, val, sizeof (hostname)); } if (tag == TAG_INTF_MTU) { intf_mtu = 0; if ((val = getenv("dhcp.interface-mtu")) != NULL) { unsigned long tmp; char *end; errno = 0; /* * Do not allow MTU to exceed max IPv4 packet * size, max value of 16-bit word. */ tmp = strtoul(val, &end, 0); if (errno != 0 || *val == '\0' || *end != '\0' || tmp > USHRT_MAX) { printf("%s: bad value: \"%s\", " "ignoring\n", "dhcp.interface-mtu", val); } else { intf_mtu = (uint_t)tmp; } } if (intf_mtu == 0) intf_mtu = be16dec(cp); } #ifdef SUPPORT_DHCP if (tag == TAG_DHCP_MSGTYPE) { if (*cp != expected_dhcpmsgtype) return (-1); dhcp_ok = 1; } if (tag == TAG_SERVERID) { bcopy(cp, &dhcp_serverip.s_addr, sizeof (dhcp_serverip.s_addr)); } #endif cp += size; } return (0); } #ifdef BOOTP_VEND_CMU static void vend_cmu(uchar_t *cp) { struct cmu_vend *vp; #ifdef BOOTP_DEBUG if (debug) printf("vend_cmu bootp info.\n"); #endif vp = (struct cmu_vend *)cp; if (vp->v_smask.s_addr != 0) { netmask = vp->v_smask.s_addr; } if (vp->v_dgate.s_addr != 0) { gateip = vp->v_dgate; } } #endif #ifdef DHCP_ENV /* * Parse DHCP options and store them into kenv variables. * Original code from Danny Braniss, modifications by Luigi Rizzo. * * The parser is driven by tables which specify the type and name of * each dhcp option and how it appears in kenv. * The first entry in the list contains the prefix used to set the kenv * name (including the . if needed), the last entry must have a 0 tag. * Entries do not need to be sorted though it helps for readability. * * Certain vendor-specific tables can be enabled according to DHCP_ENV. * Set it to 0 if you don't want any. */ enum opt_fmt { __NONE = 0, __8 = 1, __16 = 2, __32 = 4, /* Unsigned fields, value=size */ __IP, /* IPv4 address */ __TXT, /* C string */ __BYTES, /* byte sequence, printed %02x */ __INDIR, /* name=value */ __ILIST, /* name=value;name=value ... */ __VE, /* vendor specific, recurse */ }; struct dhcp_opt { uint8_t tag; uint8_t fmt; const char *desc; }; static struct dhcp_opt vndr_opt[] = { /* Vendor Specific Options */ #if DHCP_ENV == DHCP_ENV_FREEBSD /* FreeBSD table in the original code */ {0, 0, "FreeBSD"}, /* prefix */ {1, __TXT, "kernel"}, {2, __TXT, "kernelname"}, {3, __TXT, "kernel_options"}, {4, __IP, "usr-ip"}, {5, __TXT, "conf-path"}, {6, __TXT, "rc.conf0"}, {7, __TXT, "rc.conf1"}, {8, __TXT, "rc.conf2"}, {9, __TXT, "rc.conf3"}, {10, __TXT, "rc.conf4"}, {11, __TXT, "rc.conf5"}, {12, __TXT, "rc.conf6"}, {13, __TXT, "rc.conf7"}, {14, __TXT, "rc.conf8"}, {15, __TXT, "rc.conf9"}, {20, __TXT, "boot.nfsroot.options"}, {245, __INDIR, ""}, {246, __INDIR, ""}, {247, __INDIR, ""}, {248, __INDIR, ""}, {249, __INDIR, ""}, {250, __INDIR, ""}, {251, __INDIR, ""}, {252, __INDIR, ""}, {253, __INDIR, ""}, {254, __INDIR, ""}, #elif DHCP_ENV == DHCP_ENV_PXE /* some pxe options, RFC4578 */ {0, 0, "pxe"}, /* prefix */ {93, __16, "system-architecture"}, {94, __BYTES, "network-interface"}, {97, __BYTES, "machine-identifier"}, #else /* default (empty) table */ {0, 0, "dhcp.vendor."}, /* prefix */ #endif {0, __TXT, "%soption-%d"} }; static struct dhcp_opt dhcp_opt[] = { /* DHCP Option names, formats and codes, from RFC2132. */ {0, 0, "dhcp."}, // prefix {1, __IP, "subnet-mask"}, {2, __32, "time-offset"}, /* this is signed */ {3, __IP, "routers"}, {4, __IP, "time-servers"}, {5, __IP, "ien116-name-servers"}, {6, __IP, "domain-name-servers"}, {7, __IP, "log-servers"}, {8, __IP, "cookie-servers"}, {9, __IP, "lpr-servers"}, {10, __IP, "impress-servers"}, {11, __IP, "resource-location-servers"}, {12, __TXT, "host-name"}, {13, __16, "boot-size"}, {14, __TXT, "merit-dump"}, {15, __TXT, "domain-name"}, {16, __IP, "swap-server"}, {17, __TXT, "root-path"}, {18, __TXT, "extensions-path"}, {19, __8, "ip-forwarding"}, {20, __8, "non-local-source-routing"}, {21, __IP, "policy-filter"}, {22, __16, "max-dgram-reassembly"}, {23, __8, "default-ip-ttl"}, {24, __32, "path-mtu-aging-timeout"}, {25, __16, "path-mtu-plateau-table"}, {26, __16, "interface-mtu"}, {27, __8, "all-subnets-local"}, {28, __IP, "broadcast-address"}, {29, __8, "perform-mask-discovery"}, {30, __8, "mask-supplier"}, {31, __8, "perform-router-discovery"}, {32, __IP, "router-solicitation-address"}, {33, __IP, "static-routes"}, {34, __8, "trailer-encapsulation"}, {35, __32, "arp-cache-timeout"}, {36, __8, "ieee802-3-encapsulation"}, {37, __8, "default-tcp-ttl"}, {38, __32, "tcp-keepalive-interval"}, {39, __8, "tcp-keepalive-garbage"}, {40, __TXT, "nis-domain"}, {41, __IP, "nis-servers"}, {42, __IP, "ntp-servers"}, {43, __VE, "vendor-encapsulated-options"}, {44, __IP, "netbios-name-servers"}, {45, __IP, "netbios-dd-server"}, {46, __8, "netbios-node-type"}, {47, __TXT, "netbios-scope"}, {48, __IP, "x-font-servers"}, {49, __IP, "x-display-managers"}, {50, __IP, "dhcp-requested-address"}, {51, __32, "dhcp-lease-time"}, {52, __8, "dhcp-option-overload"}, {53, __8, "dhcp-message-type"}, {54, __IP, "dhcp-server-identifier"}, {55, __8, "dhcp-parameter-request-list"}, {56, __TXT, "dhcp-message"}, {57, __16, "dhcp-max-message-size"}, {58, __32, "dhcp-renewal-time"}, {59, __32, "dhcp-rebinding-time"}, {60, __TXT, "vendor-class-identifier"}, {61, __TXT, "dhcp-client-identifier"}, {64, __TXT, "nisplus-domain"}, {65, __IP, "nisplus-servers"}, {66, __TXT, "tftp-server-name"}, {67, __TXT, "bootfile-name"}, {68, __IP, "mobile-ip-home-agent"}, {69, __IP, "smtp-server"}, {70, __IP, "pop-server"}, {71, __IP, "nntp-server"}, {72, __IP, "www-server"}, {73, __IP, "finger-server"}, {74, __IP, "irc-server"}, {75, __IP, "streettalk-server"}, {76, __IP, "streettalk-directory-assistance-server"}, {77, __TXT, "user-class"}, {85, __IP, "nds-servers"}, {86, __TXT, "nds-tree-name"}, {87, __TXT, "nds-context"}, {210, __TXT, "authenticate"}, /* use the following entries for arbitrary variables */ {246, __ILIST, ""}, {247, __ILIST, ""}, {248, __ILIST, ""}, {249, __ILIST, ""}, {250, __INDIR, ""}, {251, __INDIR, ""}, {252, __INDIR, ""}, {253, __INDIR, ""}, {254, __INDIR, ""}, {0, __TXT, "%soption-%d"} }; /* * parse a dhcp response, set environment variables translating options * names and values according to the tables above. Also set dhcp.tags * to the list of selected tags. */ static void setenv_(uchar_t *cp, uchar_t *ep, struct dhcp_opt *opts) { uchar_t *ncp; uchar_t tag; char tags[512], *tp; /* the list of tags */ #define FLD_SEP ',' /* separator in list of elements */ ncp = cp; tp = tags; if (opts == NULL) opts = dhcp_opt; while (ncp < ep) { unsigned int size; /* option size */ char *vp, *endv, buf[256]; /* the value buffer */ struct dhcp_opt *op; tag = *ncp++; /* extract tag and size */ size = *ncp++; cp = ncp; /* current payload */ ncp += size; /* point to the next option */ if (tag == TAG_END) break; if (tag == 0) continue; for (op = opts+1; op->tag && op->tag != tag; op++) ; /* if not found we end up on the default entry */ /* * Copy data into the buffer. libstand does not have snprintf * so we need to be careful with sprintf(). With strings, the * source is always <256 char so shorter than the buffer so we * are safe; with other arguments, the longest string is * inet_ntoa which is 16 bytes so we make sure to have always * enough room in the string before trying an sprint. */ vp = buf; *vp = '\0'; /* last valid write position */ endv = buf + sizeof (buf) - 1 - 16; switch (op->fmt) { case __NONE: break; /* should not happen */ case __VE: /* recurse, vendor specific */ setenv_(cp, cp+size, vndr_opt); break; case __IP: /* ip address */ for (; size > 0 && vp < endv; size -= 4, cp += 4) { struct in_addr in_ip; /* ip addresses */ if (vp != buf) *vp++ = FLD_SEP; bcopy(cp, &in_ip.s_addr, sizeof (in_ip.s_addr)); sprintf(vp, "%s", inet_ntoa(in_ip)); vp += strlen(vp); } break; case __BYTES: /* opaque byte string */ for (; size > 0 && vp < endv; size -= 1, cp += 1) { sprintf(vp, "%02x", *cp); vp += strlen(vp); } break; case __TXT: bcopy(cp, buf, size); /* cannot overflow */ buf[size] = 0; break; case __32: case __16: case __8: /* op->fmt is also the length of each field */ for (; size > 0 && vp < endv; size -= op->fmt, cp += op->fmt) { uint32_t v; if (op->fmt == __32) v = (cp[0]<<24) + (cp[1]<<16) + (cp[2]<<8) + cp[3]; else if (op->fmt == __16) v = (cp[0]<<8) + cp[1]; else v = cp[0]; if (vp != buf) *vp++ = FLD_SEP; sprintf(vp, "%u", v); vp += strlen(vp); } break; case __INDIR: /* name=value */ case __ILIST: /* name=value;name=value... */ bcopy(cp, buf, size); /* cannot overflow */ buf[size] = '\0'; for (endv = buf; endv; endv = vp) { char *s = NULL; /* semicolon ? */ /* skip leading whitespace */ while (*endv && strchr(" \t\n\r", *endv)) endv++; /* find name=value separator */ vp = strchr(endv, '='); if (!vp) break; *vp++ = 0; if (op->fmt == __ILIST && (s = strchr(vp, ';'))) *s++ = '\0'; setenv(endv, vp, 1); vp = s; /* prepare for next round */ } buf[0] = '\0'; /* option already done */ } if (tp - tags < sizeof (tags) - 5) { /* add tag to the list */ if (tp != tags) *tp++ = FLD_SEP; sprintf(tp, "%d", tag); tp += strlen(tp); } if (buf[0]) { char env[128]; /* the string name */ if (op->tag == 0) sprintf(env, op->desc, opts[0].desc, tag); else sprintf(env, "%s%s", opts[0].desc, op->desc); /* * Do not replace existing values in the environment, * so that locally-obtained values can override * server-provided values. */ setenv(env, buf, 0); } } if (tp != tags) { char env[128]; /* the string name */ sprintf(env, "%stags", opts[0].desc); setenv(env, tags, 1); } } #endif /* additional dhcp */ /* * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. * * This file specifies the "implementation-independent" BOOTP protocol * information which is common to both client and server. * * Copyright 1988 by Carnegie Mellon. * * Permission to use, copy, modify, and distribute this program for any * purpose and without fee is hereby granted, provided that this copyright * and permission notice appear on all copies and supporting documentation, * the name of Carnegie Mellon not be used in advertising or publicity * pertaining to distribution of the program without specific prior * permission, and notice be given in supporting documentation that copying * and distribution is by permission of Carnegie Mellon and Stanford * University. Carnegie Mellon makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ #ifndef _BOOTP_H_ #define _BOOTP_H_ #include struct bootp { unsigned char bp_op; /* packet opcode type */ unsigned char bp_htype; /* hardware addr type */ unsigned char bp_hlen; /* hardware addr length */ unsigned char bp_hops; /* gateway hops */ unsigned int bp_xid; /* transaction ID */ unsigned short bp_secs; /* seconds since boot began */ unsigned short bp_flags; struct in_addr bp_ciaddr; /* client IP address */ struct in_addr bp_yiaddr; /* 'your' IP address */ struct in_addr bp_siaddr; /* server IP address */ struct in_addr bp_giaddr; /* gateway IP address */ unsigned char bp_chaddr[16]; /* client hardware address */ unsigned char bp_sname[64]; /* server host name */ char bp_file[128]; /* boot file name */ #ifdef SUPPORT_DHCP #define BOOTP_VENDSIZE 312 #else #define BOOTP_VENDSIZE 64 #endif unsigned char bp_vend[BOOTP_VENDSIZE]; /* vendor-specific area */ }; /* * UDP port numbers, server and client. */ #define IPPORT_BOOTPS 67 #define IPPORT_BOOTPC 68 #define BOOTREPLY 2 #define BOOTREQUEST 1 /* * Vendor magic cookie (v_magic) for CMU */ #define VM_CMU "CMU" /* * Vendor magic cookie (v_magic) for RFC1048 */ #define VM_RFC1048 { 99, 130, 83, 99 } /* * RFC1048 tag values used to specify what information is being supplied in * the vendor field of the packet. */ #define TAG_PAD ((unsigned char) 0) #define TAG_SUBNET_MASK ((unsigned char) 1) #define TAG_TIME_OFFSET ((unsigned char) 2) #define TAG_GATEWAY ((unsigned char) 3) #define TAG_TIME_SERVER ((unsigned char) 4) #define TAG_NAME_SERVER ((unsigned char) 5) #define TAG_DOMAIN_SERVER ((unsigned char) 6) #define TAG_LOG_SERVER ((unsigned char) 7) #define TAG_COOKIE_SERVER ((unsigned char) 8) #define TAG_LPR_SERVER ((unsigned char) 9) #define TAG_IMPRESS_SERVER ((unsigned char) 10) #define TAG_RLP_SERVER ((unsigned char) 11) #define TAG_HOSTNAME ((unsigned char) 12) #define TAG_BOOTSIZE ((unsigned char) 13) #define TAG_DUMPFILE ((unsigned char) 14) #define TAG_DOMAINNAME ((unsigned char) 15) #define TAG_SWAPSERVER ((unsigned char) 16) #define TAG_ROOTPATH ((unsigned char) 17) #define TAG_INTF_MTU ((unsigned char) 26) #ifdef SUPPORT_DHCP #define TAG_REQ_ADDR ((unsigned char) 50) #define TAG_LEASETIME ((unsigned char) 51) #define TAG_OVERLOAD ((unsigned char) 52) #define TAG_DHCP_MSGTYPE ((unsigned char) 53) #define TAG_SERVERID ((unsigned char) 54) #define TAG_PARAM_REQ ((unsigned char) 55) #define TAG_MSG ((unsigned char) 56) #define TAG_MAXSIZE ((unsigned char) 57) #define TAG_T1 ((unsigned char) 58) #define TAG_T2 ((unsigned char) 59) #define TAG_CLASSID ((unsigned char) 60) #define TAG_CLIENTID ((unsigned char) 61) #define TAG_USER_CLASS ((unsigned char) 77) #endif #define TAG_END ((unsigned char) 255) #ifdef SUPPORT_DHCP #define DHCPDISCOVER 1 #define DHCPOFFER 2 #define DHCPREQUEST 3 #define DHCPDECLINE 4 #define DHCPACK 5 #define DHCPNAK 6 #define DHCPRELEASE 7 #endif /* * "vendor" data permitted for CMU bootp clients. */ struct cmu_vend { unsigned char v_magic[4]; /* magic number */ unsigned int v_flags; /* flags/opcodes, etc. */ struct in_addr v_smask; /* Subnet mask */ struct in_addr v_dgate; /* Default gateway */ struct in_addr v_dns1, v_dns2; /* Domain name servers */ struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */ struct in_addr v_ts1, v_ts2; /* Time servers */ unsigned char v_unused[25]; /* currently unused */ }; /* v_flags values */ #define VF_SMASK 1 /* Subnet mask field contains valid data */ /* cached bootp response/dhcp ack */ extern struct bootp *bootp_response; extern size_t bootp_response_size; #endif /* _BOOTP_H_ */ /* $NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $ */ /* * Copyright (c) 1995 Gordon W. Ross * All rights reserved. * * 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. * 4. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Gordon W. Ross * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #include /* * RPC/bootparams */ #include #include #include #include #include #include #include "rpcv2.h" #include "stand.h" #include "net.h" #include "netif.h" #include "rpc.h" #include "bootparam.h" #ifdef DEBUG_RPC #define RPC_PRINTF(a) printf a #else #define RPC_PRINTF(a) #endif struct in_addr bp_server_addr; /* net order */ n_short bp_server_port; /* net order */ /* * RPC definitions for bootparamd */ #define BOOTPARAM_PROG 100026 #define BOOTPARAM_VERS 1 #define BOOTPARAM_WHOAMI 1 #define BOOTPARAM_GETFILE 2 /* * Inet address in RPC messages * (Note, really four ints, NOT chars. Blech.) */ struct xdr_inaddr { u_int32_t atype; int32_t addr[4]; }; int xdr_inaddr_encode(char **p, struct in_addr ia); int xdr_inaddr_decode(char **p, struct in_addr *ia); int xdr_string_encode(char **p, char *str, int len); int xdr_string_decode(char **p, char *str, int *len_p); /* * RPC: bootparam/whoami * Given client IP address, get: * client name (hostname) * domain name (domainname) * gateway address * * The hostname and domainname are set here for convenience. * * Note - bpsin is initialized to the broadcast address, * and will be replaced with the bootparam server address * after this call is complete. Have to use PMAP_PROC_CALL * to make sure we get responses only from a servers that * know about us (don't want to broadcast a getport call). */ int bp_whoami(int sockfd) { /* RPC structures for PMAPPROC_CALLIT */ struct args { u_int32_t prog; u_int32_t vers; u_int32_t proc; u_int32_t arglen; struct xdr_inaddr xina; } *args; struct repl { u_int16_t _pad; u_int16_t port; u_int32_t encap_len; /* encapsulated data here */ n_long capsule[64]; } *repl; struct { n_long h[RPC_HEADER_WORDS]; struct args d; } sdata; char *send_tail, *recv_head; struct iodesc *d; void *pkt; int len, x, rc; RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip))); rc = -1; if (!(d = socktodesc(sockfd))) { RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd)); return (rc); } args = &sdata.d; /* * Build request args for PMAPPROC_CALLIT. */ args->prog = htonl(BOOTPARAM_PROG); args->vers = htonl(BOOTPARAM_VERS); args->proc = htonl(BOOTPARAM_WHOAMI); args->arglen = htonl(sizeof(struct xdr_inaddr)); send_tail = (char*) &args->xina; /* * append encapsulated data (client IP address) */ if (xdr_inaddr_encode(&send_tail, myip)) return (rc); /* RPC: portmap/callit */ d->myport = htons(--rpc_port); d->destip.s_addr = INADDR_BROADCAST; /* XXX: subnet bcast? */ /* rpc_call will set d->destport */ pkt = NULL; len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT, args, send_tail - (char*)args, (void **)&repl, &pkt); if (len < 8) { printf("bootparamd: 'whoami' call failed\n"); goto done; } /* Save bootparam server address (from IP header). */ rpc_fromaddr(repl, &bp_server_addr, &bp_server_port); /* * Note that bp_server_port is now 111 due to the * indirect call (using PMAPPROC_CALLIT), so get the * actual port number from the reply data. */ bp_server_port = repl->port; RPC_PRINTF(("bp_whoami: server at %s:%d\n", inet_ntoa(bp_server_addr), ntohs(bp_server_port))); /* We have just done a portmap call, so cache the portnum. */ rpc_pmap_putcache(bp_server_addr, BOOTPARAM_PROG, BOOTPARAM_VERS, (int)ntohs(bp_server_port)); /* * Parse the encapsulated results from bootparam/whoami */ x = ntohl(repl->encap_len); if (len < x) { printf("bp_whoami: short reply, %d < %d\n", len, x); goto done; } recv_head = (char*) repl->capsule; /* client name */ hostnamelen = MAXHOSTNAMELEN-1; if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) { RPC_PRINTF(("bp_whoami: bad hostname\n")); goto done; } /* domain name */ domainnamelen = MAXHOSTNAMELEN-1; if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) { RPC_PRINTF(("bp_whoami: bad domainname\n")); goto done; } /* gateway address */ if (xdr_inaddr_decode(&recv_head, &gateip)) { RPC_PRINTF(("bp_whoami: bad gateway\n")); goto done; } /* success */ rc = 0; done: free(pkt); return(rc); } /* * RPC: bootparam/getfile * Given client name and file "key", get: * server name * server IP address * server pathname */ int bp_getfile(int sockfd, char *key, struct in_addr *serv_addr, char *pathname) { struct { n_long h[RPC_HEADER_WORDS]; n_long d[64]; } sdata; void *pkt; char serv_name[FNAME_SIZE]; char *rdata, *send_tail; /* misc... */ struct iodesc *d; int rc = -1, sn_len, path_len, rlen; if (!(d = socktodesc(sockfd))) { RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd)); return (-1); } send_tail = (char*) sdata.d; /* * Build request message. */ /* client name (hostname) */ if (xdr_string_encode(&send_tail, hostname, hostnamelen)) { RPC_PRINTF(("bp_getfile: bad client\n")); return (-1); } /* key name (root or swap) */ if (xdr_string_encode(&send_tail, key, strlen(key))) { RPC_PRINTF(("bp_getfile: bad key\n")); return (-1); } /* RPC: bootparam/getfile */ d->myport = htons(--rpc_port); d->destip = bp_server_addr; /* rpc_call will set d->destport */ pkt = NULL; rlen = rpc_call(d, BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE, sdata.d, send_tail - (char*)sdata.d, (void **)&rdata, &pkt); if (rlen < 4) { RPC_PRINTF(("bp_getfile: short reply\n")); errno = EBADRPC; goto done; } /* * Parse result message. */ /* server name */ sn_len = FNAME_SIZE-1; if (xdr_string_decode(&rdata, serv_name, &sn_len)) { RPC_PRINTF(("bp_getfile: bad server name\n")); goto done; } /* server IP address (mountd/NFS) */ if (xdr_inaddr_decode(&rdata, serv_addr)) { RPC_PRINTF(("bp_getfile: bad server addr\n")); goto done; } /* server pathname */ path_len = MAXPATHLEN-1; if (xdr_string_decode(&rdata, pathname, &path_len)) { RPC_PRINTF(("bp_getfile: bad server path\n")); goto done; } /* success */ rc = 0; done: free(pkt); return(rc); } /* * eXternal Data Representation routines. * (but with non-standard args...) */ int xdr_string_encode(char **pkt, char *str, int len) { uint32_t *lenp; char *datap; int padlen = (len + 3) & ~3; /* padded length */ /* The data will be int aligned. */ lenp = (uint32_t *) *pkt; *pkt += sizeof(*lenp); *lenp = htonl(len); datap = *pkt; *pkt += padlen; bcopy(str, datap, len); return (0); } int xdr_string_decode(char **pkt, char *str, int *len_p) { uint32_t *lenp; char *datap; int slen; /* string length */ int plen; /* padded length */ /* The data will be int aligned. */ lenp = (uint32_t *) *pkt; *pkt += sizeof(*lenp); slen = ntohl(*lenp); plen = (slen + 3) & ~3; if (slen > *len_p) slen = *len_p; datap = *pkt; *pkt += plen; bcopy(datap, str, slen); str[slen] = '\0'; *len_p = slen; return (0); } int xdr_inaddr_encode(char **pkt, struct in_addr ia) { struct xdr_inaddr *xi; u_char *cp; int32_t *ip; union { n_long l; /* network order */ u_char c[4]; } uia; /* The data will be int aligned. */ xi = (struct xdr_inaddr *) *pkt; *pkt += sizeof(*xi); xi->atype = htonl(1); uia.l = ia.s_addr; cp = uia.c; ip = xi->addr; /* * Note: the htonl() calls below DO NOT * imply that uia.l is in host order. * In fact this needs it in net order. */ *ip++ = htonl((unsigned int)*cp++); *ip++ = htonl((unsigned int)*cp++); *ip++ = htonl((unsigned int)*cp++); *ip++ = htonl((unsigned int)*cp++); return (0); } int xdr_inaddr_decode(char **pkt, struct in_addr *ia) { struct xdr_inaddr *xi; u_char *cp; int32_t *ip; union { n_long l; /* network order */ u_char c[4]; } uia; /* The data will be int aligned. */ xi = (struct xdr_inaddr *) *pkt; *pkt += sizeof(*xi); if (xi->atype != htonl(1)) { RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n", ntohl(xi->atype))); return(-1); } cp = uia.c; ip = xi->addr; /* * Note: the ntohl() calls below DO NOT * imply that uia.l is in host order. * In fact this needs it in net order. */ *cp++ = ntohl(*ip++); *cp++ = ntohl(*ip++); *cp++ = ntohl(*ip++); *cp++ = ntohl(*ip++); ia->s_addr = uia.l; return (0); } /* $NetBSD: bootparam.h,v 1.3 1998/01/05 19:19:41 perry Exp $ */ int bp_whoami(int sock); int bp_getfile(int sock, char *key, struct in_addr *addrp, char *path); /* $NetBSD: cd9660.c,v 1.5 1997/06/26 19:11:33 drochner Exp $ */ /* * Copyright (C) 1996 Wolfgang Solfrank. * Copyright (C) 1996 TooLs GmbH. * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by TooLs GmbH. * 4. The name of TooLs GmbH may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. */ #include /* * Stand-alone ISO9660 file reading package. * * Note: This doesn't support Rock Ridge extensions, extended attributes, * blocksizes other than 2048 bytes, multi-extent files, etc. */ #include #include #include #include #include #include #include "stand.h" #define SUSP_CONTINUATION "CE" #define SUSP_PRESENT "SP" #define SUSP_STOP "ST" #define SUSP_EXTREF "ER" #define RRIP_NAME "NM" typedef struct { ISO_SUSP_HEADER h; uchar_t signature [ISODCL(5, 6)]; uchar_t len_skp [ISODCL(7, 7)]; /* 711 */ } ISO_SUSP_PRESENT; static int buf_read_file(struct open_file *f, char **buf_p, size_t *size_p); static int cd9660_open(const char *path, struct open_file *f); static int cd9660_close(struct open_file *f); static int cd9660_read(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t cd9660_seek(struct open_file *f, off_t offset, int where); static int cd9660_stat(struct open_file *f, struct stat *sb); static int cd9660_readdir(struct open_file *f, struct dirent *d); static int dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp, int use_rrip, int lenskip); static int rrip_check(struct open_file *f, struct iso_directory_record *dp, int *lenskip); static char *rrip_lookup_name(struct open_file *f, struct iso_directory_record *dp, int lenskip, size_t *len); static ISO_SUSP_HEADER *susp_lookup_record(struct open_file *f, const char *identifier, struct iso_directory_record *dp, int lenskip); struct fs_ops cd9660_fsops = { .fs_name = "cd9660", .fo_open = cd9660_open, .fo_close = cd9660_close, .fo_read = cd9660_read, .fo_write = null_write, .fo_seek = cd9660_seek, .fo_stat = cd9660_stat, .fo_readdir = cd9660_readdir }; #define F_ISDIR 0x0001 /* Directory */ #define F_ROOTDIR 0x0002 /* Root directory */ #define F_RR 0x0004 /* Rock Ridge on this volume */ struct file { int f_flags; /* file flags */ off_t f_off; /* Current offset within file */ daddr_t f_bno; /* Starting block number */ off_t f_size; /* Size of file */ daddr_t f_buf_blkno; /* block number of data block */ char *f_buf; /* buffer for data block */ int f_susp_skip; /* len_skip for SUSP records */ }; struct ptable_ent { char namlen [ISODCL(1, 1)]; /* 711 */ char extlen [ISODCL(2, 2)]; /* 711 */ char block [ISODCL(3, 6)]; /* 732 */ char parent [ISODCL(7, 8)]; /* 722 */ char name [1]; }; #define PTFIXSZ 8 #define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2) #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE) static ISO_SUSP_HEADER * susp_lookup_record(struct open_file *f, const char *identifier, struct iso_directory_record *dp, int lenskip) { static char susp_buffer[ISO_DEFAULT_BLOCK_SIZE]; ISO_SUSP_HEADER *sh; ISO_RRIP_CONT *shc; char *p, *end; int error; size_t read; p = dp->name + isonum_711(dp->name_len) + lenskip; /* Names of even length have a padding byte after the name. */ if ((isonum_711(dp->name_len) & 1) == 0) p++; end = (char *)dp + isonum_711(dp->length); while (p + 3 < end) { sh = (ISO_SUSP_HEADER *)p; if (bcmp(sh->type, identifier, 2) == 0) return (sh); if (bcmp(sh->type, SUSP_STOP, 2) == 0) return (NULL); if (bcmp(sh->type, SUSP_CONTINUATION, 2) == 0) { shc = (ISO_RRIP_CONT *)sh; error = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(isonum_733(shc->location)), ISO_DEFAULT_BLOCK_SIZE, susp_buffer, &read); /* Bail if it fails. */ if (error != 0 || read != ISO_DEFAULT_BLOCK_SIZE) return (NULL); p = susp_buffer + isonum_733(shc->offset); end = p + isonum_733(shc->length); } else { /* Ignore this record and skip to the next. */ p += isonum_711(sh->length); /* Avoid infinite loops with corrupted file systems */ if (isonum_711(sh->length) == 0) return (NULL); } } return (NULL); } static char * rrip_lookup_name(struct open_file *f, struct iso_directory_record *dp, int lenskip, size_t *len) { ISO_RRIP_ALTNAME *p; if (len == NULL) return (NULL); p = (ISO_RRIP_ALTNAME *)susp_lookup_record(f, RRIP_NAME, dp, lenskip); if (p == NULL) return (NULL); switch (*p->flags) { case ISO_SUSP_CFLAG_CURRENT: *len = 1; return ("."); case ISO_SUSP_CFLAG_PARENT: *len = 2; return (".."); case 0: *len = isonum_711(p->h.length) - 5; return ((char *)p + 5); default: /* * We don't handle hostnames or continued names as they are * too hard, so just bail and use the default name. */ return (NULL); } } static int rrip_check(struct open_file *f, struct iso_directory_record *dp, int *lenskip) { ISO_SUSP_PRESENT *sp; ISO_RRIP_EXTREF *er; char *p; /* First, see if we can find a SP field. */ p = dp->name + isonum_711(dp->name_len); if (p > (char *)dp + isonum_711(dp->length)) return (0); sp = (ISO_SUSP_PRESENT *)p; if (bcmp(sp->h.type, SUSP_PRESENT, 2) != 0) return (0); if (isonum_711(sp->h.length) != sizeof (ISO_SUSP_PRESENT)) return (0); if (sp->signature[0] != 0xbe || sp->signature[1] != 0xef) return (0); *lenskip = isonum_711(sp->len_skp); /* * Now look for an ER field. If RRIP is present, then there must * be at least one of these. It would be more pedantic to walk * through the list of fields looking for a Rock Ridge ER field. */ er = (ISO_RRIP_EXTREF *)susp_lookup_record(f, SUSP_EXTREF, dp, 0); if (er == NULL) return (0); return (1); } static int dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp, int use_rrip, int lenskip) { size_t len, plen; char *cp, *sep; int i, icase; if (use_rrip) cp = rrip_lookup_name(f, dp, lenskip, &len); else cp = NULL; if (cp == NULL) { len = isonum_711(dp->name_len); cp = dp->name; icase = 1; } else icase = 0; sep = strchr(path, '/'); if (sep != NULL) { plen = sep - path; } else { plen = strlen(path); } if (plen != len) return (0); for (i = len; --i >= 0; path++, cp++) { if (!*path || *path == '/') break; if (*path == *cp) continue; if (!icase && toupper(*path) == *cp) continue; return (0); } if (*path && *path != '/') return (0); /* * Allow stripping of trailing dots and the version number. * Note that this will find the first instead of the last version * of a file. */ if (i >= 0 && (*cp == ';' || *cp == '.')) { /* This is to prevent matching of numeric extensions */ if (*cp == '.' && cp[1] != ';') return (0); while (--i >= 0) if (*++cp != ';' && (*cp < '0' || *cp > '9')) return (0); } return (1); } static int cd9660_open(const char *path, struct open_file *f) { struct file *fp = NULL; void *buf; struct iso_primary_descriptor *vd; size_t read, dsize, off; daddr_t bno, boff; struct iso_directory_record rec; struct iso_directory_record *dp = NULL; int rc, first, use_rrip, lenskip; bool isdir = false; /* First find the volume descriptor */ buf = malloc(MAX(ISO_DEFAULT_BLOCK_SIZE, sizeof (struct iso_primary_descriptor))); vd = buf; for (bno = 16; ; bno++) { twiddle(1); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno), ISO_DEFAULT_BLOCK_SIZE, buf, &read); if (rc) goto out; if (read != ISO_DEFAULT_BLOCK_SIZE) { rc = EIO; goto out; } rc = EINVAL; if (bcmp(vd->id, ISO_STANDARD_ID, sizeof (vd->id)) != 0) goto out; if (isonum_711(vd->type) == ISO_VD_END) goto out; if (isonum_711(vd->type) == ISO_VD_PRIMARY) break; } if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) goto out; bcopy(vd->root_directory_record, &rec, sizeof (rec)); if (*path == '/') path++; /* eat leading '/' */ first = 1; use_rrip = 0; lenskip = 0; while (*path) { bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); dsize = isonum_733(rec.size); off = 0; boff = 0; while (off < dsize) { if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) { twiddle(1); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno + boff), ISO_DEFAULT_BLOCK_SIZE, buf, &read); if (rc) goto out; if (read != ISO_DEFAULT_BLOCK_SIZE) { rc = EIO; goto out; } boff++; dp = (struct iso_directory_record *)buf; } if (isonum_711(dp->length) == 0) { /* skip to next block, if any */ off = boff * ISO_DEFAULT_BLOCK_SIZE; continue; } /* See if RRIP is in use. */ if (first) use_rrip = rrip_check(f, dp, &lenskip); if (dirmatch(f, path, dp, use_rrip, first ? 0 : lenskip)) { first = 0; break; } else { first = 0; } dp = (struct iso_directory_record *) ((char *)dp + isonum_711(dp->length)); /* If the new block has zero length, it is padding. */ if (isonum_711(dp->length) == 0) { /* Skip to next block, if any. */ off = boff * ISO_DEFAULT_BLOCK_SIZE; continue; } off += isonum_711(dp->length); } if (off >= dsize) { rc = ENOENT; goto out; } rec = *dp; while (*path && *path != '/') /* look for next component */ path++; if (*path) /* this component was directory */ isdir = true; while (*path == '/') path++; /* skip '/' */ if (*path) /* We do have next component. */ isdir = false; } /* * if the path had trailing / but the path does point to file, * report the error ENOTDIR. */ if (isdir == true && (isonum_711(rec.flags) & 2) == 0) { rc = ENOTDIR; goto out; } /* allocate file system specific data structure */ fp = malloc(sizeof (struct file)); bzero(fp, sizeof (struct file)); f->f_fsdata = (void *)fp; if ((isonum_711(rec.flags) & 2) != 0) { fp->f_flags = F_ISDIR; } if (first) { fp->f_flags |= F_ROOTDIR; /* Check for Rock Ridge since we didn't in the loop above. */ bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); twiddle(1); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno), ISO_DEFAULT_BLOCK_SIZE, buf, &read); if (rc) goto out; if (read != ISO_DEFAULT_BLOCK_SIZE) { rc = EIO; goto out; } dp = (struct iso_directory_record *)buf; use_rrip = rrip_check(f, dp, &lenskip); } if (use_rrip) { fp->f_flags |= F_RR; fp->f_susp_skip = lenskip; } fp->f_off = 0; fp->f_bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); fp->f_size = isonum_733(rec.size); free(buf); return (0); out: free(fp); free(buf); return (rc); } static int cd9660_close(struct open_file *f) { struct file *fp = (struct file *)f->f_fsdata; f->f_fsdata = NULL; free(fp); return (0); } static int buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) { struct file *fp = (struct file *)f->f_fsdata; daddr_t blkno, blkoff; int rc = 0; size_t read; blkno = fp->f_off / ISO_DEFAULT_BLOCK_SIZE + fp->f_bno; blkoff = fp->f_off % ISO_DEFAULT_BLOCK_SIZE; if (blkno != fp->f_buf_blkno) { if (fp->f_buf == (char *)0) fp->f_buf = malloc(ISO_DEFAULT_BLOCK_SIZE); twiddle(16); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(blkno), ISO_DEFAULT_BLOCK_SIZE, fp->f_buf, &read); if (rc) return (rc); if (read != ISO_DEFAULT_BLOCK_SIZE) return (EIO); fp->f_buf_blkno = blkno; } *buf_p = fp->f_buf + blkoff; *size_p = ISO_DEFAULT_BLOCK_SIZE - blkoff; if (*size_p > fp->f_size - fp->f_off) *size_p = fp->f_size - fp->f_off; return (rc); } static int cd9660_read(struct open_file *f, void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; char *buf, *addr; size_t buf_size, csize; int rc = 0; addr = start; while (size) { if (fp->f_off < 0 || fp->f_off >= fp->f_size) break; rc = buf_read_file(f, &buf, &buf_size); if (rc) break; csize = size > buf_size ? buf_size : size; bcopy(buf, addr, csize); fp->f_off += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (rc); } static int cd9660_readdir(struct open_file *f, struct dirent *d) { struct file *fp = (struct file *)f->f_fsdata; struct iso_directory_record *ep; size_t buf_size, reclen, namelen; int error = 0; int lenskip; char *buf, *name; again: if (fp->f_off >= fp->f_size) return (ENOENT); error = buf_read_file(f, &buf, &buf_size); if (error) return (error); ep = (struct iso_directory_record *)buf; if (isonum_711(ep->length) == 0) { daddr_t blkno; /* skip to next block, if any */ blkno = fp->f_off / ISO_DEFAULT_BLOCK_SIZE; fp->f_off = (blkno + 1) * ISO_DEFAULT_BLOCK_SIZE; goto again; } if (fp->f_flags & F_RR) { if (fp->f_flags & F_ROOTDIR && fp->f_off == 0) lenskip = 0; else lenskip = fp->f_susp_skip; name = rrip_lookup_name(f, ep, lenskip, &namelen); } else name = NULL; if (name == NULL) { namelen = isonum_711(ep->name_len); name = ep->name; if (namelen == 1) { if (ep->name[0] == 0) name = "."; else if (ep->name[0] == 1) { namelen = 2; name = ".."; } } } reclen = sizeof (struct dirent) - (MAXNAMLEN+1) + namelen + 1; reclen = (reclen + 3) & ~3; d->d_fileno = isonum_733(ep->extent); d->d_reclen = reclen; if (isonum_711(ep->flags) & 2) d->d_type = DT_DIR; else d->d_type = DT_REG; d->d_namlen = namelen; bcopy(name, d->d_name, d->d_namlen); d->d_name[d->d_namlen] = 0; fp->f_off += isonum_711(ep->length); return (0); } static off_t cd9660_seek(struct open_file *f, off_t offset, int where) { struct file *fp = (struct file *)f->f_fsdata; switch (where) { case SEEK_SET: fp->f_off = offset; break; case SEEK_CUR: fp->f_off += offset; break; case SEEK_END: fp->f_off = fp->f_size - offset; break; default: return (-1); } return (fp->f_off); } static int cd9660_stat(struct open_file *f, struct stat *sb) { struct file *fp = (struct file *)f->f_fsdata; /* only important stuff */ sb->st_mode = S_IRUSR | S_IRGRP | S_IROTH; if (fp->f_flags & F_ISDIR) sb->st_mode |= S_IFDIR; else sb->st_mode |= S_IFREG; sb->st_uid = sb->st_gid = 0; sb->st_size = fp->f_size; return (0); } /* $NetBSD: close.c,v 1.7 1997/01/22 00:38:09 cgd Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)close.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include "stand.h" int close(int fd) { struct open_file *f, *last; int err1 = 0, err2 = 0; f = fd2open_file(fd); if (f == NULL) { errno = EBADF; return (-1); } free(f->f_rabuf); f->f_rabuf = NULL; if (f->f_flags != 0) { if (!(f->f_flags & F_RAW) && f->f_ops) err1 = (f->f_ops->fo_close)(f); if (!(f->f_flags & F_NODEV) && f->f_dev) err2 = (f->f_dev->dv_close)(f); if (f->f_devdata != NULL) devclose(f); f->f_flags = 0; } else { /* Attempt to close already closed file. */ err1 = EBADF; } /* free unused entries from tail. */ TAILQ_FOREACH_REVERSE_SAFE(last, &files, file_list, f_link, f) { if (last->f_flags != 0) break; TAILQ_REMOVE(&files, last, f_link); free(last); } if (err1) { errno = err1; return (-1); } if (err2) { errno = err2; return (-1); } return (0); } /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2021 Toomas Soome * * 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. * * 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. */ #include #include "stand.h" void closeall(void) { struct open_file *f; /* * Pick up last entry and close it, this will also trigger * the removal of this entry, and we end up with empty list. */ while ((f = TAILQ_LAST(&files, file_list)) != NULL) { (void) close(f->f_id); } /* reset errno from close() */ errno = 0; } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2021 Toomas Soome # COMDIR = $(SRC)/common/crypto SRCS += $(CRYPTOSRC)/digest.c SRCS += $(COMDIR)/sha1/sha1.c SRCS += $(COMDIR)/edonr/edonr.c SRCS += $(COMDIR)/skein/skein.c SRCS += $(COMDIR)/skein/skein_iv.c SRCS += $(COMDIR)/skein/skein_block.c OBJECTS += digest.o OBJECTS += sha1.o OBJECTS += edonr.o OBJECTS += skein.o OBJECTS += skein_iv.o OBJECTS += skein_block.o objs/digest.o: CPPFLAGS += -I../../common pics/digest.o: CPPFLAGS += -I../../common # Do not unroll skein loops, reduce code size objs/skein_block.o: CPPFLAGS += -DSKEIN_LOOP=111 pics/skein_block.o: CPPFLAGS += -DSKEIN_LOOP=111 objs/%.o: $(COMDIR)/edonr/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(COMDIR)/edonr/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(COMDIR)/skein/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(COMDIR)/skein/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(CRYPTOSRC)/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(CRYPTOSRC)/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(COMDIR)/sha1/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(COMDIR)/sha1/%.c $(COMPILE.c) -o $@ $< sha1-x86_64.S: $(COMDIR)/sha1/amd64/sha1-x86_64.pl $(PERL) $? $@ pics/sha1-x86_64.o: sha1-x86_64.S $(COMPILE.s) -o $@ ${@F:.o=.S} #include #include #include #include void sha1(void *data, size_t size, uint8_t *result) { SHA1_CTX sha1_ctx; SHA1Init(&sha1_ctx); SHA1Update(&sha1_ctx, data, size); SHA1Final(result, &sha1_ctx); } static int command_sha1(int argc, char **argv) { void *ptr; size_t size, i; uint8_t resultbuf[SHA1_DIGEST_LENGTH]; /* * usage: address size */ if (argc != 3) { command_errmsg = "usage: address size"; return (CMD_ERROR); } ptr = (void *)(uintptr_t)strtol(argv[1], NULL, 0); size = strtol(argv[2], NULL, 0); sha1(ptr, size, resultbuf); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) printf("%02x", resultbuf[i]); printf("\n"); return (CMD_OK); } COMMAND_SET(sha1, "sha1", "print the sha1 checksum", command_sha1); /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2019 Toomas Soome */ #ifndef _LIBCRYPTO_H #define _LIBCRYPTO_H #ifdef __cplusplus extern "C" { #endif extern void sha1(void *, size_t, uint8_t *); #ifdef __cplusplus } #endif #endif /* _LIBCRYPTO_H */ /* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)dev.c 8.1 (Berkeley) 6/11/93 */ #include #include #include #include "stand.h" int nodev(void) { return (ENXIO); } void nullsys(void) { } int noioctl(struct open_file *f __unused, ulong_t cmd __unused, void *data __unused) { return (EINVAL); } /* * Copyright (c) 1996, 1998 Robert Nordier * All rights reserved. * Copyright 2024 MNX Cloud, 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. */ #include /* * Readonly filesystem for Microsoft FAT12/FAT16/FAT32 filesystems, * also supports VFAT. */ #include #include #include #include #include "stand.h" #include "dosfs.h" static int dos_open(const char *, struct open_file *); static int dos_close(struct open_file *); static int dos_read(struct open_file *, void *, size_t, size_t *); static off_t dos_seek(struct open_file *, off_t offset, int); static int dos_stat(struct open_file *, struct stat *); static int dos_readdir(struct open_file *, struct dirent *); struct fs_ops dosfs_fsops = { .fs_name = "dosfs", .fo_open = dos_open, .fo_close = dos_close, .fo_read = dos_read, .fo_write = null_write, .fo_seek = dos_seek, .fo_stat = dos_stat, .fo_readdir = dos_readdir }; #define LOCLUS 2 /* lowest cluster number */ #define FATBLKSZ 0x20000 /* size of block in the FAT cache buffer */ /* DOS "BIOS Parameter Block" */ typedef struct { uchar_t secsiz[2]; /* sector size */ uchar_t spc; /* sectors per cluster */ uchar_t ressec[2]; /* reserved sectors */ uchar_t fats; /* FATs */ uchar_t dirents[2]; /* root directory entries */ uchar_t secs[2]; /* total sectors */ uchar_t media; /* media descriptor */ uchar_t spf[2]; /* sectors per FAT */ uchar_t spt[2]; /* sectors per track */ uchar_t heads[2]; /* drive heads */ uchar_t hidsec[4]; /* hidden sectors */ uchar_t lsecs[4]; /* huge sectors */ union { struct { uchar_t drvnum; /* Int 13 drive number */ uchar_t rsvd1; /* Reserved */ uchar_t bootsig; /* Boot signature (0x29) */ uchar_t volid[4]; /* Volume serial number */ uchar_t vollab[11]; /* Volume label */ uchar_t fstype[8]; /* Informational */ } f12_f16; struct { uchar_t lspf[4]; /* huge sectors per FAT */ uchar_t xflg[2]; /* flags */ uchar_t vers[2]; /* filesystem version */ uchar_t rdcl[4]; /* root directory cluster */ uchar_t infs[2]; /* filesystem info sector */ uchar_t bkbs[2]; /* backup boot sector */ uchar_t reserved[12]; /* Reserved */ uchar_t drvnum; /* Int 13 drive number */ uchar_t rsvd1; /* Reserved */ uchar_t bootsig; /* Boot signature (0x29) */ uchar_t volid[4]; /* Volume serial number */ uchar_t vollab[11]; /* Volume label */ uchar_t fstype[8]; /* Informational */ } f32; } fstype; } DOS_BPB; /* Initial portion of DOS boot sector */ typedef struct { uchar_t jmp[3]; /* usually 80x86 'jmp' opcode */ uchar_t oem[8]; /* OEM name and version */ DOS_BPB bpb; /* BPB */ } DOS_BS; typedef struct { uchar_t fsi_leadsig[4]; /* Value 0x41615252 */ uchar_t fsi_reserved1[480]; uchar_t fsi_structsig[4]; /* Value 0x61417272 */ uchar_t fsi_free_count[4]; /* Last known free cluster count */ uchar_t fsi_next_free[4]; /* First free cluster */ uchar_t fsi_reserved2[12]; uchar_t fsi_trailsig[4]; /* Value 0xAA550000 */ } DOS_FSINFO; /* Supply missing "." and ".." root directory entries */ static const char *const dotstr[2] = {".", ".."}; static DOS_DE dot[2] = { {". ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}}, {".. ", " ", FA_DIR, {0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, {0, 0}, {0x21, 0}, {0, 0}, {0, 0, 0, 0}} }; /* The usual conversion macros to avoid multiplication and division */ #define bytsec(fs, n) ((n) >> (fs)->sshift) #define secbyt(fs, s) ((s) << (fs)->sshift) #define depsec(fs) (1U << (fs)->dshift) #define entsec(fs, e) ((e) >> (fs)->dshift) #define bytblk(fs, n) ((n) >> (fs)->bshift) #define blkbyt(fs, b) ((b) << (fs)->bshift) #define secblk(fs, s) ((s) >> ((fs)->bshift - (fs)->sshift)) #define blksec(fs, b) ((b) << ((fs)->bshift - (fs)->sshift)) /* Convert cluster number to offset within filesystem */ #define blkoff(fs, b) (secbyt(fs, (fs)->lsndta) + \ blkbyt(fs, (b) - LOCLUS)) /* Convert cluster number to logical sector number */ #define blklsn(fs, b) ((fs)->lsndta + blksec(fs, (b) - LOCLUS)) /* Convert cluster number to offset within FAT */ #define fatoff(sz, c) ((sz) == 12 ? (c) + ((c) >> 1) : \ (sz) == 16 ? (c) << 1 : \ (c) << 2) /* Does cluster number reference a valid data cluster? */ #define okclus(fs, c) ((c) >= LOCLUS && (c) <= (fs)->xclus) /* Get start cluster from directory entry */ #define stclus(sz, de) ((sz) != 32 ? (uint_t)cv2((de)->clus) : \ ((uint_t)cv2((de)->dex.h_clus) << 16) | \ cv2((de)->clus)) static int parsebs(DOS_FS *, DOS_BS *); static int namede(DOS_FS *, const char *, DOS_DE **); static int lookup(DOS_FS *, uint_t, const char *, DOS_DE **); static void cp_xdnm(uchar_t *, DOS_XDE *); static void cp_sfn(uchar_t *, DOS_DE *); static off_t fsize(DOS_FS *, DOS_DE *); static int fatcnt(DOS_FS *, uint_t); static int fatget(DOS_FS *, uint_t *); static int fatend(uint_t, uint_t); static int ioread(DOS_FS *, uint64_t, void *, size_t); static int ioget(DOS_FS *, daddr_t, void *, size_t); static int dos_read_fatblk(DOS_FS *fs, uint_t blknum) { int err; ssize_t io_size; daddr_t offset_in_fat, max_offset_in_fat; /* * Because daddr_t is signed, we also use signed io_size * so we can avoid type cast we would otherwise need * because of promotion to unsigned. */ io_size = FATBLKSZ; offset_in_fat = ((daddr_t)blknum) * io_size; max_offset_in_fat = secbyt(fs, (daddr_t)fs->spf); if (offset_in_fat > max_offset_in_fat) offset_in_fat = max_offset_in_fat; if (offset_in_fat + io_size > max_offset_in_fat) io_size = (max_offset_in_fat - offset_in_fat); if (io_size != 0) { err = ioget(fs, fs->lsnfat + bytsec(fs, offset_in_fat), fs->fatbuf, io_size); if (err != 0) { fs->fatbuf_blknum = ((uint_t)(-1)); return (err); } } if (io_size < FATBLKSZ) memset(fs->fatbuf + io_size, 0, FATBLKSZ - io_size); fs->fatbuf_blknum = blknum; return (0); } /* * Mount DOS filesystem */ static int dos_mount(DOS_FS **fsp, struct open_file *fd) { int err; unsigned secsz; uchar_t *buf; DOS_FS *fs; /* Allocate mount structure, associate with open */ fs = calloc(1, sizeof (DOS_FS)); if (fs == NULL) return (errno); fs->fd = fd; err = ioctl(fd->f_id, DIOCGSECTORSIZE, &secsz); if (err != 0) { free(fs); return (err); } buf = malloc(secsz); if (buf == NULL) { free(fs); return (errno); } if ((err = ioget(fs, 0, buf, secsz)) || (err = parsebs(fs, (DOS_BS *)buf))) { free(buf); free(fs); return (err); } fs->secbuf = buf; fs->fatbuf = malloc(FATBLKSZ); if (fs->fatbuf == NULL) { free(buf); free(fs); return (errno); } err = dos_read_fatblk(fs, 0); if (err != 0) { free(fs->fatbuf); free(buf); free(fs); return (err); } fs->root = dot[0]; fs->root.name[0] = ' '; if (fs->fatsz == 32) { fs->root.clus[0] = fs->rdcl & 0xff; fs->root.clus[1] = (fs->rdcl >> 8) & 0xff; fs->root.dex.h_clus[0] = (fs->rdcl >> 16) & 0xff; fs->root.dex.h_clus[1] = (fs->rdcl >> 24) & 0xff; } *fsp = fs; return (0); } /* * Unmount mounted filesystem */ static int dos_unmount(DOS_FS *fs) { if (fs->links) return (EBUSY); free(fs->secbuf); free(fs->fatbuf); free(fs); return (0); } /* * Open DOS file */ static int dos_open(const char *path, struct open_file *fd) { DOS_DE *de; DOS_FILE *f; DOS_FS *fs; uint_t size, clus; int err; if ((err = dos_mount(&fs, fd))) { return (err); } if ((err = namede(fs, path, &de))) { dos_unmount(fs); return (err); } clus = stclus(fs->fatsz, de); size = cv4(de->size); if ((!(de->attr & FA_DIR) && (!clus != !size)) || ((de->attr & FA_DIR) && size) || (clus && !okclus(fs, clus))) { dos_unmount(fs); return (EINVAL); } if ((f = malloc(sizeof (DOS_FILE))) == NULL) { err = errno; dos_unmount(fs); return (err); } bzero(f, sizeof (DOS_FILE)); f->fs = fs; fs->links++; f->de = *de; fd->f_fsdata = f; return (0); } /* * Read from file */ static int dos_read(struct open_file *fd, void *buf, size_t nbyte, size_t *resid) { off_t size; uint64_t off; size_t nb; uint_t clus, c, cnt, n; DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; int err = 0; /* * as ioget() can be called *a lot*, use twiddle here. * also 4 seems to be good value not to slow loading down too much: * with 270MB file (~540k ioget() calls, twiddle can easily waste * 4-5 sec. */ twiddle(4); nb = nbyte; if ((size = fsize(f->fs, &f->de)) == -1) return (EINVAL); if (nb > (n = size - f->offset)) nb = n; off = f->offset; if ((clus = stclus(f->fs->fatsz, &f->de))) off &= f->fs->bsize - 1; c = f->c; cnt = nb; while (cnt) { n = 0; if (!c) { if ((c = clus)) n = bytblk(f->fs, f->offset); } else if (!off) n++; while (n--) { if ((err = fatget(f->fs, &c))) goto out; if (!okclus(f->fs, c)) { err = EINVAL; goto out; } } if (!clus || (n = f->fs->bsize - off) > cnt) n = cnt; if (c != 0) off += blkoff(f->fs, (uint64_t)c); else off += secbyt(f->fs, f->fs->lsndir); err = ioread(f->fs, off, buf, n); if (err != 0) goto out; f->offset += n; f->c = c; off = 0; buf = (char *)buf + n; cnt -= n; } out: if (resid) *resid = nbyte - nb + cnt; return (err); } /* * Reposition within file */ static off_t dos_seek(struct open_file *fd, off_t offset, int whence) { off_t off; uint_t size; DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; size = cv4(f->de.size); switch (whence) { case SEEK_SET: off = 0; break; case SEEK_CUR: off = f->offset; break; case SEEK_END: off = size; break; default: errno = EINVAL; return (-1); } off += offset; if (off < 0 || off > size) { errno = EINVAL; return (-1); } f->offset = (uint_t)off; f->c = 0; return (off); } /* * Close open file */ static int dos_close(struct open_file *fd) { DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; DOS_FS *fs = f->fs; f->fs->links--; free(f); dos_unmount(fs); return (0); } /* * Return some stat information on a file. */ static int dos_stat(struct open_file *fd, struct stat *sb) { DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; /* only important stuff */ sb->st_mode = f->de.attr & FA_DIR ? S_IFDIR | 0555 : S_IFREG | 0444; sb->st_nlink = 1; sb->st_uid = 0; sb->st_gid = 0; if ((sb->st_size = fsize(f->fs, &f->de)) == -1) return (EINVAL); return (0); } static int dos_checksum(unsigned char *name, unsigned char *ext) { int x, i; char buf[11]; bcopy(name, buf, 8); bcopy(ext, buf+8, 3); x = 0; for (i = 0; i < 11; i++) { x = ((x & 1) << 7) | (x >> 1); x += buf[i]; x &= 0xff; } return (x); } static int dos_readdir(struct open_file *fd, struct dirent *d) { uchar_t fn[261]; DOS_DIR dd; size_t res; uint_t chk, x, xdn; int err; x = chk = 0; while (1) { xdn = x; x = 0; err = dos_read(fd, &dd, sizeof (dd), &res); if (err) return (err); if (res == sizeof (dd)) return (ENOENT); if (dd.de.name[0] == 0) return (ENOENT); /* Skip deleted entries */ if (dd.de.name[0] == 0xe5) continue; /* Check if directory entry is volume label */ if (dd.de.attr & FA_LABEL) { /* * If volume label set, check if the current entry is * extended entry (FA_XDE) for long file names. */ if ((dd.de.attr & FA_MASK) == FA_XDE) { /* * Read through all following extended entries * to get the long file name. 0x40 marks the * last entry containing part of long file name. */ if (dd.xde.seq & 0x40) chk = dd.xde.chk; else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk) continue; x = dd.xde.seq & ~0x40; if (x < 1 || x > 20) { x = 0; continue; } cp_xdnm(fn, &dd.xde); } else { /* skip only volume label entries */ continue; } } else { if (xdn == 1) { x = dos_checksum(dd.de.name, dd.de.ext); if (x == chk) break; } else { cp_sfn(fn, &dd.de); break; } x = 0; } } d->d_fileno = (dd.de.clus[1] << 8) + dd.de.clus[0]; d->d_reclen = sizeof (*d); d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG; memcpy(d->d_name, fn, sizeof (d->d_name)); return (0); } /* * Parse DOS boot sector */ static int parsebs(DOS_FS *fs, DOS_BS *bs) { uint_t sc, RootDirSectors; if (bs->bpb.media < 0xf0) return (EINVAL); /* Check supported sector sizes */ switch (cv2(bs->bpb.secsiz)) { case 512: case 1024: case 2048: case 4096: fs->sshift = ffs(cv2(bs->bpb.secsiz)) - 1; break; default: return (EINVAL); } if (!(fs->spc = bs->bpb.spc) || fs->spc & (fs->spc - 1)) return (EINVAL); fs->bsize = secbyt(fs, fs->spc); fs->bshift = ffs(fs->bsize) - 1; fs->dshift = ffs(secbyt(fs, 1) / sizeof (DOS_DE)) - 1; fs->dirents = cv2(bs->bpb.dirents); fs->spf = cv2(bs->bpb.spf); fs->lsnfat = cv2(bs->bpb.ressec); if (fs->spf != 0) { if (bs->bpb.fats != 2) return (EINVAL); if (fs->dirents == 0) return (EINVAL); } else { fs->spf = cv4(bs->bpb.fstype.f32.lspf); if (fs->spf == 0) return (EINVAL); if (bs->bpb.fats == 0 || bs->bpb.fats > 16) return (EINVAL); fs->rdcl = cv4(bs->bpb.fstype.f32.rdcl); if (fs->rdcl < LOCLUS) return (EINVAL); } RootDirSectors = ((fs->dirents * sizeof (DOS_DE)) + (secbyt(fs, 1) - 1)) / secbyt(fs, 1); fs->lsndir = fs->lsnfat + fs->spf * bs->bpb.fats; fs->lsndta = fs->lsndir + RootDirSectors; if (!(sc = cv2(bs->bpb.secs)) && !(sc = cv4(bs->bpb.lsecs))) return (EINVAL); if (fs->lsndta > sc) return (EINVAL); if ((fs->xclus = secblk(fs, sc - fs->lsndta) + 1) < LOCLUS) return (EINVAL); fs->fatsz = fs->dirents ? fs->xclus < 0xff6 ? 12 : 16 : 32; sc = (secbyt(fs, fs->spf) << 1) / (fs->fatsz >> 2) - 1; if (fs->xclus > sc) fs->xclus = sc; return (0); } /* * Return directory entry from path */ static int namede(DOS_FS *fs, const char *path, DOS_DE **dep) { char name[256]; DOS_DE *de; char *s; size_t n; int err; err = 0; de = &fs->root; while (*path) { while (*path == '/') path++; if (*path == '\0') break; if (!(s = strchr(path, '/'))) s = strchr(path, 0); if ((n = s - path) > 255) return (ENAMETOOLONG); memcpy(name, path, n); name[n] = 0; path = s; if (!(de->attr & FA_DIR)) return (ENOTDIR); if ((err = lookup(fs, stclus(fs->fatsz, de), name, &de))) return (err); } *dep = de; return (0); } /* * Lookup path segment */ static int lookup(DOS_FS *fs, uint_t clus, const char *name, DOS_DE **dep) { DOS_DIR *dir; uchar_t lfn[261]; uchar_t sfn[13]; uint_t nsec, lsec, xdn, chk, sec, ent, x; int err, ok; if (!clus) for (ent = 0; ent < 2; ent++) if (!strcasecmp(name, dotstr[ent])) { *dep = dot + ent; return (0); } if (!clus && fs->fatsz == 32) clus = fs->rdcl; nsec = !clus ? entsec(fs, fs->dirents) : fs->spc; lsec = 0; xdn = chk = 0; dir = (DOS_DIR *)fs->secbuf; for (;;) { if (!clus && !lsec) lsec = fs->lsndir; else if (okclus(fs, clus)) lsec = blklsn(fs, clus); else return (EINVAL); for (sec = 0; sec < nsec; sec++) { if ((err = ioget(fs, lsec + sec, dir, secbyt(fs, 1)))) return (err); for (ent = 0; ent < depsec(fs); ent++) { if (dir[ent].de.name[0] == 0) return (ENOENT); if (dir[ent].de.name[0] == 0xe5) { xdn = 0; continue; } if ((dir[ent].de.attr & FA_MASK) == FA_XDE) { x = dir[ent].xde.seq; if (x & 0x40 || (x + 1 == xdn && dir[ent].xde.chk == chk)) { if (x & 0x40) { chk = dir[ent].xde.chk; x &= ~0x40; } if (x >= 1 && x <= 20) { cp_xdnm(lfn, &dir[ent].xde); xdn = x; continue; } } } else if (!(dir[ent].de.attr & FA_LABEL)) { if ((ok = xdn == 1)) { x = dos_checksum( dir[ent].de.name, dir[ent].de.ext); ok = chk == x && !strcasecmp(name, (const char *)lfn); } if (!ok) { cp_sfn(sfn, &dir[ent].de); ok = !strcasecmp(name, (const char *)sfn); } if (ok) { *dep = &dir[ent].de; return (0); } } xdn = 0; } } if (!clus) break; if ((err = fatget(fs, &clus))) return (err); if (fatend(fs->fatsz, clus)) break; } return (ENOENT); } /* * Copy name from extended directory entry */ static void cp_xdnm(uchar_t *lfn, DOS_XDE *xde) { static struct { uint_t off; uint_t dim; } ix[3] = { { offsetof(DOS_XDE, name1), sizeof (xde->name1) / 2}, { offsetof(DOS_XDE, name2), sizeof (xde->name2) / 2}, { offsetof(DOS_XDE, name3), sizeof (xde->name3) / 2} }; uchar_t *p; uint_t n, x, c; lfn += 13 * ((xde->seq & ~0x40) - 1); for (n = 0; n < 3; n++) for (p = (uchar_t *)xde + ix[n].off, x = ix[n].dim; x; p += 2, x--) { if ((c = cv2(p)) && (c < 32 || c > 127)) c = '?'; if (!(*lfn++ = c)) return; } if (xde->seq & 0x40) *lfn = 0; } /* * Copy short filename */ static void cp_sfn(uchar_t *sfn, DOS_DE *de) { uchar_t *p; int j, i; p = sfn; if (*de->name != ' ') { for (j = 7; de->name[j] == ' '; j--) ; for (i = 0; i <= j; i++) *p++ = de->name[i]; if (*de->ext != ' ') { *p++ = '.'; for (j = 2; de->ext[j] == ' '; j--) ; for (i = 0; i <= j; i++) *p++ = de->ext[i]; } } *p = '\0'; if (*sfn == 5) *sfn = 0xe5; } /* * Return size of file in bytes */ static off_t fsize(DOS_FS *fs, DOS_DE *de) { ulong_t size; uint_t c; int n; if (!(size = cv4(de->size)) && de->attr & FA_DIR) { if (!(c = stclus(fs->fatsz, de))) size = fs->dirents * sizeof (DOS_DE); else { if ((n = fatcnt(fs, c)) == -1) return (n); size = blkbyt(fs, n); } } return (size); } /* * Count number of clusters in chain */ static int fatcnt(DOS_FS *fs, uint_t c) { int n; for (n = 0; okclus(fs, c); n++) if (fatget(fs, &c)) return (-1); return (fatend(fs->fatsz, c) ? n : -1); } /* * Get next cluster in cluster chain. Use in core fat cache unless * the number of current 128K block in FAT has changed. */ static int fatget(DOS_FS *fs, uint_t *c) { uint_t val_in, val_out, offset, blknum, nbyte; const uchar_t *p_entry; int err; /* check input value to prevent overflow in fatoff() */ val_in = *c; if (val_in & 0xf0000000) return (EINVAL); /* ensure that current 128K FAT block is cached */ offset = fatoff(fs->fatsz, val_in); nbyte = fs->fatsz != 32 ? 2 : 4; if (offset + nbyte > secbyt(fs, fs->spf)) return (EINVAL); blknum = offset / FATBLKSZ; offset %= FATBLKSZ; if (offset + nbyte > FATBLKSZ) return (EINVAL); if (blknum != fs->fatbuf_blknum) { err = dos_read_fatblk(fs, blknum); if (err != 0) return (err); } p_entry = fs->fatbuf + offset; /* extract cluster number from FAT entry */ switch (fs->fatsz) { case 32: val_out = cv4(p_entry); val_out &= 0x0fffffff; break; case 16: val_out = cv2(p_entry); break; case 12: val_out = cv2(p_entry); if (val_in & 1) val_out >>= 4; else val_out &= 0xfff; break; default: return (EINVAL); } *c = val_out; return (0); } /* * Is cluster an end-of-chain marker? */ static int fatend(uint_t sz, uint_t c) { return (c > (sz == 12 ? 0xff7U : sz == 16 ? 0xfff7U : 0xffffff7)); } /* * Offset-based I/O primitive */ static int ioread(DOS_FS *fs, uint64_t offset, void *buf, size_t nbyte) { char *s; size_t n, secsiz; int err; uint64_t off; secsiz = secbyt(fs, 1); s = buf; if ((off = offset & (secsiz - 1))) { offset -= off; if ((n = secsiz - off) > nbyte) n = nbyte; err = ioget(fs, bytsec(fs, offset), fs->secbuf, secsiz); if (err != 0) return (err); memcpy(s, fs->secbuf + off, n); offset += secsiz; s += n; nbyte -= n; } n = nbyte & (secsiz - 1); if (nbyte -= n) { if ((err = ioget(fs, bytsec(fs, offset), s, nbyte))) return (err); offset += nbyte; s += nbyte; } if (n != 0) { err = ioget(fs, bytsec(fs, offset), fs->secbuf, secsiz); if (err != 0) return (err); memcpy(s, fs->secbuf, n); } return (0); } /* * Sector-based I/O primitive. Note, since strategy functions are operating * in terms of 512B sectors, we need to do necessary conversion here. */ static int ioget(DOS_FS *fs, daddr_t lsec, void *buf, size_t size) { size_t rsize; int rv; struct open_file *fd = fs->fd; /* Make sure we get full read or error. */ rsize = 0; /* convert native sector number to 512B sector number. */ lsec = secbyt(fs, lsec) >> 9; rv = (fd->f_dev->dv_strategy)(fd->f_devdata, F_READ, lsec, size, buf, &rsize); if ((rv == 0) && (size != rsize)) rv = EIO; return (rv); } /* * Copyright (c) 1996, 1998 Robert Nordier * All rights reserved. * Copyright 2024 MNX Cloud, 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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 DOSIO_H #define DOSIO_H /* * DOS file attributes */ #define FA_RDONLY 001 /* read-only */ #define FA_HIDDEN 002 /* hidden file */ #define FA_SYSTEM 004 /* system file */ #define FA_LABEL 010 /* volume label */ #define FA_DIR 020 /* directory */ #define FA_ARCH 040 /* archive (file modified) */ #define FA_XDE 017 /* extended directory entry */ #define FA_MASK 077 /* all attributes */ /* * Macros to convert DOS-format 16-bit and 32-bit quantities */ #define cv2(p) ((uint16_t)(p)[0] | \ ((uint16_t)(p)[1] << 010)) #define cv4(p) ((uint32_t)(p)[0] | \ ((uint32_t)(p)[1] << 010) | \ ((uint32_t)(p)[2] << 020) | \ ((uint32_t)(p)[3] << 030)) /* * Directory, filesystem, and file structures. */ typedef struct { uchar_t x_case; /* case */ uchar_t c_hsec; /* created: secs/100 */ uchar_t c_time[2]; /* created: time */ uchar_t c_date[2]; /* created: date */ uchar_t a_date[2]; /* accessed: date */ uchar_t h_clus[2]; /* clus[hi] */ } DOS_DEX; typedef struct { uchar_t name[8]; /* name */ uchar_t ext[3]; /* extension */ uchar_t attr; /* attributes */ DOS_DEX dex; /* VFAT/FAT32 only */ uchar_t time[2]; /* modified: time */ uchar_t date[2]; /* modified: date */ uchar_t clus[2]; /* starting cluster */ uchar_t size[4]; /* size */ } DOS_DE; typedef struct { uchar_t seq; /* flags */ uchar_t name1[5][2]; /* 1st name area */ uchar_t attr; /* (see fat_de) */ uchar_t res; /* reserved */ uchar_t chk; /* checksum */ uchar_t name2[6][2]; /* 2nd name area */ uchar_t clus[2]; /* (see fat_de) */ uchar_t name3[2][2]; /* 3rd name area */ } DOS_XDE; typedef union { DOS_DE de; /* standard directory entry */ DOS_XDE xde; /* extended directory entry */ } DOS_DIR; typedef struct { struct open_file *fd; /* file descriptor */ uchar_t *secbuf; /* sector cache */ uchar_t *fatbuf; /* FAT cache buffer */ uint_t fatbuf_blknum; /* number of 128K block in FAT cache buffer */ uint_t links; /* active links to structure */ uint_t sshift; /* sector shift */ uint_t spc; /* sectors per cluster */ uint_t bsize; /* cluster size in bytes */ uint_t bshift; /* cluster conversion shift */ uint_t dshift; /* directory entries shift */ uint_t dirents; /* root directory entries */ uint_t spf; /* sectors per fat */ uint_t rdcl; /* root directory start cluster */ daddr_t lsnfat; /* start of fat */ daddr_t lsndir; /* start of root dir */ daddr_t lsndta; /* start of data area */ uint_t fatsz; /* FAT entry size */ uint_t xclus; /* maximum cluster number */ DOS_DE root; } DOS_FS; typedef struct { DOS_FS *fs; /* associated filesystem */ DOS_DE de; /* directory entry */ uint_t offset; /* current offset */ uint_t c; /* last cluster read */ } DOS_FILE; #endif /* !DOSIO_H */ /* * Copyright (c) 1998 Michael Smith. * All rights reserved. * * 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. * * 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. */ #include /* * Manage an environment-like space in which string variables may be stored. * Provide support for some method-like operations for setting/retrieving * variables in order to allow some type strength. */ #include "stand.h" #include struct env_var *environ = NULL; /* * Look up (name) and return it's env_var structure. */ struct env_var * env_getenv(const char *name) { struct env_var *ev; for (ev = environ; ev != NULL; ev = ev->ev_next) if (strcmp(ev->ev_name, name) == 0) break; return (ev); } /* * Some notes: * * If the EV_VOLATILE flag is set, a copy of the variable is made. * If EV_DYNAMIC is set, the variable has been allocated with * malloc and ownership transferred to the environment. * If (value) is NULL, the variable is set but has no value. */ int env_setenv(const char *name, int flags, const void *value, ev_sethook_t sethook, ev_unsethook_t unsethook) { struct env_var *ev, *curr, *last; if ((ev = env_getenv(name)) != NULL) { /* * If there's a set hook, let it do the work * (unless we are working for one already). */ if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK)) return (ev->ev_sethook(ev, flags, value)); /* If there is data in the variable, discard it. */ if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0) free(ev->ev_value); ev->ev_value = NULL; ev->ev_flags &= ~EV_DYNAMIC; } else { /* * New variable; create and sort into list */ ev = malloc(sizeof (struct env_var)); ev->ev_name = strdup(name); ev->ev_value = NULL; ev->ev_flags = 0; /* hooks can only be set when the variable is instantiated */ ev->ev_sethook = sethook; ev->ev_unsethook = unsethook; /* Sort into list */ ev->ev_prev = NULL; ev->ev_next = NULL; /* Search for the record to insert before */ for (last = NULL, curr = environ; curr != NULL; last = curr, curr = curr->ev_next) { if (strcmp(ev->ev_name, curr->ev_name) < 0) { if (curr->ev_prev) { curr->ev_prev->ev_next = ev; } else { environ = ev; } ev->ev_next = curr; ev->ev_prev = curr->ev_prev; curr->ev_prev = ev; break; } } if (curr == NULL) { if (last == NULL) { environ = ev; } else { last->ev_next = ev; ev->ev_prev = last; } } } /* If we have a new value, use it */ if (flags & EV_VOLATILE) { ev->ev_value = strdup(value); ev->ev_flags |= EV_DYNAMIC; } else { ev->ev_value = (char *)value; ev->ev_flags |= flags & EV_DYNAMIC; } return (0); } char * getenv(const char *name) { struct env_var *ev; /* Set but no value gives empty string */ if ((ev = env_getenv(name)) != NULL) { if (ev->ev_value != NULL) return (ev->ev_value); return (""); } return (NULL); } int setenv(const char *name, const char *value, int overwrite) { /* No guarantees about state, always assume volatile */ if (overwrite || (env_getenv(name) == NULL)) return (env_setenv(name, EV_VOLATILE, value, NULL, NULL)); return (0); } int putenv(const char *string) { char *value, *copy; int result; copy = strdup(string); if ((value = strchr(copy, '=')) != NULL) *(value++) = 0; result = setenv(copy, value, 1); free(copy); return (result); } int unsetenv(const char *name) { struct env_var *ev; int err; err = 0; if ((ev = env_getenv(name)) == NULL) { err = ENOENT; } else { if (ev->ev_unsethook != NULL) err = ev->ev_unsethook(ev); if (err == 0) { env_discard(ev); } } return (err); } void env_discard(struct env_var *ev) { if (ev->ev_prev) ev->ev_prev->ev_next = ev->ev_next; if (ev->ev_next) ev->ev_next->ev_prev = ev->ev_prev; if (environ == ev) environ = ev->ev_next; free(ev->ev_name); if (ev->ev_value != NULL && (ev->ev_flags & EV_DYNAMIC) != 0) free(ev->ev_value); free(ev); } int env_noset(struct env_var *ev __unused, int flags __unused, const void *value __unused) { return (EPERM); } int env_nounset(struct env_var *ev __unused) { return (EPERM); } /* $NetBSD: ether.c,v 1.11 1997/07/07 15:52:50 drochner Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ #include #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" #include "netif.h" /* Caller must leave room for ethernet header in front!! */ ssize_t sendether(struct iodesc *d, void *pkt, size_t len, uint8_t *dea, int etype) { ssize_t n; struct ether_header *eh; #ifdef ETHER_DEBUG if (debug) printf("sendether: called\n"); #endif eh = (struct ether_header *)pkt - 1; len += sizeof (*eh); MACPY(d->myea, eh->ether_shost); /* by byte */ MACPY(dea, eh->ether_dhost); /* by byte */ eh->ether_type = htons(etype); n = netif_put(d, eh, len); if (n == -1 || n < sizeof (*eh)) return (-1); n -= sizeof (*eh); return (n); } /* * Get a packet of any Ethernet type, with our address or * the broadcast address. Save the Ether type in etype. * Unless there is an error, we pass the whole packet and the unencapsulated * data. */ ssize_t readether(struct iodesc *d, void **pkt, void **payload, time_t tleft, uint16_t *etype) { ssize_t n; struct ether_header *eh; void *ptr; #ifdef ETHER_DEBUG if (debug) printf("readether: called\n"); #endif ptr = NULL; n = netif_get(d, &ptr, tleft); if (n == -1 || n < sizeof (*eh)) { free(ptr); return (-1); } eh = (struct ether_header *)((uintptr_t)ptr + ETHER_ALIGN); /* Validate Ethernet address. */ if (bcmp(d->myea, eh->ether_dhost, 6) != 0 && bcmp(bcea, eh->ether_dhost, 6) != 0) { #ifdef ETHER_DEBUG if (debug) printf("readether: not ours (ea=%s)\n", ether_sprintf(eh->ether_dhost)); #endif free(ptr); return (-1); } *pkt = ptr; *payload = (void *)((uintptr_t)eh + sizeof (*eh)); *etype = ntohs(eh->ether_type); n -= sizeof (*eh); return (n); } /* * Convert Ethernet address to printable (loggable) representation. */ static char digits[] = "0123456789abcdef"; char * ether_sprintf(uchar_t *ap) { int i; static char etherbuf[18]; char *cp = etherbuf; for (i = 0; i < 6; i++) { *cp++ = digits[*ap >> 4]; *cp++ = digits[*ap++ & 0xf]; *cp++ = ':'; } *--cp = 0; return (etherbuf); } /* $NetBSD: fstat.c,v 1.1 1996/01/13 22:25:38 leo Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stat.c 8.1 (Berkeley) 6/11/93 */ #include #include "stand.h" int fstat(int fd, struct stat *sb) { struct open_file *f; f = fd2open_file(fd); if (f == NULL || f->f_flags == 0) { errno = EBADF; return (-1); } /* operation not defined on raw devices */ if (f->f_flags & F_RAW) { errno = EOPNOTSUPP; return (-1); } errno = (f->f_ops->fo_stat)(f, sb); if (errno) return (-1); return (0); } /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include __FBSDID("$FreeBSD$"); #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; #endif /* LIBC_SCCS and not lint */ #include "stand.h" #include int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ optopt, /* character checked for validity */ optreset; /* reset getopt */ char *optarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" /* * getopt -- * Parse argc/argv argument vector. */ int getopt(int nargc, char * const *nargv, const char *ostr) { static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (-1); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; return (-1); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, * assume it means -1. */ if (optopt == (int)'-') return (-1); if (!*place) ++optind; if (opterr && *ostr != ':') (void)printf("illegal option -- %c\n", optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; if (*ostr == ':') return (BADARG); if (opterr) (void)printf("option requires an argument -- %c\n", optopt); return (BADCH); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } return (optopt); /* dump back option letter */ } /* $NetBSD: gets.c,v 1.6 1995/10/11 21:16:57 pk Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)gets.c 8.1 (Berkeley) 6/11/93 */ #include #include "stand.h" /* gets() with constrained input length */ void ngets(char *buf, int n) { int c; char *lp; for (lp = buf; ; ) { c = getchar(); if (c == -1) break; switch (c & 0177) { case '\n': case '\r': *lp = '\0'; putchar('\n'); return; case '\b': case '\177': if (lp > buf) { lp--; putchar('\b'); putchar(' '); putchar('\b'); } break; case 'r' & 037: { char *p; putchar('\n'); for (p = buf; p < lp; ++p) putchar(*p); break; } case 'u' & 037: case 'w' & 037: lp = buf; putchar('\n'); break; default: if ((n < 1) || ((lp - buf) < n - 1)) { *lp++ = c; putchar(c); } } } /*NOTREACHED*/ } int fgetstr(char *buf, int size, int fd) { char c; int err, len; size--; /* leave space for terminator */ len = 0; while (size != 0) { err = read(fd, &c, sizeof (c)); if (err < 0) /* read error */ return (-1); if (err == 0) { /* EOF */ if (len == 0) return (-1); /* nothing to read */ break; } if ((c == '\r') || /* line terminators */ (c == '\n')) break; *buf++ = c; /* keep char */ size--; len++; } *buf = 0; return (len); } /* $NetBSD: globals.c,v 1.3 1995/09/18 21:19:27 pk Exp $ */ /* * globals.c: * * global variables should be separate, so nothing else * must be included extraneously. */ #include #include #include #include #include "stand.h" #include "net.h" u_char bcea[6] = BA; /* broadcast ethernet address */ char rootpath[FNAME_SIZE] = "/"; /* root mount path */ char bootfile[FNAME_SIZE]; /* bootp says to boot this */ char hostname[FNAME_SIZE]; /* our hostname */ int hostnamelen; char domainname[FNAME_SIZE]; /* our DNS domain */ int domainnamelen; int netproto = NET_NONE; /* Network prototol */ char ifname[IFNAME_SIZE]; /* name of interface (e.g. "le0") */ struct in_addr myip; /* my ip address */ struct in_addr nameip; /* DNS server ip address */ struct in_addr rootip; /* root ip address */ struct in_addr swapip; /* swap ip address */ struct in_addr gateip; /* gateway ip address */ n_long netmask = 0xffffff00; /* subnet or net mask */ u_int intf_mtu; /* interface mtu from bootp/dhcp */ int errno; /* our old friend */ /* * Copyright (c) 1998 Michael Smith. * All rights reserved. * * 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. * * 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. */ #include #include "stand.h" #include #include #include #define Z_BUFSIZE 16384 /* match NFSREAD_MAX_SIZE */ struct z_file { int zf_rawfd; off_t zf_dataoffset; z_stream zf_zstream; int zf_endseen; unsigned char zf_buf[Z_BUFSIZE]; }; static int zf_fill(struct z_file *z); static int zf_open(const char *path, struct open_file *f); static int zf_close(struct open_file *f); static int zf_read(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t zf_seek(struct open_file *f, off_t offset, int where); static int zf_stat(struct open_file *f, struct stat *sb); struct fs_ops gzipfs_fsops = { .fs_name = "zip", .fo_open = zf_open, .fo_close = zf_close, .fo_read = zf_read, .fo_write = null_write, .fo_seek = zf_seek, .fo_stat = zf_stat, .fo_readdir = null_readdir }; static int zf_fill(struct z_file *zf) { int result; int req; req = Z_BUFSIZE - zf->zf_zstream.avail_in; result = 0; /* If we need more */ if (req > 0) { /* move old data to bottom of buffer */ if (req < Z_BUFSIZE) bcopy(zf->zf_buf + req, zf->zf_buf, Z_BUFSIZE - req); /* read to fill buffer and update availibility data */ result = read(zf->zf_rawfd, zf->zf_buf + zf->zf_zstream.avail_in, req); zf->zf_zstream.next_in = zf->zf_buf; if (result >= 0) zf->zf_zstream.avail_in += result; } return (result); } /* * Adapted from get_byte/check_header in libz * * Returns 0 if the header is OK, nonzero if not. */ static int get_byte(struct z_file *zf, off_t *curoffp) { if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1)) return (-1); zf->zf_zstream.avail_in--; ++*curoffp; return (*(zf->zf_zstream.next_in)++); } static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ static int check_header(struct z_file *zf) { int method; /* method byte */ int flags; /* flags byte */ uInt len; int c; zf->zf_dataoffset = 0; /* Check the gzip magic header */ for (len = 0; len < 2; len++) { c = get_byte(zf, &zf->zf_dataoffset); if (c != gz_magic[len]) { return (1); } } method = get_byte(zf, &zf->zf_dataoffset); flags = get_byte(zf, &zf->zf_dataoffset); if (method != Z_DEFLATED || (flags & RESERVED) != 0) { return (1); } /* Discard time, xflags and OS code: */ for (len = 0; len < 6; len++) (void) get_byte(zf, &zf->zf_dataoffset); if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ len = (uInt)get_byte(zf, &zf->zf_dataoffset); len += ((uInt)get_byte(zf, &zf->zf_dataoffset))<<8; /* len is garbage if EOF but the loop below will quit anyway */ while (len-- != 0 && get_byte(zf, &zf->zf_dataoffset) != -1) ; } if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ while ((c = get_byte(zf, &zf->zf_dataoffset)) != 0 && c != -1) ; } if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ while ((c = get_byte(zf, &zf->zf_dataoffset)) != 0 && c != -1) ; } if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ for (len = 0; len < 2; len++) c = get_byte(zf, &zf->zf_dataoffset); } /* if there's data left, we're in business */ return ((c == -1) ? 1 : 0); } static int zf_open(const char *fname, struct open_file *f) { char *zfname; int rawfd; struct z_file *zf; char *cp; int error; struct stat sb; /* Have to be in "just read it" mode */ if (f->f_flags != F_READ) return (EPERM); /* If the name already ends in .gz or .bz2, ignore it */ if ((cp = strrchr(fname, '.')) && (strcmp(cp, ".gz") == 0 || strcmp(cp, ".bz2") == 0 || strcmp(cp, ".split") == 0)) return (ENOENT); /* Try to open the compressed datafile */ rawfd = open(fname, O_RDONLY | F_GZIP); if (rawfd == -1) { /* add .gz sufix and try again */ zfname = malloc(strlen(fname) + 4); if (zfname == NULL) return (ENOMEM); sprintf(zfname, "%s.gz", fname); rawfd = open(zfname, O_RDONLY); free(zfname); if (rawfd == -1) return (ENOENT); } if (fstat(rawfd, &sb) < 0) { printf("zf_open: stat failed\n"); close(rawfd); return (ENOENT); } if (!S_ISREG(sb.st_mode)) { close(rawfd); return (EISDIR); /* best guess */ } /* Allocate a z_file structure, populate it */ zf = malloc(sizeof (struct z_file)); if (zf == NULL) return (ENOMEM); bzero(zf, sizeof (struct z_file)); zf->zf_rawfd = rawfd; /* Verify that the file is gzipped */ if (check_header(zf)) { close(zf->zf_rawfd); free(zf); return (EFTYPE); } /* Initialise the inflation engine */ if ((error = inflateInit2(&(zf->zf_zstream), -15)) != Z_OK) { printf("zf_open: inflateInit returned %d : %s\n", error, zf->zf_zstream.msg); close(zf->zf_rawfd); free(zf); return (EIO); } /* Looks OK, we'll take it */ f->f_fsdata = zf; return (0); } static int zf_close(struct open_file *f) { struct z_file *zf = (struct z_file *)f->f_fsdata; inflateEnd(&(zf->zf_zstream)); close(zf->zf_rawfd); free(zf); return (0); } static int zf_read(struct open_file *f, void *buf, size_t size, size_t *resid) { struct z_file *zf = (struct z_file *)f->f_fsdata; int error; zf->zf_zstream.next_out = buf; /* where and how much */ zf->zf_zstream.avail_out = size; while (zf->zf_zstream.avail_out && zf->zf_endseen == 0) { if ((zf->zf_zstream.avail_in == 0) && (zf_fill(zf) == -1)) { printf("zf_read: fill error\n"); return (EIO); } if (zf->zf_zstream.avail_in == 0) { /* oops, unexpected EOF */ printf("zf_read: unexpected EOF\n"); if (zf->zf_zstream.avail_out == size) return (EIO); break; } /* decompression pass */ error = inflate(&zf->zf_zstream, Z_SYNC_FLUSH); if (error == Z_STREAM_END) { /* EOF, all done */ zf->zf_endseen = 1; break; } if (error != Z_OK) { /* argh, decompression error */ printf("inflate: %s\n", zf->zf_zstream.msg); return (EIO); } } if (resid != NULL) *resid = zf->zf_zstream.avail_out; return (0); } static int zf_rewind(struct open_file *f) { struct z_file *zf = (struct z_file *)f->f_fsdata; if (lseek(zf->zf_rawfd, zf->zf_dataoffset, SEEK_SET) == -1) return (-1); zf->zf_zstream.avail_in = 0; zf->zf_zstream.next_in = NULL; zf->zf_endseen = 0; (void) inflateReset(&zf->zf_zstream); return (0); } static off_t zf_seek(struct open_file *f, off_t offset, int where) { struct z_file *zf = (struct z_file *)f->f_fsdata; off_t target; char discard[16]; switch (where) { case SEEK_SET: target = offset; break; case SEEK_CUR: target = offset + zf->zf_zstream.total_out; break; default: errno = EINVAL; return (-1); } /* rewind if required */ if (target < zf->zf_zstream.total_out && zf_rewind(f) != 0) return (-1); /* skip forwards if required */ while (target > zf->zf_zstream.total_out) { errno = zf_read(f, discard, min(sizeof (discard), target - zf->zf_zstream.total_out), NULL); if (errno != 0) return (-1); } /* This is where we are (be honest if we overshot) */ return (zf->zf_zstream.total_out); } static int zf_stat(struct open_file *f, struct stat *sb) { struct z_file *zf = (struct z_file *)f->f_fsdata; int result; off_t pos1, pos2; uint32_t size; /* stat as normal, but indicate that size is unknown */ if ((result = fstat(zf->zf_rawfd, sb)) == 0) { if (sb->st_size == -1) return (result); pos1 = lseek(zf->zf_rawfd, 0, SEEK_CUR); pos2 = lseek(zf->zf_rawfd, sb->st_size - 4, SEEK_SET); if (pos2 != -1) { if (read(zf->zf_rawfd, &size, 4) == 4) sb->st_size = (off_t)size; else sb->st_size = -1; } else sb->st_size = -1; pos1 = lseek(zf->zf_rawfd, pos1, SEEK_SET); } return (result); } /* $NetBSD: in_cksum.c,v 1.6 2000/03/31 19:55:09 castor Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: in_cksum.c,v 1.1 92/09/11 01:15:55 leres Exp (LBL) */ #include #include #include #include "stand.h" /* * Checksum routine for Internet Protocol family headers. * This routine is very heavily used in the network * code and should be modified for each CPU to be as fast as possible. * In particular, it should not be this one. */ int in_cksum(void *p, int len) { int sum = 0, oddbyte = 0, v = 0; uchar_t *cp = p; /* we assume < 2^16 bytes being summed */ while (len > 0) { if (oddbyte) { sum += v + *cp++; len--; } if (((long)cp & 1) == 0) { while ((len -= 2) >= 0) { sum += *(ushort_t *)cp; cp += 2; } } else { while ((len -= 2) >= 0) { #if BYTE_ORDER == BIG_ENDIAN sum += *cp++ << 8; sum += *cp++; #else sum += *cp++; sum += *cp++ << 8; #endif } } if ((oddbyte = len & 1) != 0) #if BYTE_ORDER == BIG_ENDIAN v = *cp << 8; #else v = *cp; #endif } if (oddbyte) sum += v; sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */ sum += sum >> 16; /* add potential last carry */ return (0xffff & ~sum); } /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include #include #include #include #include "stand.h" /* * Convert network-format internet address * to base 256 d.d.d.d representation. */ char * inet_ntoa(struct in_addr in) { static const char fmt[] = "%u.%u.%u.%u"; static char ret[sizeof ("255.255.255.255")]; unsigned char *src = (unsigned char *) ∈ sprintf(ret, fmt, src[0], src[1], src[2], src[3]); return (ret); } /* * Weak aliases for applications that use certain private entry points, * and fail to include . */ #undef inet_ntoa __weak_reference(__inet_ntoa, inet_ntoa); /* $NetBSD: ioctl.c,v 1.4 1994/10/30 21:48:24 cgd Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * Copyright 2024 MNX Cloud, Inc. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ioctl.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include "stand.h" int ioctl(int fd, ulong_t cmd, char *arg) { struct open_file *f; f = fd2open_file(fd); if (f == NULL || f->f_flags == 0) { errno = EBADF; return (-1); } if (f->f_dev == NULL) errno = EIO; else errno = (f->f_dev->dv_ioctl)(f, cmd, arg); if (errno != 0) return (-1); return (0); } /* $NetBSD: iodesc.h,v 1.4 1995/09/23 03:31:50 gwr Exp $ */ /* * Copyright (c) 1993 Adam Glass * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ #ifndef __SYS_LIBNETBOOT_IODESC_H #define __SYS_LIBNETBOOT_IODESC_H struct iodesc { struct in_addr destip; /* dest. ip addr, net order */ struct in_addr myip; /* local ip addr, net order */ u_short destport; /* dest. port, net order */ u_short myport; /* local port, net order */ u_long xid; /* transaction identification */ u_char myea[6]; /* my ethernet address */ struct netif *io_netif; int io_id; /* descriptor id */ TAILQ_ENTRY(iodesc) io_link; /* next entry in list */ }; #endif /* __SYS_LIBNETBOOT_IODESC_H */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ /* * The send and receive functions were originally implemented in udp.c and * moved here. Also it is likely some more cleanup can be done, especially * once we will implement the support for tcp. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" typedef STAILQ_HEAD(ipqueue, ip_queue) ip_queue_t; struct ip_queue { void *ipq_pkt; struct ip *ipq_hdr; STAILQ_ENTRY(ip_queue) ipq_next; }; /* * Fragment re-assembly queue. */ struct ip_reasm { struct in_addr ip_src; struct in_addr ip_dst; uint16_t ip_id; uint8_t ip_proto; uint8_t ip_ttl; size_t ip_total_size; ip_queue_t ip_queue; void *ip_pkt; struct ip *ip_hdr; STAILQ_ENTRY(ip_reasm) ip_next; }; STAILQ_HEAD(ire_list, ip_reasm) ire_list = STAILQ_HEAD_INITIALIZER(ire_list); /* Caller must leave room for ethernet and ip headers in front!! */ ssize_t sendip(struct iodesc *d, void *pkt, size_t len, uint8_t proto) { ssize_t cc; struct ip *ip; uchar_t *ea; #ifdef NET_DEBUG if (debug) { printf("sendip: proto: %x d=%p called.\n", proto, (void *)d); printf("saddr: %s:%d daddr: %s:%d\n", inet_ntoa(d->myip), ntohs(d->myport), inet_ntoa(d->destip), ntohs(d->destport)); } #endif ip = (struct ip *)pkt - 1; len += sizeof (*ip); bzero(ip, sizeof (*ip)); ip->ip_v = IPVERSION; /* half-char */ ip->ip_hl = sizeof (*ip) >> 2; /* half-char */ ip->ip_len = htons(len); ip->ip_p = proto; /* char */ ip->ip_ttl = IPDEFTTL; /* char */ ip->ip_src = d->myip; ip->ip_dst = d->destip; ip->ip_sum = in_cksum(ip, sizeof (*ip)); /* short, but special */ if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 || netmask == 0 || SAMENET(ip->ip_src, ip->ip_dst, netmask)) ea = arpwhohas(d, ip->ip_dst); else ea = arpwhohas(d, gateip); cc = sendether(d, ip, len, ea, ETHERTYPE_IP); if (cc == -1) return (-1); if (cc != len) panic("sendip: bad write (%zd != %zd)", cc, len); return (cc - sizeof (*ip)); } static void ip_reasm_free(struct ip_reasm *ipr) { struct ip_queue *ipq; while ((ipq = STAILQ_FIRST(&ipr->ip_queue)) != NULL) { STAILQ_REMOVE_HEAD(&ipr->ip_queue, ipq_next); free(ipq->ipq_pkt); free(ipq); } free(ipr->ip_pkt); free(ipr); } static bool ip_reasm_add(struct ip_reasm *ipr, void *pkt, struct ip *ip) { struct ip_queue *ipq, *p; uint16_t off_q, off_ip; if ((ipq = calloc(1, sizeof (*ipq))) == NULL) return (false); ipq->ipq_pkt = pkt; ipq->ipq_hdr = ip; STAILQ_FOREACH(p, &ipr->ip_queue, ipq_next) { off_q = ntohs(p->ipq_hdr->ip_off) & IP_OFFMASK; off_ip = ntohs(ip->ip_off) & IP_OFFMASK; if (off_q == off_ip) { /* duplicate */ free(pkt); free(ipq); return (true); } if (off_ip < off_q) { /* * Everything in queue has larger offset, * drop out of loop and insert to HEAD. */ break; } /* * p in queue is smaller than ip, check if we need to put * ip after p or after p->next. */ struct ip_queue *next = STAILQ_NEXT(p, ipq_next); if (next == NULL) { /* insert after p */ STAILQ_INSERT_AFTER(&ipr->ip_queue, p, ipq, ipq_next); return (true); } off_q = ntohs(next->ipq_hdr->ip_off) & IP_OFFMASK; if (off_ip < off_q) { /* next fragment offset is larger, insert after p. */ STAILQ_INSERT_AFTER(&ipr->ip_queue, p, ipq, ipq_next); return (true); } /* next fragment offset is smaller, loop */ } STAILQ_INSERT_HEAD(&ipr->ip_queue, ipq, ipq_next); return (true); } /* * Receive a IP packet and validate it is for us. */ static ssize_t readipv4(struct iodesc *d, void **pkt, void **payload, ssize_t n) { struct ip *ip = *payload; size_t hlen; struct ether_header *eh; struct udphdr *uh; char *ptr = *pkt; struct ip_reasm *ipr; struct ip_queue *ipq, *last; bool morefrag, isfrag; uint16_t fragoffset; if (n < sizeof (*ip)) { free(ptr); errno = EAGAIN; /* Call me again. */ return (-1); } hlen = ip->ip_hl << 2; if (hlen < sizeof (*ip) || in_cksum(ip, hlen) != 0) { #ifdef NET_DEBUG if (debug) printf("%s: short hdr or bad cksum.\n", __func__); #endif free(ptr); errno = EAGAIN; /* Call me again. */ return (-1); } if (n < ntohs(ip->ip_len)) { #ifdef NET_DEBUG if (debug) { printf("readip: bad length %dz < %d.\n", n, ntohs(ip->ip_len)); } #endif free(ptr); errno = EAGAIN; /* Call me again. */ return (-1); } fragoffset = (ntohs(ip->ip_off) & IP_OFFMASK) * 8; morefrag = (ntohs(ip->ip_off) & IP_MF) == 0 ? false : true; isfrag = morefrag || fragoffset != 0; uh = (struct udphdr *)((uintptr_t)ip + sizeof (*ip)); if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { #ifdef NET_DEBUG if (debug) { printf("%s: not for us: saddr %s (%d) != %s (%d)\n", __func__, inet_ntoa(d->myip), ntohs(d->myport), inet_ntoa(ip->ip_dst), ntohs(uh->uh_dport)); } #endif free(ptr); errno = EAGAIN; /* Call me again. */ return (-1); } /* Unfragmented packet. */ if (!isfrag) { #ifdef NET_DEBUG if (debug) { printf("%s: unfragmented saddr %s:%d -> ", __func__, inet_ntoa(ip->ip_src), ntohs(uh->uh_sport)); printf("%s:%d\n", inet_ntoa(ip->ip_dst), ntohs(uh->uh_dport)); } #endif /* If there were ip options, make them go away */ if (hlen != sizeof (*ip)) { bcopy(((uchar_t *)ip) + hlen, uh, ntohs(uh->uh_ulen) - hlen); ip->ip_len = htons(sizeof (*ip)); n -= hlen - sizeof (*ip); } n = (n > (ntohs(ip->ip_len) - sizeof (*ip))) ? ntohs(ip->ip_len) - sizeof (*ip) : n; *pkt = ptr; *payload = (void *)((uintptr_t)ip + sizeof (*ip)); return (n); } STAILQ_FOREACH(ipr, &ire_list, ip_next) { if (ipr->ip_src.s_addr == ip->ip_src.s_addr && ipr->ip_dst.s_addr == ip->ip_dst.s_addr && ipr->ip_id == ip->ip_id && ipr->ip_proto == ip->ip_p) break; } /* Allocate new reassembly entry */ if (ipr == NULL) { if ((ipr = calloc(1, sizeof (*ipr))) == NULL) { free(ptr); return (-1); } ipr->ip_src = ip->ip_src; ipr->ip_dst = ip->ip_dst; ipr->ip_id = ip->ip_id; ipr->ip_proto = ip->ip_p; ipr->ip_ttl = MAXTTL; STAILQ_INIT(&ipr->ip_queue); STAILQ_INSERT_TAIL(&ire_list, ipr, ip_next); #ifdef NET_DEBUG if (debug) { printf("%s: new reassembly ID=%d %s -> ", __func__, ntohs(ip->ip_id), inet_ntoa(ip->ip_src)); printf("%s\n", inet_ntoa(ip->ip_dst)); } #endif } /* * NOTE: with ip_reasm_add() ptr will be stored in reassembly * queue and we can not free it without destroying the queue. */ if (!ip_reasm_add(ipr, ptr, ip)) { STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); free(ipr); free(ptr); return (-1); } /* * Walk the packet list in reassembly queue, if we got all the * fragments, build the packet. */ n = 0; last = NULL; STAILQ_FOREACH(ipq, &ipr->ip_queue, ipq_next) { fragoffset = (ntohs(ipq->ipq_hdr->ip_off) & IP_OFFMASK) * 8; if (fragoffset != n) { #ifdef NET_DEBUG if (debug) { printf("%s: need more fragments %d %s -> ", __func__, ntohs(ipq->ipq_hdr->ip_id), inet_ntoa(ipq->ipq_hdr->ip_src)); printf("%s offset=%d MF=%d\n", inet_ntoa(ipq->ipq_hdr->ip_dst), fragoffset, (ntohs(ipq->ipq_hdr->ip_off) & IP_MF) != 0); } #endif errno = EAGAIN; return (-1); } n += ntohs(ipq->ipq_hdr->ip_len) - (ipq->ipq_hdr->ip_hl << 2); last = ipq; } /* complete queue has last packet with MF 0 */ if ((ntohs(last->ipq_hdr->ip_off) & IP_MF) != 0) { #ifdef NET_DEBUG if (debug) { printf("%s: need more fragments %d %s -> ", __func__, ntohs(last->ipq_hdr->ip_id), inet_ntoa(last->ipq_hdr->ip_src)); printf("%s offset=%d MF=%d\n", inet_ntoa(last->ipq_hdr->ip_dst), (ntohs(last->ipq_hdr->ip_off) & IP_OFFMASK) * 8, (ntohs(last->ipq_hdr->ip_off) & IP_MF) != 0); } #endif errno = EAGAIN; return (-1); } ipr->ip_total_size = n + sizeof (*ip) + sizeof (struct ether_header); ipr->ip_pkt = malloc(ipr->ip_total_size + 2); if (ipr->ip_pkt == NULL) { STAILQ_REMOVE(&ire_list, ipr, ip_reasm, ip_next); ip_reasm_free(ipr); return (-1); } ipq = STAILQ_FIRST(&ipr->ip_queue); /* Fabricate ethernet header */ eh = (struct ether_header *)((uintptr_t)ipr->ip_pkt + 2); bcopy((void *)((uintptr_t)ipq->ipq_pkt + 2), eh, sizeof (*eh)); /* Fabricate IP header */ ipr->ip_hdr = (struct ip *)((uintptr_t)eh + sizeof (*eh)); bcopy(ipq->ipq_hdr, ipr->ip_hdr, sizeof (*ipr->ip_hdr)); ipr->ip_hdr->ip_hl = sizeof (*ipr->ip_hdr) >> 2; ipr->ip_hdr->ip_len = htons(n); ipr->ip_hdr->ip_sum = 0; ipr->ip_hdr->ip_sum = in_cksum(ipr->ip_hdr, sizeof (*ipr->ip_hdr)); n = 0; ptr = (char *)((uintptr_t)ipr->ip_hdr + sizeof (*ipr->ip_hdr)); STAILQ_FOREACH(ipq, &ipr->ip_queue, ipq_next) { char *data; size_t len; hlen = ipq->ipq_hdr->ip_hl << 2; len = ntohs(ipq->ipq_hdr->ip_len) - hlen; data = (char *)((uintptr_t)ipq->ipq_hdr + hlen); bcopy(data, ptr + n, len); n += len; } *pkt = ipr->ip_pkt; ipr->ip_pkt = NULL; /* Avoid free from ip_reasm_free() */ *payload = ptr; /* Clean up the reassembly list */ while ((ipr = STAILQ_FIRST(&ire_list)) != NULL) { STAILQ_REMOVE_HEAD(&ire_list, ip_next); ip_reasm_free(ipr); } #ifdef NET_DEBUG if (debug) { printf("%s: completed fragments ID=%d %s -> %s\n", __func__, ntohs(ip->ip_id), inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)); } #endif return (n); } /* * Receive a IP packet. */ ssize_t readip(struct iodesc *d, void **pkt, void **payload, time_t tleft, uint8_t proto) { time_t t; ssize_t ret = -1; t = getsecs(); while ((getsecs() - t) < tleft) { ssize_t n; uint16_t etype; /* host order */ void *ptr = NULL; void *data = NULL; errno = 0; n = readether(d, &ptr, &data, tleft, &etype); if (n == -1) { free(ptr); continue; } /* Ethernet address checks are done in readether() */ /* Need to respond to ARP requests. */ if (etype == ETHERTYPE_ARP) { struct arphdr *ah = data; #ifdef NET_DEBUG if (debug) printf("%s: ARP request\n", __func__); #endif if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); } free(ptr); continue; /* Get next packet */ } if (etype == ETHERTYPE_IP) { struct ip *ip = data; if (ip->ip_v == IPVERSION && /* half char */ ip->ip_p == proto) { errno = 0; ret = readipv4(d, &ptr, &data, n); if (ret >= 0) { *pkt = ptr; *payload = data; return (ret); } /* * Bubble up the error if it wasn't successful */ if (errno != EAGAIN) return (-1); continue; } #ifdef NET_DEBUG if (debug) { printf("%s: IP version or proto. " "ip_v=%d ip_p=%d\n", __func__, ip->ip_v, ip->ip_p); } #endif free(ptr); continue; } free(ptr); } /* We've exhausted tleft; timeout */ errno = ETIMEDOUT; #ifdef NET_DEBUG if (debug) { printf("%s: timeout\n", __func__); } #endif return (-1); } /* $NetBSD: lseek.c,v 1.4 1997/01/22 00:38:10 cgd Exp $ */ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)lseek.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include "stand.h" off_t lseek(int fd, off_t offset, int where) { off_t bufpos, filepos, target; struct open_file *f; f = fd2open_file(fd); if (f == NULL || f->f_flags == 0) { errno = EBADF; return (-1); } if (f->f_flags & F_RAW) { /* * On RAW devices, update internal offset. */ switch (where) { case SEEK_SET: f->f_offset = offset; break; case SEEK_CUR: f->f_offset += offset; break; default: errno = EOFFSET; return (-1); } return (f->f_offset); } /* * If there is some unconsumed data in the readahead buffer and it * contains the desired offset, simply adjust the buffer offset and * length. We don't bother with SEEK_END here, since the code to * handle it would fail in the same cases where the non-readahead * code fails (namely, for streams which cannot seek backward and whose * size isn't known in advance). */ if (f->f_ralen != 0 && where != SEEK_END) { filepos = (f->f_ops->fo_seek)(f, 0, SEEK_CUR); if (filepos == -1) return (-1); bufpos = filepos - f->f_ralen; switch (where) { case SEEK_SET: target = offset; break; case SEEK_CUR: target = bufpos + offset; break; default: errno = EINVAL; return (-1); } if (bufpos <= target && target < filepos) { f->f_raoffset += target - bufpos; f->f_ralen -= target - bufpos; return (target); } } /* * If this is a relative seek, we need to correct the offset for * bytes that we have already read but the caller doesn't know * about. */ if (where == SEEK_CUR) offset -= f->f_ralen; /* * Invalidate the readahead buffer. */ f->f_ralen = 0; return (f->f_ops->fo_seek)(f, offset, where); } /* $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ #include #include #include #include #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" /* * Maximum wait time for sending and receiving before we give up and timeout. * If set to 0, operations will eventually timeout completely, but send/recv * timeouts must progress exponentially from MINTMO to MAXTMO before final * timeout is hit. */ #ifndef MAXWAIT #define MAXWAIT 0 /* seconds */ #endif #if MAXWAIT < 0 #error MAXWAIT must not be a negative number #endif /* * Send a packet and wait for a reply, with exponential backoff. * * The send routine must return the actual number of bytes written, * or -1 on error. * * The receive routine can indicate success by returning the number of * bytes read; it can return 0 to indicate EOF; it can return -1 with a * non-zero errno to indicate failure; finally, it can return -1 with a * zero errno to indicate it isn't done yet. */ ssize_t sendrecv(struct iodesc *d, ssize_t (*sproc)(struct iodesc *, void *, size_t), void *sbuf, size_t ssize, ssize_t (*rproc)(struct iodesc *, void **, void**, time_t, void *), void **pkt, void **payload, void *recv_extra) { ssize_t cc; time_t t, tmo, tlast; time_t tref; long tleft; #ifdef NET_DEBUG if (debug) printf("sendrecv: called\n"); #endif tmo = MINTMO; tlast = 0; tleft = 0; tref = getsecs(); t = getsecs(); for (;;) { if (MAXWAIT > 0 && (getsecs() - tref) >= MAXWAIT) { errno = ETIMEDOUT; return (-1); } if (tleft <= 0) { if (tmo >= MAXTMO) { errno = ETIMEDOUT; return (-1); } cc = (*sproc)(d, sbuf, ssize); if (cc != -1 && cc < ssize) panic("sendrecv: short write! (%zd < %zd)", cc, ssize); tleft = tmo; tmo += MINTMO; if (tmo > MAXTMO) tmo = MAXTMO; if (cc == -1) { /* Error on transmit; wait before retrying */ while ((getsecs() - t) < tmo) ; tleft = 0; continue; } tlast = t; } /* Try to get a packet and process it. */ cc = (*rproc)(d, pkt, payload, tleft, recv_extra); /* Return on data, EOF or real error. */ if (cc != -1 || (errno != 0 && errno != ETIMEDOUT)) return (cc); /* Timed out or didn't get the packet we're waiting for */ t = getsecs(); tleft -= t - tlast; tlast = t; } } /* * Like inet_addr() in the C library, but we only accept base-10. * Return values are in network order. */ n_long inet_addr(char *cp) { unsigned long val; int n; char c; unsigned int parts[4]; unsigned int *pp = parts; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, other=decimal. */ val = 0; while ((c = *cp) != '\0') { if (c >= '0' && c <= '9') { val = (val * 10) + (c - '0'); cp++; continue; } break; } if (*cp == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16-bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3 || val > 0xff) goto bad; *pp++ = val, cp++; } else break; } /* * Check for trailing characters. */ if (*cp != '\0') goto bad; /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffff) goto bad; val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffff) goto bad; val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xff) goto bad; val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } return (htonl(val)); bad: return (htonl(INADDR_NONE)); } char * inet_ntoa(struct in_addr ia) { return (intoa(ia.s_addr)); } /* Similar to inet_ntoa() */ char * intoa(n_long addr) { char *cp; unsigned int byte; int n; static char buf[17]; /* strlen(".255.255.255.255") + 1 */ addr = ntohl(addr); cp = &buf[sizeof (buf)]; *--cp = '\0'; n = 4; do { byte = addr & 0xff; *--cp = byte % 10 + '0'; byte /= 10; if (byte > 0) { *--cp = byte % 10 + '0'; byte /= 10; if (byte > 0) *--cp = byte + '0'; } *--cp = '.'; addr >>= 8; } while (--n > 0); return (cp+1); } static char * number(char *s, uint32_t *n) { for (*n = 0; isdigit(*s); s++) *n = (*n * 10) + *s - '0'; return (s); } n_long ip_convertaddr(char *p) { #define IP_ANYADDR 0 uint32_t addr = 0, n; if (p == NULL || *p == '\0') return (IP_ANYADDR); p = number(p, &n); addr |= (n << 24) & 0xff000000; if (*p == '\0' || *p++ != '.') return (IP_ANYADDR); p = number(p, &n); addr |= (n << 16) & 0xff0000; if (*p == '\0' || *p++ != '.') return (IP_ANYADDR); p = number(p, &n); addr |= (n << 8) & 0xff00; if (*p == '\0' || *p++ != '.') return (IP_ANYADDR); p = number(p, &n); addr |= n & 0xff; if (*p != '\0') return (IP_ANYADDR); return (htonl(addr)); } /* * Copyright (c) 1993 Adam Glass * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _STAND_NET_H #define _STAND_NET_H #ifndef _KERNEL /* XXX - see */ #undef __IPADDR #define __IPADDR(x) htonl((u_int32_t)(x)) #endif #include "iodesc.h" #define BA { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } enum net_proto { NET_NONE, NET_NFS, NET_TFTP }; /* Returns true if n_long's on the same net */ #define SAMENET(a1, a2, m) ((a1.s_addr & m) == (a2.s_addr & m)) #define MACPY(s, d) bcopy((char *)s, (char *)d, 6) #define MAXTMO 120 /* seconds */ #define MINTMO 2 /* seconds */ #define FNAME_SIZE 128 #define IFNAME_SIZE 16 #define RECV_SIZE 1536 /* XXX delete this */ /* * How much room to leave for headers: * 14: struct ether_header * 20: struct ip * 8: struct udphdr * That's 42 but let's pad it out to 48 bytes. */ #define ETHER_SIZE 14 #define HEADER_SIZE 48 extern u_char bcea[6]; extern char rootpath[FNAME_SIZE]; extern char bootfile[FNAME_SIZE]; extern char hostname[FNAME_SIZE]; extern int hostnamelen; extern char domainname[FNAME_SIZE]; extern int domainnamelen; extern int netproto; extern char ifname[IFNAME_SIZE]; /* All of these are in network order. */ extern struct in_addr myip; extern struct in_addr rootip; extern struct in_addr swapip; extern struct in_addr gateip; extern struct in_addr nameip; extern struct in_addr tftpip; extern n_long netmask; extern u_int intf_mtu; extern int debug; /* defined in the machdep sources */ /* ARP/RevARP functions: */ u_char *arpwhohas(struct iodesc *, struct in_addr); void arp_reply(struct iodesc *, void *); int rarp_getipaddress(int); /* Link functions: */ ssize_t sendether(struct iodesc *d, void *pkt, size_t len, u_char *dea, int etype); ssize_t readether(struct iodesc *, void **, void **, time_t, u_int16_t *); ssize_t sendip(struct iodesc *, void *, size_t, uint8_t); ssize_t readip(struct iodesc *, void **, void **, time_t, uint8_t); ssize_t sendudp(struct iodesc *, void *, size_t); ssize_t readudp(struct iodesc *, void **, void **, time_t); ssize_t sendrecv(struct iodesc *, ssize_t (*)(struct iodesc *, void *, size_t), void *, size_t, ssize_t (*)(struct iodesc *, void **, void **, time_t, void *), void **, void **, void *); /* bootp/DHCP */ void bootp(int); /* Utilities: */ char *ether_sprintf(u_char *); int in_cksum(void *, int); char *inet_ntoa(struct in_addr); char *intoa(n_long); /* similar to inet_ntoa */ n_long inet_addr(char *); #endif /* ! _STAND_NET_H */ /* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */ /* * Copyright (c) 1993 Adam Glass * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Adam Glass. * 4. 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 Adam Glass ``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 REGENTS 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. */ #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" #include "netif.h" typedef TAILQ_HEAD(socket_list, iodesc) socket_list_t; /* * Open socket list. The current implementation and assumption is, * we only remove entries from tail and we only add new entries to tail. * This decision is to keep iodesc id management simple - we get list * entries ordered by continiously growing io_id field. * If we do have multiple sockets open and we do close socket not from tail, * this entry will be marked unused. netif_open() will reuse unused entry, or * netif_close() will free all unused tail entries. */ static socket_list_t sockets = TAILQ_HEAD_INITIALIZER(sockets); #ifdef NETIF_DEBUG int netif_debug = 0; #endif /* * netif_init: * * initialize the generic network interface layer */ void netif_init(void) { struct netif_driver *drv; int d, i; #ifdef NETIF_DEBUG if (netif_debug) printf("netif_init: called\n"); #endif for (d = 0; netif_drivers[d]; d++) { drv = netif_drivers[d]; for (i = 0; i < drv->netif_nifs; i++) drv->netif_ifs[i].dif_used = 0; } } int netif_match(struct netif *nif, void *machdep_hint) { struct netif_driver *drv = nif->nif_driver; #if NETIF_DEBUG if (netif_debug) printf("%s%d: netif_match (%d)\n", drv->netif_bname, nif->nif_unit, nif->nif_sel); #endif return (drv->netif_match(nif, machdep_hint)); } struct netif * netif_select(void *machdep_hint) { int d, u, s; struct netif_driver *drv; struct netif cur_if; static struct netif best_if; int best_val; int val; best_val = 0; best_if.nif_driver = NULL; for (d = 0; netif_drivers[d] != NULL; d++) { cur_if.nif_driver = netif_drivers[d]; drv = cur_if.nif_driver; for (u = 0; u < drv->netif_nifs; u++) { cur_if.nif_unit = u; #ifdef NETIF_DEBUG if (netif_debug) printf("\t%s%d:", drv->netif_bname, cur_if.nif_unit); #endif for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { cur_if.nif_sel = s; if (drv->netif_ifs[u].dif_used & (1 << s)) { #ifdef NETIF_DEBUG if (netif_debug) printf(" [%d used]", s); #endif continue; } val = netif_match(&cur_if, machdep_hint); #ifdef NETIF_DEBUG if (netif_debug) printf(" [%d -> %d]", s, val); #endif if (val > best_val) { best_val = val; best_if = cur_if; } } #ifdef NETIF_DEBUG if (netif_debug) printf("\n"); #endif } } if (best_if.nif_driver == NULL) return (NULL); best_if.nif_driver-> netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); #ifdef NETIF_DEBUG if (netif_debug) printf("netif_select: %s%d(%d) wins\n", best_if.nif_driver->netif_bname, best_if.nif_unit, best_if.nif_sel); #endif return (&best_if); } int netif_probe(struct netif *nif, void *machdep_hint) { struct netif_driver *drv = nif->nif_driver; #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); #endif return (drv->netif_probe(nif, machdep_hint)); } void netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint) { struct netif_driver *drv = nif->nif_driver; #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); #endif desc->io_netif = nif; #ifdef PARANOID if (drv->netif_init == NULL) panic("%s%d: no netif_init support", drv->netif_bname, nif->nif_unit); #endif drv->netif_init(desc, machdep_hint); bzero(drv->netif_ifs[nif->nif_unit].dif_stats, sizeof (struct netif_stats)); } void netif_detach(struct netif *nif) { struct netif_driver *drv = nif->nif_driver; #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); #endif #ifdef PARANOID if (drv->netif_end == NULL) panic("%s%d: no netif_end support", drv->netif_bname, nif->nif_unit); #endif drv->netif_end(nif); } ssize_t netif_get(struct iodesc *desc, void **pkt, time_t timo) { #ifdef NETIF_DEBUG struct netif *nif = desc->io_netif; #endif struct netif_driver *drv = desc->io_netif->nif_driver; ssize_t rv; #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); #endif #ifdef PARANOID if (drv->netif_get == NULL) panic("%s%d: no netif_get support", drv->netif_bname, nif->nif_unit); #endif rv = drv->netif_get(desc, pkt, timo); #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_get returning %d\n", drv->netif_bname, nif->nif_unit, (int)rv); #endif return (rv); } ssize_t netif_put(struct iodesc *desc, void *pkt, size_t len) { #ifdef NETIF_DEBUG struct netif *nif = desc->io_netif; #endif struct netif_driver *drv = desc->io_netif->nif_driver; ssize_t rv; #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); #endif #ifdef PARANOID if (drv->netif_put == NULL) panic("%s%d: no netif_put support", drv->netif_bname, nif->nif_unit); #endif rv = drv->netif_put(desc, pkt, len); #ifdef NETIF_DEBUG if (netif_debug) printf("%s%d: netif_put returning %d\n", drv->netif_bname, nif->nif_unit, (int)rv); #endif return (rv); } /* * socktodesc_impl: * * Walk socket list and return pointer to iodesc structure. * if id is < 0, return first unused iodesc. */ static struct iodesc * socktodesc_impl(int socket) { struct iodesc *s; TAILQ_FOREACH(s, &sockets, io_link) { /* search by socket id */ if (socket >= 0) { if (s->io_id == socket) break; continue; } /* search for first unused entry */ if (s->io_netif == NULL) break; } return (s); } struct iodesc * socktodesc(int sock) { struct iodesc *desc; if (sock < 0) desc = NULL; else desc = socktodesc_impl(sock); if (desc == NULL) errno = EBADF; return (desc); } int netif_open(void *machdep_hint) { struct iodesc *s; struct netif *nif; /* find a free socket */ s = socktodesc_impl(-1); if (s == NULL) { struct iodesc *last; s = calloc(1, sizeof (*s)); if (s == NULL) return (-1); last = TAILQ_LAST(&sockets, socket_list); if (last != NULL) s->io_id = last->io_id + 1; TAILQ_INSERT_TAIL(&sockets, s, io_link); } netif_init(); nif = netif_select(machdep_hint); if (!nif) panic("netboot: no interfaces left untried"); if (netif_probe(nif, machdep_hint)) { printf("netboot: couldn't probe %s%d\n", nif->nif_driver->netif_bname, nif->nif_unit); errno = EINVAL; return (-1); } netif_attach(nif, s, machdep_hint); return (s->io_id); } int netif_close(int sock) { struct iodesc *s, *last; int err; err = 0; s = socktodesc_impl(sock); if (s == NULL || sock < 0) { err = EBADF; return (-1); } netif_detach(s->io_netif); bzero(&s->destip, sizeof (s->destip)); bzero(&s->myip, sizeof (s->myip)); s->destport = 0; s->myport = 0; s->xid = 0; bzero(s->myea, sizeof (s->myea)); s->io_netif = NULL; /* free unused entries from tail. */ TAILQ_FOREACH_REVERSE_SAFE(last, &sockets, socket_list, io_link, s) { if (last->io_netif != NULL) break; TAILQ_REMOVE(&sockets, last, io_link); free(last); } if (err) { errno = err; return (-1); } return (0); } /* $NetBSD: netif.h,v 1.4 1995/09/14 23:45:30 pk Exp $ */ /* $FreeBSD$ */ #ifndef __SYS_LIBNETBOOT_NETIF_H #define __SYS_LIBNETBOOT_NETIF_H #include "iodesc.h" struct netif_driver { const char *netif_bname; int (*netif_match)(struct netif *, void *); int (*netif_probe)(struct netif *, void *); void (*netif_init)(struct iodesc *, void *); ssize_t (*netif_get)(struct iodesc *, void **, time_t); ssize_t (*netif_put)(struct iodesc *, void *, size_t); void (*netif_end)(struct netif *); struct netif_dif *netif_ifs; int netif_nifs; }; struct netif_dif { int dif_unit; int dif_nsel; struct netif_stats *dif_stats; void *dif_private; /* the following fields are used internally by the netif layer */ u_long dif_used; }; struct netif_stats { int collisions; int collision_error; int missed; int sent; int received; int deferred; int overflow; }; struct netif { struct netif_driver *nif_driver; int nif_unit; int nif_sel; void *nif_devdata; }; extern struct netif_driver *netif_drivers[]; /* machdep */ extern int n_netif_drivers; extern int netif_debug; void netif_init(void); struct netif *netif_select(void *); int netif_probe(struct netif *, void *); void netif_attach(struct netif *, struct iodesc *, void *); void netif_detach(struct netif *); ssize_t netif_get(struct iodesc *, void **, time_t); ssize_t netif_put(struct iodesc *, void *, size_t); int netif_open(void *); int netif_close(int); struct iodesc *socktodesc(int); #endif /* __SYS_LIBNETBOOT_NETIF_H */ /* $NetBSD: nfs.c,v 1.2 1998/01/24 12:43:09 drochner Exp $ */ /* * Copyright (c) 1993 John Brezak * All rights reserved. * * 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 `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 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. */ #include #include #include #include #include #include #include #include #include #include "rpcv2.h" #include "nfsv2.h" #include "stand.h" #include "net.h" #include "netif.h" #include "rpc.h" #define NFS_DEBUGxx #define NFSREAD_MIN_SIZE 1024 #define NFSREAD_MAX_SIZE 16384 /* NFSv3 definitions */ #define NFS_V3MAXFHSIZE 64 #define NFS_VER3 3 #define RPCMNT_VER3 3 #define NFSPROCV3_LOOKUP 3 #define NFSPROCV3_READLINK 5 #define NFSPROCV3_READ 6 #define NFSPROCV3_READDIR 16 typedef struct { uint32_t val[2]; } n_quad; struct nfsv3_time { uint32_t nfs_sec; uint32_t nfs_nsec; }; struct nfsv3_fattrs { uint32_t fa_type; uint32_t fa_mode; uint32_t fa_nlink; uint32_t fa_uid; uint32_t fa_gid; n_quad fa_size; n_quad fa_used; n_quad fa_rdev; n_quad fa_fsid; n_quad fa_fileid; struct nfsv3_time fa_atime; struct nfsv3_time fa_mtime; struct nfsv3_time fa_ctime; }; /* * For NFSv3, the file handle is variable in size, so most fixed sized * structures for arguments won't work. For most cases, a structure * that starts with any fixed size section is followed by an array * that covers the maximum size required. */ struct nfsv3_readdir_repl { uint32_t errno; uint32_t ok; struct nfsv3_fattrs fa; uint32_t cookiev0; uint32_t cookiev1; }; struct nfsv3_readdir_entry { uint32_t follows; uint32_t fid0; uint32_t fid1; uint32_t len; uint32_t nameplus[0]; }; struct nfs_iodesc { struct iodesc *iodesc; off_t off; uint32_t fhsize; uchar_t fh[NFS_V3MAXFHSIZE]; struct nfsv3_fattrs fa; /* all in network order */ uint64_t cookie; }; /* * XXX interactions with tftp? See nfswrapper.c for a confusing * issue. */ int nfs_open(const char *path, struct open_file *f); static int nfs_close(struct open_file *f); static int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t nfs_seek(struct open_file *f, off_t offset, int where); static int nfs_stat(struct open_file *f, struct stat *sb); static int nfs_readdir(struct open_file *f, struct dirent *d); struct nfs_iodesc nfs_root_node; struct fs_ops nfs_fsops = { .fs_name = "nfs", .fo_open = nfs_open, .fo_close = nfs_close, .fo_read = nfs_read, .fo_write = null_write, .fo_seek = nfs_seek, .fo_stat = nfs_stat, .fo_readdir = nfs_readdir }; static int nfs_read_size = NFSREAD_MIN_SIZE; /* * Improve boot performance over NFS */ static void set_nfs_read_size(void) { char *env, *end; char buf[10]; if ((env = getenv("nfs.read_size")) != NULL) { errno = 0; nfs_read_size = strtol(env, &end, 0); if (errno != 0 || *env == '\0' || *end != '\0') { printf("%s: bad value: \"%s\", defaulting to %d\n", "nfs.read_size", env, NFSREAD_MIN_SIZE); nfs_read_size = NFSREAD_MIN_SIZE; } } if (nfs_read_size < NFSREAD_MIN_SIZE) { printf("%s: bad value: \"%d\", defaulting to %d\n", "nfs.read_size", nfs_read_size, NFSREAD_MIN_SIZE); nfs_read_size = NFSREAD_MIN_SIZE; } if (nfs_read_size > NFSREAD_MAX_SIZE) { printf("%s: bad value: \"%d\", defaulting to %d\n", "nfs.read_size", nfs_read_size, NFSREAD_MIN_SIZE); nfs_read_size = NFSREAD_MAX_SIZE; } snprintf(buf, sizeof (buf), "%d", nfs_read_size); setenv("nfs.read_size", buf, 1); } /* * Fetch the root file handle (call mount daemon) * Return zero or error number. */ int nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, uchar_t *fhp) { void *pkt = NULL; int len; struct args { uint32_t len; char path[FNAME_SIZE]; } *args; struct repl { uint32_t errno; uint32_t fhsize; uchar_t fh[NFS_V3MAXFHSIZE]; uint32_t authcnt; uint32_t auth[7]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; size_t cc; #ifdef NFS_DEBUG if (debug) printf("nfs_getrootfh: %s\n", path); #endif args = &sdata.d; bzero(args, sizeof (*args)); len = strlen(path); if (len > sizeof (args->path)) len = sizeof (args->path); args->len = htonl(len); bcopy(path, args->path, len); len = sizeof (uint32_t) + roundup(len, sizeof (uint32_t)); cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT, args, len, (void **)&repl, &pkt); if (cc == -1) { free(pkt); /* errno was set by rpc_call */ return (errno); } if (cc < 2 * sizeof (uint32_t)) { free(pkt); return (EBADRPC); } if (repl->errno != 0) { free(pkt); return (ntohl(repl->errno)); } *fhlenp = ntohl(repl->fhsize); bcopy(repl->fh, fhp, *fhlenp); set_nfs_read_size(); free(pkt); return (0); } /* * Lookup a file. Store handle and attributes. * Return zero or error number. */ int nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd) { void *pkt = NULL; int len, pos; struct args { uint32_t fhsize; uint32_t fhplusname[1 + (NFS_V3MAXFHSIZE + FNAME_SIZE) / sizeof (uint32_t)]; } *args; struct repl { uint32_t errno; uint32_t fhsize; uint32_t fhplusattr[(NFS_V3MAXFHSIZE + 2 * (sizeof (uint32_t) + sizeof (struct nfsv3_fattrs))) / sizeof (uint32_t)]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; ssize_t cc; #ifdef NFS_DEBUG if (debug) printf("lookupfh: called\n"); #endif args = &sdata.d; bzero(args, sizeof (*args)); args->fhsize = htonl(d->fhsize); bcopy(d->fh, args->fhplusname, d->fhsize); len = strlen(name); if (len > FNAME_SIZE) len = FNAME_SIZE; pos = roundup(d->fhsize, sizeof (uint32_t)) / sizeof (uint32_t); args->fhplusname[pos++] = htonl(len); bcopy(name, &args->fhplusname[pos], len); len = sizeof (uint32_t) + pos * sizeof (uint32_t) + roundup(len, sizeof (uint32_t)); cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_LOOKUP, args, len, (void **)&repl, &pkt); if (cc == -1) { free(pkt); return (errno); /* XXX - from rpc_call */ } if (cc < 2 * sizeof (uint32_t)) { free(pkt); return (EIO); } if (repl->errno != 0) { free(pkt); /* saerrno.h now matches NFS error numbers. */ return (ntohl(repl->errno)); } newfd->fhsize = ntohl(repl->fhsize); bcopy(repl->fhplusattr, &newfd->fh, newfd->fhsize); pos = roundup(newfd->fhsize, sizeof (uint32_t)) / sizeof (uint32_t); if (repl->fhplusattr[pos++] == 0) { free(pkt); return (EIO); } bcopy(&repl->fhplusattr[pos], &newfd->fa, sizeof (newfd->fa)); free(pkt); return (0); } /* * Get the destination of a symbolic link. */ int nfs_readlink(struct nfs_iodesc *d, char *buf) { void *pkt = NULL; struct args { uint32_t fhsize; uchar_t fh[NFS_V3MAXFHSIZE]; } *args; struct repl { uint32_t errno; uint32_t ok; struct nfsv3_fattrs fa; uint32_t len; uchar_t path[NFS_MAXPATHLEN]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; ssize_t cc; int rc = 0; #ifdef NFS_DEBUG if (debug) printf("readlink: called\n"); #endif args = &sdata.d; bzero(args, sizeof (*args)); args->fhsize = htonl(d->fhsize); bcopy(d->fh, args->fh, d->fhsize); cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READLINK, args, sizeof (uint32_t) + roundup(d->fhsize, sizeof (uint32_t)), (void **)&repl, &pkt); if (cc == -1) return (errno); if (cc < 2 * sizeof (uint32_t)) { rc = EIO; goto done; } if (repl->errno != 0) { rc = ntohl(repl->errno); goto done; } if (repl->ok == 0) { rc = EIO; goto done; } repl->len = ntohl(repl->len); if (repl->len > NFS_MAXPATHLEN) { rc = ENAMETOOLONG; goto done; } bcopy(repl->path, buf, repl->len); buf[repl->len] = 0; done: free(pkt); return (rc); } /* * Read data from a file. * Return transfer count or -1 (and set errno) */ ssize_t nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len) { void *pkt = NULL; struct args { uint32_t fhsize; uint32_t fhoffcnt[NFS_V3MAXFHSIZE / sizeof (uint32_t) + 3]; } *args; struct repl { uint32_t errno; uint32_t ok; struct nfsv3_fattrs fa; uint32_t count; uint32_t eof; uint32_t len; uchar_t data[NFSREAD_MAX_SIZE]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; size_t cc; long x; int hlen, rlen, pos; args = &sdata.d; bzero(args, sizeof (*args)); args->fhsize = htonl(d->fhsize); bcopy(d->fh, args->fhoffcnt, d->fhsize); pos = roundup(d->fhsize, sizeof (uint32_t)) / sizeof (uint32_t); args->fhoffcnt[pos++] = 0; args->fhoffcnt[pos++] = htonl((uint32_t)off); if (len > nfs_read_size) len = nfs_read_size; args->fhoffcnt[pos] = htonl((uint32_t)len); hlen = offsetof(struct repl, data[0]); cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ, args, 4 * sizeof (uint32_t) + roundup(d->fhsize, sizeof (uint32_t)), (void **)&repl, &pkt); if (cc == -1) { /* errno was already set by rpc_call */ return (-1); } if (cc < hlen) { errno = EBADRPC; free(pkt); return (-1); } if (repl->errno != 0) { errno = ntohl(repl->errno); free(pkt); return (-1); } rlen = cc - hlen; x = ntohl(repl->count); if (rlen < x) { printf("nfsread: short packet, %d < %ld\n", rlen, x); errno = EBADRPC; free(pkt); return (-1); } bcopy(repl->data, addr, x); free(pkt); return (x); } /* * Open a file. * return zero or error number */ int nfs_open(const char *upath, struct open_file *f) { struct devdesc *dev; struct iodesc *desc; struct nfs_iodesc *currfd = NULL; char buf[2 * NFS_V3MAXFHSIZE + 3]; uchar_t *fh; char *cp; int i; struct nfs_iodesc *newfd = NULL; char *ncp; int c; char namebuf[NFS_MAXPATHLEN + 1]; char linkbuf[NFS_MAXPATHLEN + 1]; int nlinks = 0; int error; char *path = NULL; if (netproto != NET_NFS) return (EINVAL); dev = f->f_devdata; #ifdef NFS_DEBUG if (debug) printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath); #endif if (!rootpath[0]) { printf("no rootpath, no nfs\n"); return (ENXIO); } if (f->f_dev->dv_type != DEVT_NET) return (EINVAL); if (!(desc = socktodesc(*(int *)(dev->d_opendata)))) return (EINVAL); /* Bind to a reserved port. */ desc->myport = htons(--rpc_port); desc->destip = rootip; if ((error = nfs_getrootfh(desc, rootpath, &nfs_root_node.fhsize, nfs_root_node.fh))) return (error); nfs_root_node.fa.fa_type = htonl(NFDIR); nfs_root_node.fa.fa_mode = htonl(0755); nfs_root_node.fa.fa_nlink = htonl(2); nfs_root_node.iodesc = desc; fh = &nfs_root_node.fh[0]; buf[0] = 'X'; cp = &buf[1]; for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2) sprintf(cp, "%02x", fh[i]); sprintf(cp, "X"); setenv("boot.nfsroot.server", inet_ntoa(rootip), 1); setenv("boot.nfsroot.path", rootpath, 1); setenv("boot.nfsroot.nfshandle", buf, 1); sprintf(buf, "%d", nfs_root_node.fhsize); setenv("boot.nfsroot.nfshandlelen", buf, 1); /* Allocate file system specific data structure */ currfd = malloc(sizeof (*newfd)); if (currfd == NULL) { error = ENOMEM; goto out; } bcopy(&nfs_root_node, currfd, sizeof (*currfd)); newfd = NULL; cp = path = strdup(upath); if (path == NULL) { error = ENOMEM; goto out; } while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if (currfd->fa.fa_type != htonl(NFDIR)) { error = ENOTDIR; goto out; } /* allocate file system specific data structure */ newfd = malloc(sizeof (*newfd)); if (newfd == NULL) { error = ENOMEM; goto out; } newfd->iodesc = currfd->iodesc; /* * Get next component of path name. */ { int len = 0; ncp = cp; while ((c = *cp) != '\0' && c != '/') { if (++len > NFS_MAXNAMLEN) { error = ENOENT; goto out; } cp++; } *cp = '\0'; } /* lookup a file handle */ error = nfs_lookupfh(currfd, ncp, newfd); *cp = c; if (error) goto out; /* * Check for symbolic link */ if (newfd->fa.fa_type == htonl(NFLNK)) { int link_len, len; error = nfs_readlink(newfd, linkbuf); if (error) goto out; link_len = strlen(linkbuf); len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { error = ENOENT; goto out; } bcopy(cp, &namebuf[link_len], len + 1); bcopy(linkbuf, namebuf, link_len); /* * If absolute pathname, restart at root. * If relative pathname, restart at parent directory. */ cp = namebuf; if (*cp == '/') bcopy(&nfs_root_node, currfd, sizeof (*currfd)); free(newfd); newfd = NULL; continue; } free(currfd); currfd = newfd; newfd = NULL; } error = 0; out: free(newfd); free(path); if (!error) { currfd->off = 0; currfd->cookie = 0; f->f_fsdata = currfd; return (0); } #ifdef NFS_DEBUG if (debug) printf("nfs_open: %s lookupfh failed: %s\n", path, strerror(error)); #endif free(currfd); return (error); } int nfs_close(struct open_file *f) { struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; #ifdef NFS_DEBUG if (debug) printf("nfs_close: fp=%#p\n", fp); #endif free(fp); f->f_fsdata = NULL; return (0); } /* * read a portion of a file */ int nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid) { struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; ssize_t cc; char *addr = buf; #ifdef NFS_DEBUG if (debug) printf("nfs_read: size=%zu off=%j\n", size, (intmax_t)fp->off); #endif while (size > 0) { twiddle(16); cc = nfs_readdata(fp, fp->off, addr, size); /* XXX maybe should retry on certain errors */ if (cc == -1) { #ifdef NFS_DEBUG if (debug) printf("nfs_read: read: %s", strerror(errno)); #endif return (errno); /* XXX - from nfs_readdata */ } if (cc == 0) { #ifdef NFS_DEBUG if (debug) printf("nfs_read: hit EOF unexpectantly"); #endif goto ret; } fp->off += cc; addr += cc; size -= cc; } ret: if (resid) *resid = size; return (0); } off_t nfs_seek(struct open_file *f, off_t offset, int where) { struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata; uint32_t size = ntohl(d->fa.fa_size.val[1]); switch (where) { case SEEK_SET: d->off = offset; break; case SEEK_CUR: d->off += offset; break; case SEEK_END: d->off = size - offset; break; default: errno = EINVAL; return (-1); } return (d->off); } /* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5, NFSOCK=6, NFFIFO=7 */ int nfs_stat_types[9] = { 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO, 0 }; int nfs_stat(struct open_file *f, struct stat *sb) { struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; uint32_t ftype, mode; ftype = ntohl(fp->fa.fa_type); mode = ntohl(fp->fa.fa_mode); mode |= nfs_stat_types[ftype & 7]; sb->st_mode = mode; sb->st_nlink = ntohl(fp->fa.fa_nlink); sb->st_uid = ntohl(fp->fa.fa_uid); sb->st_gid = ntohl(fp->fa.fa_gid); sb->st_size = ntohl(fp->fa.fa_size.val[1]); return (0); } static int nfs_readdir(struct open_file *f, struct dirent *d) { struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; struct nfsv3_readdir_repl *repl; struct nfsv3_readdir_entry *rent; static void *pkt = NULL; static char *buf; static struct nfs_iodesc *pfp = NULL; static uint64_t cookie = 0; size_t cc; int pos, rc; struct args { uint32_t fhsize; uint32_t fhpluscookie[5 + NFS_V3MAXFHSIZE]; } *args; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; if (fp != pfp || fp->off != cookie) { pfp = NULL; refill: free(pkt); pkt = NULL; args = &sdata.d; bzero(args, sizeof (*args)); args->fhsize = htonl(fp->fhsize); bcopy(fp->fh, args->fhpluscookie, fp->fhsize); pos = roundup(fp->fhsize, sizeof (uint32_t)) / sizeof (uint32_t); args->fhpluscookie[pos++] = htonl(fp->off >> 32); args->fhpluscookie[pos++] = htonl(fp->off); args->fhpluscookie[pos++] = htonl(fp->cookie >> 32); args->fhpluscookie[pos++] = htonl(fp->cookie); args->fhpluscookie[pos] = htonl(NFS_READDIRSIZE); cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READDIR, args, 6 * sizeof (uint32_t) + roundup(fp->fhsize, sizeof (uint32_t)), (void **)&buf, &pkt); if (cc == -1) { rc = errno; goto err; } repl = (struct nfsv3_readdir_repl *)buf; if (repl->errno != 0) { rc = ntohl(repl->errno); goto err; } pfp = fp; cookie = fp->off; fp->cookie = ((uint64_t)ntohl(repl->cookiev0) << 32) | ntohl(repl->cookiev1); buf += sizeof (struct nfsv3_readdir_repl); } rent = (struct nfsv3_readdir_entry *)buf; if (rent->follows == 0) { /* fid0 is actually eof */ if (rent->fid0 != 0) { rc = ENOENT; goto err; } goto refill; } d->d_namlen = ntohl(rent->len); bcopy(rent->nameplus, d->d_name, d->d_namlen); d->d_name[d->d_namlen] = '\0'; pos = roundup(d->d_namlen, sizeof (uint32_t)) / sizeof (uint32_t); fp->off = cookie = ((uint64_t)ntohl(rent->nameplus[pos]) << 32) | ntohl(rent->nameplus[pos + 1]); pos += 2; buf = (char *)&rent->nameplus[pos]; return (0); err: free(pkt); pkt = NULL; pfp = NULL; cookie = 0; return (rc); } /* $FreeBSD$ */ /* $NetBSD: nfsv2.h,v 1.2 1996/02/26 23:05:23 gwr Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Macklem at The University of Guelph. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)nfsv2.h 8.1 (Berkeley) 6/10/93 */ /* * nfs definitions as per the version 2 specs */ /* * Constants as defined in the Sun NFS Version 2 spec. * "NFS: Network File System Protocol Specification" RFC1094 */ #define NFS_PORT 2049 #define NFS_PROG 100003 #define NFS_VER2 2 #define NFS_MAXDGRAMDATA 8192 #define NFS_MAXDATA 32768 #define NFS_MAXPATHLEN 1024 #define NFS_MAXNAMLEN 255 #define NFS_FHSIZE 32 #define NFS_MAXPKTHDR 404 #define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA) #define NFS_MINPACKET 20 #define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ #define NFS_READDIRSIZE 1024 /* Stat numbers for rpc returns */ #define NFS_OK 0 #define NFSERR_PERM 1 #define NFSERR_NOENT 2 #define NFSERR_IO 5 #define NFSERR_NXIO 6 #define NFSERR_ACCES 13 #define NFSERR_EXIST 17 #define NFSERR_NODEV 19 #define NFSERR_NOTDIR 20 #define NFSERR_ISDIR 21 #define NFSERR_FBIG 27 #define NFSERR_NOSPC 28 #define NFSERR_ROFS 30 #define NFSERR_NAMETOL 63 #define NFSERR_NOTEMPTY 66 #define NFSERR_DQUOT 69 #define NFSERR_STALE 70 #define NFSERR_WFLUSH 99 /* Sizes in bytes of various nfs rpc components */ #define NFSX_FH 32 #define NFSX_UNSIGNED 4 #define NFSX_FATTR 68 #define NFSX_SATTR 32 #define NFSX_STATFS 20 #define NFSX_COOKIE 4 /* nfs rpc procedure numbers */ #define NFSPROC_NULL 0 #define NFSPROC_GETATTR 1 #define NFSPROC_SETATTR 2 #define NFSPROC_NOOP 3 #define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */ #define NFSPROC_LOOKUP 4 #define NFSPROC_READLINK 5 #define NFSPROC_READ 6 #define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */ #define NFSPROC_WRITE 8 #define NFSPROC_CREATE 9 #define NFSPROC_REMOVE 10 #define NFSPROC_RENAME 11 #define NFSPROC_LINK 12 #define NFSPROC_SYMLINK 13 #define NFSPROC_MKDIR 14 #define NFSPROC_RMDIR 15 #define NFSPROC_READDIR 16 #define NFSPROC_STATFS 17 #define NFS_NPROCS 18 /* File types */ typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 } nfstype; /*- * Copyright (c) 2006 Olivier Houchard * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ #include __FBSDID("$FreeBSD$"); #include #define _BYTEORDER_FUNC_DEFINED #include uint32_t htonl(uint32_t hl) { return (__htonl(hl)); } uint16_t htons(uint16_t hs) { return (__htons(hs)); } uint32_t ntohl(uint32_t nl) { return (__ntohl(nl)); } uint16_t ntohs(uint16_t ns) { return (__ntohs(ns)); } /* $NetBSD: nullfs.c,v 1.1 1996/01/13 22:25:39 leo Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)open.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include "stand.h" /* * Null filesystem */ int null_open(const char *path __unused, struct open_file *f __unused) { return EINVAL; } int null_close(struct open_file *f __unused) { return 0; } int null_read(struct open_file *f __unused, void *buf __unused, size_t size __unused, size_t *resid __unused) { return EIO; } int null_write(struct open_file *f __unused, const void *buf __unused, size_t size __unused, size_t *resid __unused) { return EROFS; } off_t null_seek(struct open_file *f __unused, off_t offset __unused, int where __unused) { errno = EIO; return -1; } int null_stat(struct open_file *f __unused, struct stat *sb __unused) { return EIO; } int null_readdir(struct open_file *f __unused, struct dirent *d __unused) { return EIO; } /* $NetBSD: open.c,v 1.16 1997/01/28 09:41:03 pk Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)open.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include "stand.h" struct fs_ops *exclusive_file_system; /* * Open file list. The current implementation and assumption is, * we only remove entries from tail and we only add new entries to tail. * This decision is to keep file id management simple - we get list * entries ordered by continiously growing f_id field. * If we do have multiple files open and we do close file not from tail, * this entry will be marked unused. open() will reuse unused entry, or * close will free all unused tail entries. * * Only case we expect open file list to grow long, is with zfs pools with * many disks. */ file_list_t files = TAILQ_HEAD_INITIALIZER(files); /* * Walk file list and return pointer to open_file structure. * if fd is < 0, return first unused open_file. */ struct open_file * fd2open_file(int fd) { struct open_file *f; TAILQ_FOREACH(f, &files, f_link) { if (fd >= 0) { if (f->f_id == fd) break; continue; } if (f->f_flags == 0) break; } return (f); } static int o_gethandle(struct open_file **ptr) { struct open_file *f, *last; /* Pick up unused entry */ f = fd2open_file(-1); if (f != NULL) { *ptr = f; return (f->f_id); } /* Add new entry */ f = calloc(1, sizeof (*f)); if (f == NULL) return (-1); last = TAILQ_LAST(&files, file_list); if (last != NULL) f->f_id = last->f_id + 1; TAILQ_INSERT_TAIL(&files, f, f_link); *ptr = f; return (f->f_id); } static void o_rainit(struct open_file *f) { f->f_rabuf = malloc(SOPEN_RASIZE); f->f_ralen = 0; f->f_raoffset = 0; } int open(const char *fname, int mode) { struct fs_ops *fs; struct open_file *f; int fd, i, error, besterror; const char *file; if ((fd = o_gethandle(&f)) == -1) { errno = EMFILE; return (-1); } f->f_flags = mode + 1; f->f_dev = NULL; f->f_ops = NULL; f->f_offset = 0; f->f_devdata = NULL; file = NULL; if (exclusive_file_system != NULL) { fs = exclusive_file_system; error = (fs->fo_open)(fname, f); if (error == 0) goto ok; goto err; } error = devopen(f, fname, &file); if (error || (((f->f_flags & F_NODEV) == 0) && f->f_dev == NULL)) goto err; /* see if we opened a raw device; otherwise, 'file' is the file name. */ if (file == NULL || *file == '\0') { f->f_flags |= F_RAW; f->f_rabuf = NULL; return (fd); } /* pass file name to the different filesystem open routines */ besterror = ENOENT; for (i = 0; file_system[i] != NULL; i++) { fs = file_system[i]; error = (fs->fo_open)(file, f); if (error == 0) goto ok; if (error != EINVAL) besterror = error; } error = besterror; if ((f->f_flags & F_NODEV) == 0 && f->f_dev != NULL) f->f_dev->dv_close(f); if (error) devclose(f); err: f->f_flags = 0; errno = error; return (-1); ok: f->f_ops = fs; o_rainit(f); return (fd); } /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ /* * Simple paged-output and paged-viewing functions */ #include #include "stand.h" #include static int p_maxlines = -1; static int p_freelines; static char *pager_prompt1 = \ " --more-- page down line down quit "; static char *pager_blank = \ " "; /* * 'open' the pager */ void pager_open(void) { int nlines; char *cp, *lp; nlines = 24; /* sensible default */ if ((cp = getenv("screen-#rows")) != NULL) { nlines = strtol(cp, &lp, 0); } p_maxlines = nlines - 1; if (p_maxlines < 1) p_maxlines = 1; p_freelines = p_maxlines; } /* * 'close' the pager */ void pager_close(void) { p_maxlines = -1; } /* * Emit lines to the pager; may not return until the user * has responded to the prompt. * * Will return nonzero if the user enters 'q' or 'Q' at the prompt. * * XXX note that this watches outgoing newlines (and eats them), but * does not handle wrap detection (req. count of columns). */ int pager_output(const char *cp) { int action; if (cp == NULL) return (0); for (;;) { if (*cp == 0) return (0); putchar(*cp); /* always emit character */ if (*(cp++) == '\n') { /* got a newline? */ p_freelines--; if (p_freelines <= 0) { printf("%s", pager_prompt1); action = 0; while (action == 0) { switch (getchar()) { case '\r': case '\n': p_freelines = 1; action = 1; break; case ' ': p_freelines = p_maxlines; action = 1; break; case 'q': case 'Q': action = 2; break; default: break; } } printf("\r%s\r", pager_blank); if (action == 2) return (1); } } } } /* * Display from (fd). */ int pager_file(const char *fname) { char buf[80]; size_t hmuch; int fd; int result; if ((fd = open(fname, O_RDONLY)) == -1) { printf("can't open '%s': %s\n", fname, strerror(errno)); return (-1); } for (;;) { hmuch = read(fd, buf, sizeof (buf) - 1); if (hmuch == -1) { result = -1; break; } if (hmuch == 0) { result = 0; break; } buf[hmuch] = 0; if (pager_output(buf)) { result = 1; break; } } close(fd); return (result); } /* * $NetBSD: panic.c,v 1.2 1997/03/22 01:48:36 thorpej Exp $ */ /* * Copyright (c) 1996 * Matthias Drochner. All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project * by Matthias Drochner. * 4. 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 ``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 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. * */ #include #include #include /* * Boot loaders and other standalone programs that wish to have a * different panic policy can provide their own panic_action rotuine. */ __weak_symbol void panic_action(void) { printf("--> Press a key on the console to reboot <--\n"); getchar(); printf("Rebooting...\n"); exit(1); } void panic(const char *fmt, ...) { va_list ap; printf("panic: "); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); panic_action(); } /* * Copyright (c) 1986, 1988, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ #include /* * Standaloneified version of the FreeBSD kernel printf family. */ #include #include #include #include #include #include "stand.h" /* * Note that stdarg.h and the ANSI style va_start macro is used for both * ANSI and traditional C compilers. */ #include #define MAXNBUF (sizeof (intmax_t) * CHAR_BIT + 1) typedef void (kvprintf_fn_t)(int, void *); static char *ksprintn(char *, uintmax_t, int, int *, int); static int kvprintf(char const *, kvprintf_fn_t *, void *, int, va_list); static void putchar_wrapper(int cc, void *arg __unused) { putchar(cc); } int printf(const char *fmt, ...) { va_list ap; int retval; va_start(ap, fmt); retval = kvprintf(fmt, putchar_wrapper, NULL, 10, ap); va_end(ap); return (retval); } void vprintf(const char *fmt, va_list ap) { kvprintf(fmt, putchar_wrapper, NULL, 10, ap); } int sprintf(char *buf, const char *cfmt, ...) { int retval; va_list ap; va_start(ap, cfmt); retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); buf[retval] = '\0'; va_end(ap); return (retval); } struct print_buf { char *buf; size_t size; }; static void snprint_func(int ch, void *arg) { struct print_buf *pbuf = arg; if (pbuf->size < 2) { /* * Reserve last buffer position for the terminating * character: */ return; } *(pbuf->buf)++ = ch; pbuf->size--; } int asprintf(char **buf, const char *cfmt, ...) { int retval; struct print_buf arg; va_list ap; *buf = NULL; va_start(ap, cfmt); retval = kvprintf(cfmt, NULL, NULL, 10, ap); va_end(ap); if (retval <= 0) return (-1); arg.size = retval + 1; arg.buf = *buf = malloc(arg.size); if (*buf == NULL) return (-1); va_start(ap, cfmt); retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap); va_end(ap); if (arg.size >= 1) *(arg.buf)++ = 0; return (retval); } int snprintf(char *buf, size_t size, const char *cfmt, ...) { int retval; va_list ap; struct print_buf arg; arg.buf = buf; arg.size = size; va_start(ap, cfmt); retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap); va_end(ap); if (arg.size >= 1) *(arg.buf)++ = 0; return (retval); } void vsprintf(char *buf, const char *cfmt, va_list ap) { int retval; retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); buf[retval] = '\0'; } void vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap) { int retval; struct print_buf arg; arg.buf = buf; arg.size = size; retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap); buf[retval] = '\0'; } /* * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse * order; return an optional length and a pointer to the last character * written in the buffer (i.e., the first character of the string). * The buffer pointed to by `nbuf' must have length >= MAXNBUF. */ static char * ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) { char *p, c; p = nbuf; *p = '\0'; do { c = hex2ascii(num % base); *++p = upper ? toupper(c) : c; } while (num /= base); if (lenp) *lenp = p - nbuf; return (p); } /* * Scaled down version of printf(3). * * Two additional formats: * * The format %b is supported to decode error registers. * Its usage is: * * printf("reg=%b\n", regval, "*"); * * where is the output base expressed as a control character, e.g. * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, * the first of which gives the bit number to be inspected (origin 1), and * the next characters (up to a control character, i.e. a character <= 32), * give the name of the register. Thus: * * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE"); * * would produce output: * * reg=3 * * XXX: %D -- Hexdump, takes pointer and separator string: * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX * ("%*D", len, ptr, " " -> XX XX XX XX ... */ static int kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap) { #define PCHAR(c) { \ int cc = (c); \ \ if (func) { \ (*func)(cc, arg); \ } else if (d != NULL) { \ *d++ = cc; \ } \ retval++; \ } char nbuf[MAXNBUF]; char *d; const char *p, *percent, *q; uint16_t *S; uchar_t *up; int ch, n; uintmax_t num; int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; int cflag, hflag, jflag, tflag, zflag; int dwidth, upper; char padc; int stop = 0, retval = 0; num = 0; if (!func) d = (char *)arg; else d = NULL; if (fmt == NULL) fmt = "(fmt null)\n"; if (radix < 2 || radix > 36) radix = 10; for (;;) { padc = ' '; width = 0; while ((ch = (uchar_t)*fmt++) != '%' || stop) { if (ch == '\0') return (retval); PCHAR(ch); } percent = fmt - 1; qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; sign = 0; dot = 0; dwidth = 0; upper = 0; cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; reswitch: switch (ch = (uchar_t)*fmt++) { case '.': dot = 1; goto reswitch; case '#': sharpflag = 1; goto reswitch; case '+': sign = 1; goto reswitch; case '-': ladjust = 1; goto reswitch; case '%': PCHAR(ch); break; case '*': if (!dot) { width = va_arg(ap, int); if (width < 0) { ladjust = !ladjust; width = -width; } } else { dwidth = va_arg(ap, int); } goto reswitch; case '0': if (!dot) { padc = '0'; goto reswitch; } /* FALLTHROUGH */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': for (n = 0; ; ++fmt) { n = n * 10 + ch - '0'; ch = *fmt; if (ch < '0' || ch > '9') break; } if (dot) dwidth = n; else width = n; goto reswitch; case 'b': num = (uint_t)va_arg(ap, int); p = va_arg(ap, char *); for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q; ) PCHAR(*q--); if (num == 0) break; for (tmp = 0; *p; ) { n = *p++; if (num & (1 << (n - 1))) { PCHAR(tmp ? ',' : '<'); for (; (n = *p) > ' '; ++p) PCHAR(n); tmp = 1; } else for (; *p > ' '; ++p) continue; } if (tmp) PCHAR('>'); break; case 'c': PCHAR(va_arg(ap, int)); break; case 'D': up = va_arg(ap, uchar_t *); p = va_arg(ap, char *); if (!width) width = 16; while (width--) { PCHAR(hex2ascii(*up >> 4)); PCHAR(hex2ascii(*up & 0x0f)); up++; if (width) for (q = p; *q; q++) PCHAR(*q); } break; case 'd': case 'i': base = 10; sign = 1; goto handle_sign; case 'h': if (hflag) { hflag = 0; cflag = 1; } else hflag = 1; goto reswitch; case 'j': jflag = 1; goto reswitch; case 'l': if (lflag) { lflag = 0; qflag = 1; } else lflag = 1; goto reswitch; case 'n': if (jflag) *(va_arg(ap, intmax_t *)) = retval; else if (qflag) *(va_arg(ap, quad_t *)) = retval; else if (lflag) *(va_arg(ap, long *)) = retval; else if (zflag) *(va_arg(ap, size_t *)) = retval; else if (hflag) *(va_arg(ap, short *)) = retval; else if (cflag) *(va_arg(ap, char *)) = retval; else *(va_arg(ap, int *)) = retval; break; case 'o': base = 8; goto handle_nosign; case 'p': base = 16; sharpflag = (width == 0); sign = 0; num = (uintptr_t)va_arg(ap, void *); goto number; case 'q': qflag = 1; goto reswitch; case 'r': base = radix; if (sign) goto handle_sign; goto handle_nosign; case 's': p = va_arg(ap, char *); if (p == NULL) p = "(null)"; if (!dot) n = strlen(p); else for (n = 0; n < dwidth && p[n]; n++) continue; width -= n; if (!ladjust && width > 0) while (width--) PCHAR(padc); while (n--) PCHAR(*p++); if (ladjust && width > 0) while (width--) PCHAR(padc); break; case 'S': /* Assume console can cope with wide chars */ S = va_arg(ap, uint16_t *); if (S == NULL) S = (uint16_t *)L"(null)"; if (!dot) { for (n = 0; S[n] != 0; n++) continue; } else { for (n = 0; n < dwidth && S[n]; n++) continue; } width -= n; if (!ladjust && width > 0) while (width--) PCHAR(padc); while (n--) PCHAR(*S++); if (ladjust && width > 0) while (width--) PCHAR(padc); break; case 't': tflag = 1; goto reswitch; case 'u': base = 10; goto handle_nosign; case 'X': upper = 1; /* FALLTHROUGH */ case 'x': base = 16; goto handle_nosign; case 'y': base = 16; sign = 1; goto handle_sign; case 'z': zflag = 1; goto reswitch; handle_nosign: sign = 0; if (jflag) num = va_arg(ap, uintmax_t); else if (qflag) num = va_arg(ap, uint64_t); else if (tflag) num = va_arg(ap, ptrdiff_t); else if (lflag) num = va_arg(ap, ulong_t); else if (zflag) num = va_arg(ap, size_t); else if (hflag) num = (ushort_t)va_arg(ap, int); else if (cflag) num = (uchar_t)va_arg(ap, int); else num = va_arg(ap, uint_t); goto number; handle_sign: if (jflag) num = va_arg(ap, intmax_t); else if (qflag) num = va_arg(ap, quad_t); else if (tflag) num = va_arg(ap, ptrdiff_t); else if (lflag) num = va_arg(ap, long); else if (zflag) num = va_arg(ap, ssize_t); else if (hflag) num = (short)va_arg(ap, int); else if (cflag) num = (char)va_arg(ap, int); else num = va_arg(ap, int); number: if (sign && (intmax_t)num < 0) { neg = 1; num = -(intmax_t)num; } p = ksprintn(nbuf, num, base, &n, upper); tmp = 0; if (sharpflag && num != 0) { if (base == 8) tmp++; else if (base == 16) tmp += 2; } if (neg) tmp++; if (!ladjust && padc == '0') dwidth = width - tmp; width -= tmp + imax(dwidth, n); dwidth -= n; if (!ladjust) while (width-- > 0) PCHAR(' '); if (neg) PCHAR('-'); if (sharpflag && num != 0) { if (base == 8) { PCHAR('0'); } else if (base == 16) { PCHAR('0'); PCHAR('x'); } } while (dwidth-- > 0) PCHAR('0'); while (*p) PCHAR(*p--); if (ladjust) while (width-- > 0) PCHAR(' '); break; default: while (percent < fmt) PCHAR(*percent++); /* * Since we ignore a formatting argument it is no * longer safe to obey the remaining formatting * arguments as the arguments will no longer match * the format specs. */ stop = 1; break; } } #undef PCHAR } /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * From: Id: qdivrem.c,v 1.7 1997/11/07 09:20:40 phk Exp */ #include #include /* * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed), * section 4.3.1, pp. 257--259. */ #include "quad.h" #define B (1 << HALF_BITS) /* digit base */ /* Combine two `digits' to make a single two-digit number. */ #define COMBINE(a, b) (((u_int)(a) << HALF_BITS) | (b)) _Static_assert(sizeof(int) / 2 == sizeof(short), "Bitwise functions in libstand are broken on this architecture\n"); /* select a type for digits in base B: use unsigned short if they fit */ typedef unsigned short digit; /* * Shift p[0]..p[len] left `sh' bits, ignoring any bits that * `fall out' the left (there never will be any such anyway). * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS. */ static void shl(digit *p, int len, int sh) { int i; for (i = 0; i < len; i++) p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh)); p[i] = LHALF(p[i] << sh); } /* * __udivmoddi4(u, v, rem) returns u/v and, optionally, sets *rem to u%v. * * We do this in base 2-sup-HALF_BITS, so that all intermediate products * fit within u_int. As a consequence, the maximum length dividend and * divisor are 4 `digits' in this base (they are shorter if they have * leading zeros). */ u_quad_t __udivmoddi4(u_quad_t uq, u_quad_t vq, u_quad_t *arq) { union uu tmp; digit *u, *v, *q; digit v1, v2; u_int qhat, rhat, t; int m, n, d, j, i; digit uspace[5], vspace[5], qspace[5]; /* * Take care of special cases: divide by zero, and u < v. */ if (vq == 0) { /* divide by zero. */ static volatile const unsigned int zero = 0; tmp.ul[H] = tmp.ul[L] = 1 / zero; if (arq) *arq = uq; return (tmp.q); } if (uq < vq) { if (arq) *arq = uq; return (0); } u = &uspace[0]; v = &vspace[0]; q = &qspace[0]; /* * Break dividend and divisor into digits in base B, then * count leading zeros to determine m and n. When done, we * will have: * u = (u[1]u[2]...u[m+n]) sub B * v = (v[1]v[2]...v[n]) sub B * v[1] != 0 * 1 < n <= 4 (if n = 1, we use a different division algorithm) * m >= 0 (otherwise u < v, which we already checked) * m + n = 4 * and thus * m = 4 - n <= 2 */ tmp.uq = uq; u[0] = 0; u[1] = HHALF(tmp.ul[H]); u[2] = LHALF(tmp.ul[H]); u[3] = HHALF(tmp.ul[L]); u[4] = LHALF(tmp.ul[L]); tmp.uq = vq; v[1] = HHALF(tmp.ul[H]); v[2] = LHALF(tmp.ul[H]); v[3] = HHALF(tmp.ul[L]); v[4] = LHALF(tmp.ul[L]); for (n = 4; v[1] == 0; v++) { if (--n == 1) { u_int rbj; /* r*B+u[j] (not root boy jim) */ digit q1, q2, q3, q4; /* * Change of plan, per exercise 16. * r = 0; * for j = 1..4: * q[j] = floor((r*B + u[j]) / v), * r = (r*B + u[j]) % v; * We unroll this completely here. */ t = v[2]; /* nonzero, by definition */ q1 = u[1] / t; rbj = COMBINE(u[1] % t, u[2]); q2 = rbj / t; rbj = COMBINE(rbj % t, u[3]); q3 = rbj / t; rbj = COMBINE(rbj % t, u[4]); q4 = rbj / t; if (arq) *arq = rbj % t; tmp.ul[H] = COMBINE(q1, q2); tmp.ul[L] = COMBINE(q3, q4); return (tmp.q); } } /* * By adjusting q once we determine m, we can guarantee that * there is a complete four-digit quotient at &qspace[1] when * we finally stop. */ for (m = 4 - n; u[1] == 0; u++) m--; for (i = 4 - m; --i >= 0;) q[i] = 0; q += 4 - m; /* * Here we run Program D, translated from MIX to C and acquiring * a few minor changes. * * D1: choose multiplier 1 << d to ensure v[1] >= B/2. */ d = 0; for (t = v[1]; t < B / 2; t <<= 1) d++; if (d > 0) { shl(&u[0], m + n, d); /* u <<= d */ shl(&v[1], n - 1, d); /* v <<= d */ } /* * D2: j = 0. */ j = 0; v1 = v[1]; /* for D3 -- note that v[1..n] are constant */ v2 = v[2]; /* for D3 */ do { digit uj0, uj1, uj2; /* * D3: Calculate qhat (\^q, in TeX notation). * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and * let rhat = (u[j]*B + u[j+1]) mod v[1]. * While rhat < B and v[2]*qhat > rhat*B+u[j+2], * decrement qhat and increase rhat correspondingly. * Note that if rhat >= B, v[2]*qhat < rhat*B. */ uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */ uj1 = u[j + 1]; /* for D3 only */ uj2 = u[j + 2]; /* for D3 only */ if (uj0 == v1) { qhat = B; rhat = uj1; goto qhat_too_big; } else { u_int nn = COMBINE(uj0, uj1); qhat = nn / v1; rhat = nn % v1; } while (v2 * qhat > COMBINE(rhat, uj2)) { qhat_too_big: qhat--; if ((rhat += v1) >= B) break; } /* * D4: Multiply and subtract. * The variable `t' holds any borrows across the loop. * We split this up so that we do not require v[0] = 0, * and to eliminate a final special case. */ for (t = 0, i = n; i > 0; i--) { t = u[i + j] - v[i] * qhat - t; u[i + j] = LHALF(t); t = (B - HHALF(t)) & (B - 1); } t = u[j] - t; u[j] = LHALF(t); /* * D5: test remainder. * There is a borrow if and only if HHALF(t) is nonzero; * in that (rare) case, qhat was too large (by exactly 1). * Fix it by adding v[1..n] to u[j..j+n]. */ if (HHALF(t)) { qhat--; for (t = 0, i = n; i > 0; i--) { /* D6: add back. */ t += u[i + j] + v[i]; u[i + j] = LHALF(t); t = HHALF(t); } u[j] = LHALF(u[j] + t); } q[j] = qhat; } while (++j <= m); /* D7: loop on j. */ /* * If caller wants the remainder, we have to calculate it as * u[m..m+n] >> d (this is at most n digits and thus fits in * u[m+1..m+n], but we may need more source digits). */ if (arq) { if (d) { for (i = m + n; i > m; --i) u[i] = (u[i] >> d) | LHALF(u[i - 1] << (HALF_BITS - d)); u[i] = 0; } tmp.ul[H] = COMBINE(uspace[1], uspace[2]); tmp.ul[L] = COMBINE(uspace[3], uspace[4]); *arq = tmp.q; } tmp.ul[H] = COMBINE(qspace[1], qspace[2]); tmp.ul[L] = COMBINE(qspace[3], qspace[4]); return (tmp.q); } /* * Divide two unsigned quads. */ u_quad_t __udivdi3(u_quad_t a, u_quad_t b) { return (__udivmoddi4(a, b, NULL)); } /* * Return remainder after dividing two unsigned quads. */ u_quad_t __umoddi3(u_quad_t a, u_quad_t b) { u_quad_t r; (void)__udivmoddi4(a, b, &r); return (r); } /* * Divide two signed quads. * ??? if -1/2 should produce -1 on this machine, this code is wrong */ quad_t __divdi3(quad_t a, quad_t b) { u_quad_t ua, ub, uq; int neg; if (a < 0) ua = -(u_quad_t)a, neg = 1; else ua = a, neg = 0; if (b < 0) ub = -(u_quad_t)b, neg ^= 1; else ub = b; uq = __udivmoddi4(ua, ub, NULL); return (neg ? -uq : uq); } /* * Return remainder after dividing two signed quads. * * XXX * If -1/2 should produce -1 on this machine, this code is wrong. */ quad_t __moddi3(quad_t a, quad_t b) { u_quad_t ua, ub, ur; int neg; if (a < 0) ua = -(u_quad_t)a, neg = 1; else ua = a, neg = 0; if (b < 0) ub = -(u_quad_t)b; else ub = b; (void)__udivmoddi4(ua, ub, &ur); return (neg ? -ur : ur); } quad_t __divmoddi4(quad_t a, quad_t b, quad_t *r) { quad_t d; d = __divdi3(a, b); if (r != NULL) *r = a - (b * d); return (d); } /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)quad.h 8.1 (Berkeley) 6/4/93 * $FreeBSD$ */ /* * Quad arithmetic. * * This library makes the following assumptions: * * - The type long long (aka quad_t) exists. * * - A quad variable is exactly twice as long as `long'. * * - The machine's arithmetic is two's complement. * * This library can provide 128-bit arithmetic on a machine with 128-bit * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines * with 48-bit longs. */ #include #include #include _Static_assert(sizeof(quad_t) == sizeof(int) * 2, "Bitwise function in libstand are broken on this architecture\n"); /* * Depending on the desired operation, we view a `long long' (aka quad_t) in * one or more of the following formats. */ union uu { quad_t q; /* as a (signed) quad */ quad_t uq; /* as an unsigned quad */ int sl[2]; /* as two signed ints */ u_int ul[2]; /* as two unsigned ints */ }; /* * Define high and low longwords. */ #define H _QUAD_HIGHWORD #define L _QUAD_LOWWORD /* * Total number of bits in a quad_t and in the pieces that make it up. * These are used for shifting, and also below for halfword extraction * and assembly. */ #define QUAD_BITS (sizeof(quad_t) * CHAR_BIT) #define HALF_BITS (sizeof(int) * CHAR_BIT / 2) /* * Extract high and low shortwords from longword, and move low shortword of * longword to upper half of long, i.e., produce the upper longword of * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.) * * These are used in the multiply code, to split a longword into upper * and lower halves, and to reassemble a product as a quad_t, shifted left * (sizeof(long)*CHAR_BIT/2). */ #define HHALF(x) ((x) >> HALF_BITS) #define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) #define LHUP(x) ((x) << HALF_BITS) quad_t __divdi3(quad_t a, quad_t b); quad_t __moddi3(quad_t a, quad_t b); u_quad_t __udivmoddi4(u_quad_t u, u_quad_t v, u_quad_t *rem); u_quad_t __udivdi3(u_quad_t a, u_quad_t b); u_quad_t __umoddi3(u_quad_t a, u_quad_t b); /* * XXX * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use * both compilers. */ #if __GNUC__ >= 2 typedef unsigned int qshift_t; #else typedef u_quad_t qshift_t; #endif /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)random.c 8.1 (Berkeley) 6/10/93 */ #include #include static ulong_t randseed = 1; void srandom(ulong_t seed) { randseed = seed; } /* * Pseudo-random number generator for randomizing the profiling clock, * and whatever else we might use it for. The result is uniform on * [0, 2^31 - 1]. */ ulong_t random(void) { long x, hi, lo, t; /* * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1). * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. */ x = randseed; hi = x / 127773; lo = x % 127773; t = 16807 * lo - 2836 * hi; if (t <= 0) t += 0x7fffffff; randseed = t; return (t); } /* $NetBSD: rarp.c,v 1.16 1997/07/07 15:52:52 drochner Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: arp.c,v 1.5 93/07/15 05:52:26 leres Exp (LBL) */ #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" #include "netif.h" static ssize_t rarpsend(struct iodesc *, void *, size_t); static ssize_t rarprecv(struct iodesc *, void **, void **, time_t, void *); /* * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826). */ int rarp_getipaddress(int sock) { struct iodesc *d; struct ether_arp *ap; void *pkt; struct { u_char header[ETHER_SIZE]; struct { struct ether_arp arp; u_char pad[18]; /* 60 - sizeof(arp) */ } data; } wbuf; #ifdef RARP_DEBUG if (debug) printf("rarp: socket=%d\n", sock); #endif if (!(d = socktodesc(sock))) { printf("rarp: bad socket. %d\n", sock); return (-1); } #ifdef RARP_DEBUG if (debug) printf("rarp: d=%x\n", (u_int)d); #endif bzero((char*)&wbuf.data, sizeof(wbuf.data)); ap = &wbuf.data.arp; ap->arp_hrd = htons(ARPHRD_ETHER); ap->arp_pro = htons(ETHERTYPE_IP); ap->arp_hln = sizeof(ap->arp_sha); /* hardware address length */ ap->arp_pln = sizeof(ap->arp_spa); /* protocol address length */ ap->arp_op = htons(ARPOP_REVREQUEST); bcopy(d->myea, ap->arp_sha, 6); bcopy(d->myea, ap->arp_tha, 6); pkt = NULL; if (sendrecv(d, rarpsend, &wbuf.data, sizeof(wbuf.data), rarprecv, &pkt, (void *)&ap, NULL) < 0) { printf("No response for RARP request\n"); return (-1); } bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip)); #if 0 /* XXX - Can NOT assume this is our root server! */ bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip)); #endif free(pkt); /* Compute our "natural" netmask. */ if (IN_CLASSA(myip.s_addr)) netmask = IN_CLASSA_NET; else if (IN_CLASSB(myip.s_addr)) netmask = IN_CLASSB_NET; else netmask = IN_CLASSC_NET; d->myip = myip; return (0); } /* * Broadcast a RARP request (i.e. who knows who I am) */ static ssize_t rarpsend(struct iodesc *d, void *pkt, size_t len) { #ifdef RARP_DEBUG if (debug) printf("rarpsend: called\n"); #endif return (sendether(d, pkt, len, bcea, ETHERTYPE_REVARP)); } /* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ static ssize_t rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra __unused) { ssize_t n; struct ether_arp *ap; void *ptr = NULL; uint16_t etype; /* host order */ #ifdef RARP_DEBUG if (debug) printf("rarprecv: "); #endif n = readether(d, &ptr, (void **)&ap, tleft, &etype); errno = 0; /* XXX */ if (n == -1 || n < sizeof(struct ether_arp)) { #ifdef RARP_DEBUG if (debug) printf("bad len=%d\n", n); #endif free(ptr); return (-1); } if (etype != ETHERTYPE_REVARP) { #ifdef RARP_DEBUG if (debug) printf("bad type=0x%x\n", etype); #endif free(ptr); return (-1); } if (ap->arp_hrd != htons(ARPHRD_ETHER) || ap->arp_pro != htons(ETHERTYPE_IP) || ap->arp_hln != sizeof(ap->arp_sha) || ap->arp_pln != sizeof(ap->arp_spa) ) { #ifdef RARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); #endif free(ptr); return (-1); } if (ap->arp_op != htons(ARPOP_REVREPLY)) { #ifdef RARP_DEBUG if (debug) printf("bad op=0x%x\n", ntohs(ap->arp_op)); #endif free(ptr); return (-1); } /* Is the reply for our Ethernet address? */ if (bcmp(ap->arp_tha, d->myea, 6)) { #ifdef RARP_DEBUG if (debug) printf("unwanted address\n"); #endif free(ptr); return (-1); } /* We have our answer. */ #ifdef RARP_DEBUG if (debug) printf("got it\n"); #endif *pkt = ptr; *payload = ap; return (n); } /* $NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)read.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include #include "stand.h" ssize_t read(int fd, void *dest, size_t bcount) { struct open_file *f; size_t resid; f = fd2open_file(fd); if (f == NULL || !(f->f_flags & F_READ)) { errno = EBADF; return (-1); } if (f->f_flags & F_RAW) { twiddle(8); errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, btodb(f->f_offset), bcount, dest, &resid); if (errno) return (-1); f->f_offset += resid; return (resid); } /* * Optimise reads from regular files using a readahead buffer. * If the request can't be satisfied from the current buffer contents, * check to see if it should be bypassed, or refill the buffer and * complete the request. */ resid = bcount; for (;;) { size_t ccount, cresid; /* how much can we supply? */ ccount = imin(f->f_ralen, resid); if (ccount > 0) { bcopy(f->f_rabuf + f->f_raoffset, dest, ccount); f->f_raoffset += ccount; f->f_ralen -= ccount; resid -= ccount; if (resid == 0) return (bcount); dest = (char *)dest + ccount; } /* will filling the readahead buffer again not help? */ if (f->f_rabuf == NULL || resid >= SOPEN_RASIZE) { /* * bypass the rest of the request and leave the * buffer empty */ errno = (f->f_ops->fo_read)(f, dest, resid, &cresid); if (errno != 0) return (-1); return (bcount - cresid); } /* fetch more data */ errno = (f->f_ops->fo_read)(f, f->f_rabuf, SOPEN_RASIZE, &cresid); if (errno != 0) return (-1); f->f_raoffset = 0; f->f_ralen = SOPEN_RASIZE - cresid; /* no more data, return what we had */ if (f->f_ralen == 0) return (bcount - resid); } } /*- * Copyright (c) 1999,2000 Jonathan Lemon * All rights reserved. * * 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. * * 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. */ #include #include #include "stand.h" struct dirent * readdirfd(int fd) { static struct dirent dir; /* XXX not thread safe */ struct open_file *f; f = fd2open_file(fd); if (f == NULL || !(f->f_flags & F_READ)) { errno = EBADF; return (NULL); } if (f->f_flags & F_RAW) { errno = EIO; return (NULL); } errno = (f->f_ops->fo_readdir)(f, &dir); if (errno) return (NULL); return (&dir); } /* $NetBSD: rpc.c,v 1.18 1998/01/23 19:27:45 thorpej Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: rpc.c,v 1.12 93/09/28 08:31:56 leres Exp (LBL) */ #include /* * RPC functions used by NFS and bootparams. * Note that bootparams requires the ability to find out the * address of the server from which its response has come. * This is supported by keeping the IP/UDP headers in the * buffer space provided by the caller. (See rpc_fromaddr) */ #include #include #include #include #include #include "rpcv2.h" #include "stand.h" #include "net.h" #include "netif.h" #include "rpc.h" struct auth_info { int32_t authtype; /* auth type */ u_int32_t authlen; /* auth length */ }; struct auth_unix { int32_t ua_time; int32_t ua_hostname; /* null */ int32_t ua_uid; int32_t ua_gid; int32_t ua_gidlist; /* null */ }; struct rpc_call { u_int32_t rp_xid; /* request transaction id */ int32_t rp_direction; /* call direction (0) */ u_int32_t rp_rpcvers; /* rpc version (2) */ u_int32_t rp_prog; /* program */ u_int32_t rp_vers; /* version */ u_int32_t rp_proc; /* procedure */ }; struct rpc_reply { u_int32_t rp_xid; /* request transaction id */ int32_t rp_direction; /* call direction (1) */ int32_t rp_astatus; /* accept status (0: accepted) */ union { u_int32_t rpu_errno; struct { struct auth_info rok_auth; u_int32_t rok_status; } rpu_rok; } rp_u; }; /* Local forwards */ static ssize_t recvrpc(struct iodesc *, void **, void **, time_t, void *); static int rpc_getport(struct iodesc *, n_long, n_long); int rpc_xid; int rpc_port = 0x400; /* predecrement */ /* * Make a rpc call; return length of answer * Note: Caller must leave room for headers. */ ssize_t rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc, void *sdata, size_t slen, void **rdata, void **pkt) { ssize_t cc, rsize; struct auth_info *auth; struct rpc_call *call; struct rpc_reply *reply; char *send_head, *send_tail; void *ptr; n_long x; int port; /* host order */ #ifdef RPC_DEBUG if (debug) printf("rpc_call: prog=0x%x vers=%d proc=%d\n", prog, vers, proc); #endif port = rpc_getport(d, prog, vers); if (port == -1) return (-1); d->destport = htons(port); /* * Prepend authorization stuff and headers. * Note, must prepend things in reverse order. */ send_head = sdata; send_tail = (char *)sdata + slen; /* Auth verifier is always auth_null */ send_head -= sizeof(*auth); auth = (struct auth_info *)send_head; auth->authtype = htonl(RPCAUTH_NULL); auth->authlen = 0; /* Auth credentials: always auth unix (as root) */ send_head -= sizeof(struct auth_unix); bzero(send_head, sizeof(struct auth_unix)); send_head -= sizeof(*auth); auth = (struct auth_info *)send_head; auth->authtype = htonl(RPCAUTH_UNIX); auth->authlen = htonl(sizeof(struct auth_unix)); /* RPC call structure. */ send_head -= sizeof(*call); call = (struct rpc_call *)send_head; rpc_xid++; call->rp_xid = htonl(rpc_xid); call->rp_direction = htonl(RPC_CALL); call->rp_rpcvers = htonl(RPC_VER2); call->rp_prog = htonl(prog); call->rp_vers = htonl(vers); call->rp_proc = htonl(proc); ptr = NULL; cc = sendrecv(d, sendudp, send_head, send_tail - send_head, recvrpc, &ptr, (void **)&reply, NULL); #ifdef RPC_DEBUG if (debug) printf("callrpc: cc=%zd\n", cc); #endif if (cc == -1) return (-1); if (cc <= sizeof(*reply)) { errno = EBADRPC; free(ptr); return (-1); } /* * Check the RPC reply status. * The xid, dir, astatus were already checked. */ auth = &reply->rp_u.rpu_rok.rok_auth; x = ntohl(auth->authlen); if (x != 0) { #ifdef RPC_DEBUG if (debug) printf("callrpc: reply auth != NULL\n"); #endif errno = EBADRPC; free(ptr); return (-1); } x = ntohl(reply->rp_u.rpu_rok.rok_status); if (x != 0) { printf("callrpc: error = %ld\n", (long)x); errno = EBADRPC; free(ptr); return (-1); } rsize = cc - sizeof(*reply); *rdata = (void *)((uintptr_t)reply + sizeof(*reply)); *pkt = ptr; return (rsize); } /* * Returns true if packet is the one we're waiting for. * This just checks the XID, direction, acceptance. * Remaining checks are done by callrpc */ static ssize_t recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra __unused) { void *ptr; struct rpc_reply *reply; ssize_t n; int x; errno = 0; #ifdef RPC_DEBUG if (debug) printf("recvrpc: called\n"); #endif ptr = NULL; n = readudp(d, &ptr, (void **)&reply, tleft); if (n <= (4 * 4)) { free(ptr); return (-1); } x = ntohl(reply->rp_xid); if (x != rpc_xid) { #ifdef RPC_DEBUG if (debug) printf("recvrpc: rp_xid %d != xid %d\n", x, rpc_xid); #endif free(ptr); return (-1); } x = ntohl(reply->rp_direction); if (x != RPC_REPLY) { #ifdef RPC_DEBUG if (debug) printf("recvrpc: rp_direction %d != REPLY\n", x); #endif free(ptr); return (-1); } x = ntohl(reply->rp_astatus); if (x != RPC_MSGACCEPTED) { errno = ntohl(reply->rp_u.rpu_errno); printf("recvrpc: reject, astat=%d, errno=%d\n", x, errno); free(ptr); return (-1); } *pkt = ptr; *payload = reply; /* Return data count (thus indicating success) */ return (n); } /* * Given a pointer to a reply just received, * dig out the IP address/port from the headers. */ void rpc_fromaddr(void *pkt, struct in_addr *addr, u_short *port) { struct hackhdr { /* Tail of IP header: just IP addresses */ n_long ip_src; n_long ip_dst; /* UDP header: */ u_int16_t uh_sport; /* source port */ u_int16_t uh_dport; /* destination port */ int16_t uh_ulen; /* udp length */ u_int16_t uh_sum; /* udp checksum */ /* RPC reply header: */ struct rpc_reply rpc; } *hhdr; hhdr = ((struct hackhdr *)pkt) - 1; addr->s_addr = hhdr->ip_src; *port = hhdr->uh_sport; } /* * RPC Portmapper cache */ #define PMAP_NUM 8 /* need at most 5 pmap entries */ int rpc_pmap_num; struct pmap_list { struct in_addr addr; /* server, net order */ u_int prog; /* host order */ u_int vers; /* host order */ int port; /* host order */ } rpc_pmap_list[PMAP_NUM]; /* * return port number in host order, or -1. * arguments are: * addr .. server, net order. * prog .. host order. * vers .. host order. */ int rpc_pmap_getcache(struct in_addr addr, u_int prog, u_int vers) { struct pmap_list *pl; for (pl = rpc_pmap_list; pl < &rpc_pmap_list[rpc_pmap_num]; pl++) { if (pl->addr.s_addr == addr.s_addr && pl->prog == prog && pl->vers == vers ) { return (pl->port); } } return (-1); } /* * arguments are: * addr .. server, net order. * prog .. host order. * vers .. host order. * port .. host order. */ void rpc_pmap_putcache(struct in_addr addr, u_int prog, u_int vers, int port) { struct pmap_list *pl; /* Don't overflow cache... */ if (rpc_pmap_num >= PMAP_NUM) { /* ... just re-use the last entry. */ rpc_pmap_num = PMAP_NUM - 1; #ifdef RPC_DEBUG printf("rpc_pmap_putcache: cache overflow\n"); #endif } pl = &rpc_pmap_list[rpc_pmap_num]; rpc_pmap_num++; /* Cache answer */ pl->addr = addr; pl->prog = prog; pl->vers = vers; pl->port = port; } /* * Request a port number from the port mapper. * Returns the port in host order. * prog and vers are host order. */ int rpc_getport(struct iodesc *d, n_long prog, n_long vers) { struct args { n_long prog; /* call program */ n_long vers; /* call version */ n_long proto; /* call protocol */ n_long port; /* call port (unused) */ } *args; struct res { n_long port; } *res; struct { n_long h[RPC_HEADER_WORDS]; struct args d; } sdata; void *pkt; ssize_t cc; int port; #ifdef RPC_DEBUG if (debug) printf("%s: prog=0x%x vers=%d\n", __func__, prog, vers); #endif /* This one is fixed forever. */ if (prog == PMAPPROG) { port = PMAPPORT; goto out; } /* Try for cached answer first */ port = rpc_pmap_getcache(d->destip, prog, vers); if (port != -1) goto out; args = &sdata.d; args->prog = htonl(prog); args->vers = htonl(vers); args->proto = htonl(IPPROTO_UDP); args->port = 0; pkt = NULL; cc = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT, args, sizeof(*args), (void **)&res, &pkt); if (cc < sizeof(*res)) { printf("getport: %s", strerror(errno)); errno = EBADRPC; free(pkt); return (-1); } port = (int)ntohl(res->port); free(pkt); rpc_pmap_putcache(d->destip, prog, vers, port); out: #ifdef RPC_DEBUG if (debug) printf("%s: port=%u\n", __func__, port); #endif return (port); } /* $NetBSD: rpc.h,v 1.8 1996/09/26 23:22:03 cgd Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ /* XXX defines we can't easily get from system includes */ #define PMAPPORT 111 #define PMAPPROG 100000 #define PMAPVERS 2 #define PMAPPROC_NULL 0 #define PMAPPROC_SET 1 #define PMAPPROC_UNSET 2 #define PMAPPROC_GETPORT 3 #define PMAPPROC_DUMP 4 #define PMAPPROC_CALLIT 5 /* RPC functions: */ ssize_t rpc_call(struct iodesc *, n_long, n_long, n_long, void *, size_t, void **, void **); void rpc_fromaddr(void *, struct in_addr *, u_short *); int rpc_pmap_getcache(struct in_addr, u_int, u_int); void rpc_pmap_putcache(struct in_addr, u_int, u_int, int); extern int rpc_port; /* decrement before bind */ /* * How much space to leave in front of RPC requests. * In 32-bit words (alignment) we have: * 12: Ether + IP + UDP + padding * 6: RPC call header * 7: Auth UNIX * 2: Auth NULL */ #define RPC_HEADER_WORDS 28 /* $NetBSD: rpcv2.h,v 1.1 1996/02/26 23:05:32 gwr Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Macklem at The University of Guelph. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)rpcv2.h 8.1 (Berkeley) 6/10/93 * * $FreeBSD$ */ /* * Definitions for Sun RPC Version 2, from * "RPC: Remote Procedure Call Protocol Specification" RFC1057 */ /* Version # */ #define RPC_VER2 2 /* Authentication */ #define RPCAUTH_NULL 0 #define RPCAUTH_UNIX 1 #define RPCAUTH_SHORT 2 #define RPCAUTH_MAXSIZ 400 #define RPCAUTH_UNIXGIDS 16 /* Rpc Constants */ #define RPC_CALL 0 #define RPC_REPLY 1 #define RPC_MSGACCEPTED 0 #define RPC_MSGDENIED 1 #define RPC_PROGUNAVAIL 1 #define RPC_PROGMISMATCH 2 #define RPC_PROCUNAVAIL 3 #define RPC_GARBAGE 4 /* I like this one */ #define RPC_MISMATCH 0 #define RPC_AUTHERR 1 /* Authentication failures */ #define AUTH_BADCRED 1 #define AUTH_REJECTCRED 2 #define AUTH_BADVERF 3 #define AUTH_REJECTVERF 4 #define AUTH_TOOWEAK 5 /* Give em wheaties */ /* Sizes of rpc header parts */ #define RPC_SIZ 24 #define RPC_REPLYSIZ 28 /* RPC Prog definitions */ #define RPCPROG_MNT 100005 #define RPCMNT_VER1 1 #define RPCMNT_MOUNT 1 #define RPCMNT_DUMP 2 #define RPCMNT_UMOUNT 3 #define RPCMNT_UMNTALL 4 #define RPCMNT_EXPORT 5 #define RPCMNT_NAMELEN 255 #define RPCMNT_PATHLEN 1024 #define RPCPROG_NFS 100003 /* $NetBSD: saioctl.h,v 1.2 1994/10/26 05:45:04 cgd Exp $ */ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)saioctl.h 8.1 (Berkeley) 6/11/93 * * $FreeBSD$ */ /* ioctl's -- for disks just now */ #define SAIOHDR (('d'<<8)|1) /* next i/o includes header */ #define SAIOCHECK (('d'<<8)|2) /* next i/o checks data */ #define SAIOHCHECK (('d'<<8)|3) /* next i/o checks header & data */ #define SAIONOBAD (('d'<<8)|4) /* inhibit bad sector forwarding */ #define SAIODOBAD (('d'<<8)|5) /* enable bad sector forwarding */ #define SAIOECCLIM (('d'<<8)|6) /* set limit to ecc correction, bits */ #define SAIOECCUNL (('d'<<8)|7) /* use standard ecc procedures */ #define SAIORETRIES (('d'<<8)|8) /* set retry count for unit */ #define SAIODEVDATA (('d'<<8)|9) /* get pointer to pack label */ #define SAIOSSI (('d'<<8)|10) /* set skip sector inhibit */ #define SAIONOSSI (('d'<<8)|11) /* inhibit skip sector handling */ #define SAIOSSDEV (('d'<<8)|12) /* is device skip sector type? */ #define SAIODEBUG (('d'<<8)|13) /* enable/disable debugging */ #define SAIOGBADINFO (('d'<<8)|14) /* get bad-sector table */ /* * Copyright (c) 1998 Michael Smith * All rights reserved. * * 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. * * 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. */ #include /* * Minimal sbrk() emulation required for malloc support. */ #include #include "stand.h" #include "zalloc_defs.h" static size_t maxheap, heapsize = 0; static void *heapbase; void setheap(void *base, void *top) { /* Align start address for the malloc code. Sigh. */ heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) & ~MALLOCALIGN_MASK); maxheap = (char *)top - (char *)heapbase; } void * sbrk(intptr_t incr) { char *ret; if (heapbase == NULL) panic("No heap setup"); if ((heapsize + incr) <= maxheap) { ret = (char *)heapbase + heapsize; bzero(ret, incr); heapsize += incr; return (ret); } errno = ENOMEM; return ((char *)-1); } /* * Copyright (c) 2005-2009 Jung-uk Kim * All rights reserved. * * 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. * * 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. */ #include #include #include #include "smbios.h" /* * Detect SMBIOS and export information about the SMBIOS into the * environment. * * System Management BIOS Reference Specification, v2.6 Final * http://www.dmtf.org/standards/published_documents/DSP0134_2.6.0.pdf * System Management BIOS (SMBIOS) Reference Specification, v3.1.0 * http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.0.pdf */ /* * 2.1.1 SMBIOS Structure Table Entry Point * * "On non-EFI systems, the SMBIOS Entry Point structure, described below, can * be located by application software by searching for the anchor-string on * paragraph (16-byte) boundaries within the physical memory address range * 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor * string that is used by some existing DMI browsers." */ #define SMBIOS_START 0xf0000 #define SMBIOS_LENGTH 0x10000 #define SMBIOS_STEP 0x10 #define SMBIOS_SIG "_SM_" #define SMBIOS_SIG_LEN (4) #define SMBIOS3_SIG "_SM3_" #define SMBIOS3_SIG_LEN (5) #define SMBIOS_DMI_SIG "_DMI_" #define SMBIOS_DMI_SIG_LEN (5) #define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off))) #define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off))) #define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off))) #define SMBIOS_GET64(base, off) (*(uint64_t *)((base) + (off))) #define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01) #define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base)) struct smbios_attr { int probed; caddr_t addr; size_t length; size_t count; int major; int minor; int ver; const char* bios_vendor; const char* maker; const char* product; uint32_t enabled_memory; uint32_t old_enabled_memory; uint8_t enabled_sockets; uint8_t populated_sockets; }; static struct smbios_attr smbios; static uint8_t smbios_checksum(const caddr_t addr, const uint8_t len) { uint8_t sum; int i; for (sum = 0, i = 0; i < len; i++) sum += SMBIOS_GET8(addr, i); return (sum); } static caddr_t smbios_sigsearch(const caddr_t addr, const uint32_t len) { caddr_t cp; uintptr_t paddr; /* Search on 16-byte boundaries. */ for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) { if (strncmp(cp, SMBIOS_SIG, SMBIOS_SIG_LEN) == 0 && smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 && strncmp(cp + 0x10, SMBIOS_DMI_SIG, SMBIOS_DMI_SIG_LEN) == 0 && smbios_checksum(cp + 0x10, 0x0f) == 0) { /* Structure Table Length */ smbios.length = SMBIOS_GET16(cp, 0x16); /* Structure Table Address */ paddr = SMBIOS_GET32(cp, 0x18); /* No of SMBIOS Structures */ smbios.count = SMBIOS_GET16(cp, 0x1c); /* SMBIOS BCD Revision */ smbios.ver = SMBIOS_GET8(cp, 0x1e); if (smbios.ver != 0) { smbios.major = smbios.ver >> 4; smbios.minor = smbios.ver & 0x0f; if (smbios.major > 9 || smbios.minor > 9) smbios.ver = 0; } if (smbios.ver == 0) { /* SMBIOS Major Version */ smbios.major = SMBIOS_GET8(cp, 0x06); /* SMBIOS Minor Version */ smbios.minor = SMBIOS_GET8(cp, 0x07); } smbios.ver = (smbios.major << 8) | smbios.minor; smbios.addr = ptov(paddr); return (cp); } #ifdef _LP64 /* * Check for the SMBIOS 64-bit entry point introduced in * version 3.0. * * The table address is a 64-bit physical address that may * appear at any 64-bit address. We only search for * the 64-bit entry point when running a 64-bit application. */ if (strncmp(cp, SMBIOS3_SIG, SMBIOS3_SIG_LEN) == 0 && smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0) { /* SMBIOS Major Version */ smbios.major = SMBIOS_GET8(cp, 0x07); /* SMBIOS Minor Version */ smbios.minor = SMBIOS_GET8(cp, 0x08); /* Entry Point Revision */ smbios.ver = SMBIOS_GET8(cp, 0x0a); /* Structure Table maximum size */ smbios.length = SMBIOS_GET32(cp, 0x0c); /* Structure Table Address */ paddr = SMBIOS_GET64(cp, 0x10); smbios.addr = ptov(paddr); /* * Calculate upper limit for structure count, * use size of table header (4 bytes). */ smbios.count = smbios.length / 4; return (cp); } #endif } return (NULL); } static const char* smbios_getstring(caddr_t addr, const int offset) { caddr_t cp; int i, idx; idx = SMBIOS_GET8(addr, offset); if (idx != 0) { cp = SMBIOS_GETSTR(addr); for (i = 1; i < idx; i++) cp += strlen(cp) + 1; return cp; } return (NULL); } static void smbios_setenv(const char *name, caddr_t addr, const int offset) { const char* val; val = smbios_getstring(addr, offset); if (val != NULL) setenv(name, val, 1); } #ifdef SMBIOS_SERIAL_NUMBERS #define UUID_SIZE 16 #define UUID_TYPE uint32_t #define UUID_STEP sizeof(UUID_TYPE) #define UUID_ALL_BITS (UUID_SIZE / UUID_STEP) #define UUID_GET(base, off) (*(UUID_TYPE *)((base) + (off))) static void smbios_setuuid(const char *name, const caddr_t addr) { char uuid[37]; int byteorder, i, ones, zeros; UUID_TYPE n; uint32_t f1; uint16_t f2, f3; for (i = 0, ones = 0, zeros = 0; i < UUID_SIZE; i += UUID_STEP) { n = UUID_GET(addr, i) + 1; if (zeros == 0 && n == 0) ones++; else if (ones == 0 && n == 1) zeros++; else break; } if (ones != UUID_ALL_BITS && zeros != UUID_ALL_BITS) { /* * 3.3.2.1 System UUID * * "Although RFC 4122 recommends network byte order for all * fields, the PC industry (including the ACPI, UEFI, and * Microsoft specifications) has consistently used * little-endian byte encoding for the first three fields: * time_low, time_mid, time_hi_and_version. The same encoding, * also known as wire format, should also be used for the * SMBIOS representation of the UUID." * * Note: We use network byte order for backward compatibility * unless SMBIOS version is 2.6+ or little-endian is forced. */ #if defined(SMBIOS_LITTLE_ENDIAN_UUID) byteorder = LITTLE_ENDIAN; #elif defined(SMBIOS_NETWORK_ENDIAN_UUID) byteorder = BIG_ENDIAN; #else byteorder = ver < 0x0206 ? BIG_ENDIAN : LITTLE_ENDIAN; #endif if (byteorder != LITTLE_ENDIAN) { f1 = ntohl(SMBIOS_GET32(addr, 0)); f2 = ntohs(SMBIOS_GET16(addr, 4)); f3 = ntohs(SMBIOS_GET16(addr, 6)); } else { f1 = le32toh(SMBIOS_GET32(addr, 0)); f2 = le16toh(SMBIOS_GET16(addr, 4)); f3 = le16toh(SMBIOS_GET16(addr, 6)); } sprintf(uuid, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", f1, f2, f3, SMBIOS_GET8(addr, 8), SMBIOS_GET8(addr, 9), SMBIOS_GET8(addr, 10), SMBIOS_GET8(addr, 11), SMBIOS_GET8(addr, 12), SMBIOS_GET8(addr, 13), SMBIOS_GET8(addr, 14), SMBIOS_GET8(addr, 15)); setenv(name, uuid, 1); } } #undef UUID_SIZE #undef UUID_TYPE #undef UUID_STEP #undef UUID_ALL_BITS #undef UUID_GET #endif static caddr_t smbios_parse_table(const caddr_t addr) { caddr_t cp; int proc, size, osize, type; type = SMBIOS_GET8(addr, 0); /* 3.1.2 Structure Header Format */ switch(type) { case 0: /* 3.3.1 BIOS Information (Type 0) */ smbios_setenv("smbios.bios.vendor", addr, 0x04); smbios_setenv("smbios.bios.version", addr, 0x05); smbios_setenv("smbios.bios.reldate", addr, 0x08); break; case 1: /* 3.3.2 System Information (Type 1) */ smbios_setenv("smbios.system.maker", addr, 0x04); smbios_setenv("smbios.system.product", addr, 0x05); smbios_setenv("smbios.system.version", addr, 0x06); #ifdef SMBIOS_SERIAL_NUMBERS smbios_setenv("smbios.system.serial", addr, 0x07); smbios_setuuid("smbios.system.uuid", addr + 0x08); #endif if (smbios.major > 2 || (smbios.major == 2 && smbios.minor >= 4)) { smbios_setenv("smbios.system.sku", addr, 0x19); smbios_setenv("smbios.system.family", addr, 0x1a); } break; case 2: /* 3.3.3 Base Board (or Module) Information (Type 2) */ smbios_setenv("smbios.planar.maker", addr, 0x04); smbios_setenv("smbios.planar.product", addr, 0x05); smbios_setenv("smbios.planar.version", addr, 0x06); #ifdef SMBIOS_SERIAL_NUMBERS smbios_setenv("smbios.planar.serial", addr, 0x07); smbios_setenv("smbios.planar.tag", addr, 0x08); #endif smbios_setenv("smbios.planar.location", addr, 0x0a); break; case 3: /* 3.3.4 System Enclosure or Chassis (Type 3) */ smbios_setenv("smbios.chassis.maker", addr, 0x04); smbios_setenv("smbios.chassis.version", addr, 0x06); #ifdef SMBIOS_SERIAL_NUMBERS smbios_setenv("smbios.chassis.serial", addr, 0x07); smbios_setenv("smbios.chassis.tag", addr, 0x08); #endif break; case 4: /* 3.3.5 Processor Information (Type 4) */ /* * Offset 18h: Processor Status * * Bit 7 Reserved, must be 0 * Bit 6 CPU Socket Populated * 1 - CPU Socket Populated * 0 - CPU Socket Unpopulated * Bit 5:3 Reserved, must be zero * Bit 2:0 CPU Status * 0h - Unknown * 1h - CPU Enabled * 2h - CPU Disabled by User via BIOS Setup * 3h - CPU Disabled by BIOS (POST Error) * 4h - CPU is Idle, waiting to be enabled * 5-6h - Reserved * 7h - Other */ proc = SMBIOS_GET8(addr, 0x18); if ((proc & 0x07) == 1) smbios.enabled_sockets++; if ((proc & 0x40) != 0) smbios.populated_sockets++; break; case 6: /* 3.3.7 Memory Module Information (Type 6, Obsolete) */ /* * Offset 0Ah: Enabled Size * * Bit 7 Bank connection * 1 - Double-bank connection * 0 - Single-bank connection * Bit 6:0 Size (n), where 2**n is the size in MB * 7Dh - Not determinable (Installed Size only) * 7Eh - Module is installed, but no memory * has been enabled * 7Fh - Not installed */ osize = SMBIOS_GET8(addr, 0x0a) & 0x7f; if (osize > 0 && osize < 22) smbios.old_enabled_memory += 1 << (osize + 10); break; case 17: /* 3.3.18 Memory Device (Type 17) */ /* * Offset 0Ch: Size * * Bit 15 Granularity * 1 - Value is in kilobytes units * 0 - Value is in megabytes units * Bit 14:0 Size */ size = SMBIOS_GET16(addr, 0x0c); if (size != 0 && size != 0xffff) smbios.enabled_memory += (size & 0x8000) != 0 ? (size & 0x7fff) : (size << 10); break; default: /* skip other types */ break; } /* Find structure terminator. */ cp = SMBIOS_GETSTR(addr); while (SMBIOS_GET16(cp, 0) != 0) cp++; return (cp + 2); } static caddr_t smbios_find_struct(int type) { caddr_t dmi; size_t i; if (smbios.addr == NULL) return (NULL); for (dmi = smbios.addr, i = 0; dmi < smbios.addr + smbios.length && i < smbios.count; i++) { if (SMBIOS_GET8(dmi, 0) == type) return dmi; /* Find structure terminator. */ dmi = SMBIOS_GETSTR(dmi); while (SMBIOS_GET16(dmi, 0) != 0) dmi++; dmi += 2; } return (NULL); } static void smbios_probe(const caddr_t addr) { caddr_t info; const caddr_t paddr = addr != NULL ? addr : ptov(SMBIOS_START); if (smbios.probed) return; smbios.probed = 1; /* Search signatures and validate checksums. */ if (smbios_sigsearch(paddr, SMBIOS_LENGTH) == NULL) return; /* Get system information from SMBIOS */ info = smbios_find_struct(0x00); if (info != NULL) { smbios.bios_vendor = smbios_getstring(info, 0x04); } info = smbios_find_struct(0x01); if (info != NULL) { smbios.maker = smbios_getstring(info, 0x04); smbios.product = smbios_getstring(info, 0x05); } } void smbios_detect(const caddr_t addr) { char buf[16]; caddr_t dmi; size_t i; smbios_probe(addr); if (smbios.addr == NULL) return; for (dmi = smbios.addr, i = 0; dmi < smbios.addr + smbios.length && i < smbios.count; i++) dmi = smbios_parse_table(dmi); sprintf(buf, "%d.%d", smbios.major, smbios.minor); setenv("smbios.version", buf, 1); if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) { sprintf(buf, "%u", smbios.enabled_memory > 0 ? smbios.enabled_memory : smbios.old_enabled_memory); setenv("smbios.memory.enabled", buf, 1); } if (smbios.enabled_sockets > 0) { sprintf(buf, "%u", smbios.enabled_sockets); setenv("smbios.socket.enabled", buf, 1); } if (smbios.populated_sockets > 0) { sprintf(buf, "%u", smbios.populated_sockets); setenv("smbios.socket.populated", buf, 1); } } static int smbios_match_str(const char* s1, const char* s2) { return (s1 == NULL || (s2 != NULL && !strcmp(s1, s2))); } int smbios_match(const char* bios_vendor, const char* maker, const char* product) { /* XXXRP currently, only called from non-EFI. */ smbios_probe(NULL); return (smbios_match_str(bios_vendor, smbios.bios_vendor) && smbios_match_str(maker, smbios.maker) && smbios_match_str(product, smbios.product)); } /* * Copyright (c) 2015 Rui Paulo * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _SMBIOS_H_ #define _SMBIOS_H_ void smbios_detect(const caddr_t); int smbios_match(const char *, const char *, const char *); #endif /* _SMBIOS_H_ */ /* * Copyright (c) 1998 Michael Smith. * All rights reserved. * Copyright 2024 MNX Cloud, 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. * * 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. * * $FreeBSD$ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stand.h 8.1 (Berkeley) 6/11/93 */ #ifndef STAND_H #define STAND_H #include #include #include #include #include /* this header intentionally exports NULL from */ #include #define CHK(fmt, args...) \ printf("%s(%d): " fmt "\n", __func__, __LINE__, ##args) #define PCHK(fmt, args...) {\ printf("%s(%d): " fmt "\n", __func__, __LINE__, ##args); getchar();\ } /* Avoid unwanted userlandish components */ #define _KERNEL #include #undef _KERNEL /* special stand error codes */ #define EADAPT (ELAST+1) /* bad adaptor */ #define ECTLR (ELAST+2) /* bad controller */ #define EUNIT (ELAST+3) /* bad unit */ #define ESLICE (ELAST+4) /* bad slice */ #define EPART (ELAST+5) /* bad partition */ #define ERDLAB (ELAST+6) /* can't read disk label */ #define EUNLAB (ELAST+7) /* unlabeled disk */ #define EOFFSET (ELAST+8) /* relative seek not supported */ #define ESALAST (ELAST+8) /* */ struct open_file; /* * This structure is used to define file system operations in a file system * independent way. * * XXX note that filesystem providers should export a pointer to their fs_ops * struct, so that consumers can reference this and thus include the * filesystems that they require. */ struct fs_ops { const char *fs_name; int (*fo_open)(const char *path, struct open_file *f); int (*fo_close)(struct open_file *f); int (*fo_read)(struct open_file *f, void *buf, size_t size, size_t *resid); int (*fo_write)(struct open_file *f, const void *buf, size_t size, size_t *resid); off_t (*fo_seek)(struct open_file *f, off_t offset, int where); int (*fo_stat)(struct open_file *f, struct stat *sb); int (*fo_readdir)(struct open_file *f, struct dirent *d); }; /* * libsa-supplied filesystems */ extern struct fs_ops ufs_fsops; extern struct fs_ops tftp_fsops; extern struct fs_ops nfs_fsops; extern struct fs_ops cd9660_fsops; extern struct fs_ops gzipfs_fsops; extern struct fs_ops dosfs_fsops; /* where values for lseek(2) */ #define SEEK_SET 0 /* set file offset to offset */ #define SEEK_CUR 1 /* set file offset to current plus offset */ #define SEEK_END 2 /* set file offset to EOF plus offset */ /* * Device switch */ struct devsw { const char dv_name[8]; int dv_type; /* opaque type constant, arch-dependant */ #define DEVT_NONE 0 #define DEVT_DISK 1 #define DEVT_NET 2 #define DEVT_CD 3 #define DEVT_ZFS 4 #define DEVT_FD 5 int (*dv_init)(void); /* early probe call */ int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); int (*dv_open)(struct open_file *f, ...); int (*dv_close)(struct open_file *f); int (*dv_ioctl)(struct open_file *f, ulong_t cmd, void *data); int (*dv_print)(int verbose); /* print device information */ void (*dv_cleanup)(void); }; /* * libstand-supplied device switch */ extern struct devsw netdev; extern int errno; /* * Generic device specifier; architecture-dependent * versions may be larger, but should be allowed to * overlap. */ struct devdesc { struct devsw *d_dev; int d_unit; void *d_opendata; }; struct open_file { int f_flags; /* see F_* below */ struct devsw *f_dev; /* pointer to device operations */ void *f_devdata; /* device specific data */ struct fs_ops *f_ops; /* pointer to file system operations */ void *f_fsdata; /* file system specific data */ off_t f_offset; /* current file offset */ char *f_rabuf; /* readahead buffer pointer */ size_t f_ralen; /* valid data in readahead buffer */ off_t f_raoffset; /* consumer offset in readahead buffer */ int f_id; /* file number */ TAILQ_ENTRY(open_file) f_link; /* next entry */ #define SOPEN_RASIZE 512 }; typedef TAILQ_HEAD(file_list, open_file) file_list_t; extern file_list_t files; extern struct open_file *fd2open_file(int); /* f_flags values */ #define F_READ 0x0001 /* file opened for reading */ #define F_WRITE 0x0002 /* file opened for writing */ #define F_RAW 0x0004 /* raw device open - no file system */ #define F_NODEV 0x0008 /* network open - no device */ #define F_GZIP 0x0010 /* file is compressed by gzip */ #define F_MASK 0xFFFF /* Mode modifier for strategy() */ #define F_NORA (0x01 << 16) /* Disable Read-Ahead */ #define isascii(c) (((c) & ~0x7F) == 0) static __inline int isupper(int c) { return (c >= 'A' && c <= 'Z'); } static __inline int islower(int c) { return (c >= 'a' && c <= 'z'); } static __inline int isspace(int c) { return (c == ' ' || (c >= 0x9 && c <= 0xd)); } static __inline int isdigit(int c) { return (c >= '0' && c <= '9'); } static __inline int isxdigit(int c) { return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); } static __inline int isalpha(int c) { return (isupper(c) || islower(c)); } static __inline int isalnum(int c) { return (isalpha(c) || isdigit(c)); } static __inline int iscntrl(int c) { return ((c >= 0 && c < ' ') || c == 127); } static __inline int isgraph(int c) { return (c >= '!' && c <= '~'); } static __inline int ispunct(int c) { return ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~')); } static __inline int toupper(int c) { return (islower(c) ? c - 'a' + 'A' : c); } static __inline int tolower(int c) { return (isupper(c) ? c - 'A' + 'a' : c); } /* sbrk emulation */ extern void setheap(void *base, void *top); /* * Hammerhead: match GCC 14's builtin sbrk signature (void *sbrk(intptr_t)) and * illumos upstream; the old K&R-style `char *sbrk(int)` triggers * -Werror=builtin-declaration-mismatch even under -fno-builtin. */ extern void *sbrk(intptr_t incr); extern void mallocstats(void); const char *x86_hypervisor(void); extern int printf(const char *fmt, ...) __printflike(1, 2); extern void vprintf(const char *fmt, __va_list); extern int asprintf(char **buf, const char *cfmt, ...) __printflike(2, 3); extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3); extern int snprintf(char *buf, size_t size, const char *cfmt, ...) \ __printflike(3, 4); extern void vsprintf(char *buf, const char *cfmt, __va_list); extern void vsnprintf(char *buf, size_t size, const char *cfmt, __va_list); extern void twiddle(uint_t callerdiv); extern void twiddle_divisor(uint_t globaldiv); extern void ngets(char *, int); #define gets(x) ngets((x), 0) extern int fgetstr(char *buf, int size, int fd); extern int open(const char *, int); #define O_RDONLY 0x0 #define O_WRONLY 0x1 #define O_RDWR 0x2 extern int close(int); extern void closeall(void); extern ssize_t read(int, void *, size_t); extern ssize_t write(int, const void *, size_t); extern struct dirent *readdirfd(int); extern void srandom(ulong_t seed); extern ulong_t random(void); extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt, optreset; extern int getopt(int, char * const [], const char *); /* pager.c */ extern void pager_open(void); extern void pager_close(void); extern int pager_output(const char *lines); extern int pager_file(const char *fname); /* No signal state to preserve */ #define setjmp _setjmp #define longjmp _longjmp /* environment.c */ /* value was dynamically allocated, free if changed/unset */ #define EV_DYNAMIC (1<<0) /* value is volatile, make a copy of it */ #define EV_VOLATILE (1<<1) /* don't call hook when setting */ #define EV_NOHOOK (1<<2) struct env_var; typedef char *(ev_format_t)(struct env_var *ev); typedef int (ev_sethook_t)(struct env_var *ev, int flags, const void *value); typedef int (ev_unsethook_t)(struct env_var *ev); struct env_var { char *ev_name; int ev_flags; void *ev_value; ev_sethook_t *ev_sethook; ev_unsethook_t *ev_unsethook; struct env_var *ev_next, *ev_prev; }; extern struct env_var *environ; extern struct env_var *env_getenv(const char *name); extern int env_setenv(const char *name, int flags, const void *value, ev_sethook_t sethook, ev_unsethook_t unsethook); extern void env_discard(struct env_var *); extern char *getenv(const char *name); extern int setenv(const char *name, const char *value, int overwrite); extern int putenv(const char *string); extern int unsetenv(const char *name); extern ev_sethook_t env_noset; /* refuse set operation */ extern ev_unsethook_t env_nounset; /* refuse unset operation */ /* stdlib.h routines */ extern long strtol(const char *__restrict, char **__restrict, int); extern long long strtoll(const char *__restrict, char **__restrict, int); extern unsigned long strtoul(const char *__restrict, char **__restrict, int); extern unsigned long long strtoull(const char *__restrict, char **__restrict, int); /* BCD conversions (undocumented) */ extern uchar_t const bcd2bin_data[]; extern uchar_t const bin2bcd_data[]; extern char const hex2ascii_data[]; #define bcd2bin(bcd) (bcd2bin_data[bcd]) #define bin2bcd(bin) (bin2bcd_data[bin]) #define hex2ascii(hex) (hex2ascii_data[hex]) /* min/max (undocumented) */ static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline long lmax(long a, long b) { return (a > b ? a : b); } static __inline long lmin(long a, long b) { return (a < b ? a : b); } static __inline uint_t max(uint_t a, uint_t b) { return (a > b ? a : b); } static __inline uint_t min(uint_t a, uint_t b) { return (a < b ? a : b); } static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); } static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); } static __inline ulong_t ulmax(ulong_t a, ulong_t b) { return (a > b ? a : b); } static __inline ulong_t ulmin(ulong_t a, ulong_t b) { return (a < b ? a : b); } /* null functions for device/filesystem switches (undocumented) */ extern int nodev(void); extern int noioctl(struct open_file *, ulong_t, void *); extern void nullsys(void); extern int null_open(const char *, struct open_file *); extern int null_close(struct open_file *); extern int null_read(struct open_file *, void *, size_t, size_t *); extern int null_write(struct open_file *, const void *, size_t, size_t *); extern off_t null_seek(struct open_file *, off_t, int); extern int null_stat(struct open_file *, struct stat *); extern int null_readdir(struct open_file *, struct dirent *); /* * Machine dependent functions and data, must be provided or stubbed by * the consumer */ extern void exit(int) __dead2; extern int getchar(void); extern int ischar(void); extern void putchar(int); extern int devopen(struct open_file *, const char *, const char **); extern int devclose(struct open_file *f); extern void panic(const char *, ...) __dead2 __printflike(1, 2); extern void panic_action(void) __weak_symbol __dead2; extern time_t getsecs(void); extern struct fs_ops *file_system[]; extern struct fs_ops *exclusive_file_system; extern struct devsw *devsw[]; /* * Expose byteorder(3) functions. */ #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED extern uint32_t htonl(uint32_t); extern uint16_t htons(uint16_t); extern uint32_t ntohl(uint32_t); extern uint16_t ntohs(uint16_t); #endif #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif void *Malloc(size_t, const char *, int); void *Memalign(size_t, size_t, const char *, int); void *Calloc(size_t, size_t, const char *, int); void *Realloc(void *, size_t, const char *, int); void *Reallocf(void *, size_t, const char *, int); void Free(void *, const char *, int); #if DEBUG_MALLOC #define malloc(x) Malloc(x, __FILE__, __LINE__) #define memalign(x, y) Memalign(x, y, __FILE__, __LINE__) #define calloc(x, y) Calloc(x, y, __FILE__, __LINE__) #define free(x) Free(x, __FILE__, __LINE__) #define realloc(x, y) Realloc(x, y, __FILE__, __LINE__) #define reallocf(x, y) Reallocf(x, y, __FILE__, __LINE__) #else #define malloc(x) Malloc(x, NULL, 0) #define memalign(x, y) Memalign(x, y, NULL, 0) #define calloc(x, y) Calloc(x, y, NULL, 0) #define free(x) Free(x, NULL, 0) #define realloc(x, y) Realloc(x, y, NULL, 0) #define reallocf(x, y) Reallocf(x, y, NULL, 0) #endif /* * va <-> pa routines. MD code must supply. */ caddr_t ptov(uintptr_t); #endif /* STAND_H */ /* $NetBSD: stat.c,v 1.4 1996/01/13 22:25:43 leo Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stat.c 8.1 (Berkeley) 6/11/93 */ #include #include "stand.h" int stat(const char *str, struct stat *sb) { int fd, rv; fd = open(str, O_RDONLY); if (fd < 0) return (-1); rv = fstat(fd, sb); (void) close(fd); return (rv); } /* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include #include #include "stand.h" int strcasecmp(const char *s1, const char *s2) { const uchar_t *us1 = (const uchar_t *)s1; const uchar_t *us2 = (const uchar_t *)s2; while (tolower(*us1) == tolower(*us2++)) if (*us1++ == '\0') return (0); return (tolower(*us1) - tolower(*--us2)); } int strncasecmp(const char *s1, const char *s2, size_t n) { if (n != 0) { const uchar_t *us1 = (const uchar_t *)s1; const uchar_t *us2 = (const uchar_t *)s2; do { if (tolower(*us1) != tolower(*us2++)) return (tolower(*us1) - tolower(*--us2)); if (*us1++ == '\0') break; } while (--n != 0); } return (0); } /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include "stand.h" #include #include char * strdup(const char *str) { size_t len; char *copy = NULL; if (str != NULL) { len = strlen(str) + 1; if ((copy = malloc(len)) == NULL) return (NULL); memcpy(copy, str, len); } return (copy); } /* $NetBSD: strerror.c,v 1.12 1997/01/25 00:37:50 cgd Exp $ */ /*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include __FBSDID("$FreeBSD$"); #include "stand.h" static struct { int err; char *msg; } errtab[] = { {0, "no error"}, /* standard errors */ {EPERM, "operation not permitted"}, {ENOENT, "no such file or directory"}, {EIO, "input/output error"}, {ENXIO, "device not configured"}, {ENOEXEC, "exec format error"}, {EBADF, "bad file descriptor"}, {ENOMEM, "cannot allocate memory"}, {ENODEV, "operation not supported by device"}, {ENOTDIR, "not a directory"}, {EISDIR, "is a directory"}, {EINVAL, "invalid argument"}, {EMFILE, "too many open files"}, {EFBIG, "file too large"}, {EROFS, "read-only filesystem"}, {EOPNOTSUPP, "operation not supported"}, {ETIMEDOUT, "operation timed out"}, {ESTALE, "stale NFS file handle"}, {EBADRPC, "RPC struct is bad"}, {EFTYPE, "inappropriate file type or format"}, {EADAPT, "bad adaptor number"}, {ECTLR, "bad controller number"}, {EUNIT, "bad unit number"}, {ESLICE, "bad slice number"}, {EPART, "bad partition"}, {ERDLAB, "can't read disk label"}, {EUNLAB, "disk unlabelled"}, {EOFFSET, "illegal seek"}, {0, NULL} }; char * strerror(int err) { static char msg[32]; int i; for (i = 0; errtab[i].msg != NULL; i++) if (errtab[i].err == err) return(errtab[i].msg); sprintf(msg, "unknown error (%d)", err); return(msg); } /* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * bcmp -- vax cmpc3 instruction */ int bcmp(const void *b1, const void *b2, size_t length) { char *p1, *p2; if (length == 0) return (0); p1 = (char *)b1; p2 = (char *)b2; do if (*p1++ != *p2++) break; while (--length); return (length); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * sizeof(word) MUST BE A POWER OF TWO * SO THAT wmask BELOW IS ALL ONES */ typedef int word; /* "word" used for optimal copy speed */ #define wsize sizeof(word) #define wmask (wsize - 1) /* * Copy a block of memory, handling overlap. * This is the routine that actually implements * (the portable versions of) bcopy, memcpy, and memmove. */ #if defined(MEMCOPY) || defined(MEMMOVE) #include void * #ifdef MEMCOPY memcpy #else memmove #endif (void *dst0, const void *src0, size_t length) #else #include void bcopy(const void *src0, void *dst0, size_t length) #endif { char *dst = dst0; const char *src = src0; size_t t; if (length == 0 || dst == src) /* nothing to do */ goto done; /* * Macros: loop-t-times; and loop-t-times, t>0 */ #define TLOOP(s) if (t) TLOOP1(s) #define TLOOP1(s) do { s; } while (--t) if ((unsigned long)dst < (unsigned long)src) { /* * Copy forward. */ t = (uintptr_t)src; /* only need low bits */ if ((t | (uintptr_t)dst) & wmask) { /* * Try to align operands. This cannot be done * unless the low bits match. */ if ((t ^ (uintptr_t)dst) & wmask || length < wsize) t = length; else t = wsize - (t & wmask); length -= t; TLOOP1(*dst++ = *src++); } /* * Copy whole words, then mop up any trailing bytes. */ t = length / wsize; TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); t = length & wmask; TLOOP(*dst++ = *src++); } else { /* * Copy backwards. Otherwise essentially the same. * Alignment works as before, except that it takes * (t&wmask) bytes to align, not wsize-(t&wmask). */ src += length; dst += length; t = (uintptr_t)src; if ((t | (uintptr_t)dst) & wmask) { if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) t = length; else t &= wmask; length -= t; TLOOP1(*--dst = *--src); } t = length / wsize; TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); t = length & wmask; TLOOP(*--dst = *--src); } done: #if defined(MEMCOPY) || defined(MEMMOVE) return (dst0); #else return; #endif } #include __FBSDID("$FreeBSD$"); #define BZERO #include "memset.c" /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ffs.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Find First Set bit */ int ffs(int mask) { int bit; if (mask == 0) return(0); for (bit = 1; !(mask & 1); bit++) mask = (unsigned int)mask >> 1; return (bit); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include __FBSDID("$FreeBSD$"); #include /* * Find Last Set bit */ int fls(int mask) { int bit; if (mask == 0) return (0); for (bit = 1; mask != 1; bit++) mask = (unsigned int)mask >> 1; return (bit); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include void * memccpy(void *t, const void *f, int c, size_t n) { if (n) { unsigned char *tp = t; const unsigned char *fp = f; unsigned char uc = c; do { if ((*tp++ = *fp++) == uc) return (tp); } while (--n != 0); } return (0); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include void * memchr(const void *s, int c, size_t n) { if (n != 0) { const unsigned char *p = s; do { if (*p++ == (unsigned char)c) return ((void *)(p - 1)); } while (--n != 0); } return (NULL); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Compare memory regions. */ int memcmp(const void *s1, const void *s2, size_t n) { if (n != 0) { const unsigned char *p1 = s1, *p2 = s2; do { if (*p1++ != *p2++) return (*--p1 - *--p2); } while (--n != 0); } return (0); } #include __FBSDID("$FreeBSD$"); #define MEMCOPY #include "bcopy.c" #include __FBSDID("$FreeBSD$"); #define MEMMOVE #include "bcopy.c" /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Hibler and Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #define wsize sizeof(u_int) #define wmask (wsize - 1) #ifdef BZERO #include #define RETURN return #define VAL 0 #define WIDEVAL 0 void bzero(void *dst0, size_t length) #else #include #define RETURN return (dst0) #define VAL c0 #define WIDEVAL c void * memset(void *dst0, int c0, size_t length) #endif { size_t t; #ifndef BZERO u_int c; #endif u_char *dst; dst = dst0; /* * If not enough words, just fill bytes. A length >= 2 words * guarantees that at least one of them is `complete' after * any necessary alignment. For instance: * * |-----------|-----------|-----------| * |00|01|02|03|04|05|06|07|08|09|0A|00| * ^---------------------^ * dst dst+length-1 * * but we use a minimum of 3 here since the overhead of the code * to do word writes is substantial. */ if (length < 3 * wsize) { while (length != 0) { *dst++ = VAL; --length; } RETURN; } #ifndef BZERO if ((c = (u_char)c0) != 0) { /* Fill the word. */ c = (c << 8) | c; /* u_int is 16 bits. */ #if UINT_MAX > 0xffff c = (c << 16) | c; /* u_int is 32 bits. */ #endif #if UINT_MAX > 0xffffffff c = (c << 32) | c; /* u_int is 64 bits. */ #endif } #endif /* Align destination by filling in bytes. */ if ((t = (long)dst & wmask) != 0) { t = wsize - t; length -= t; do { *dst++ = VAL; } while (--t != 0); } /* Fill words. Length was >= 2*words so we know t >= 1 here. */ t = length / wsize; do { *(u_int *)dst = WIDEVAL; dst += wsize; } while (--t != 0); /* Mop up trailing bytes, if any. */ t = length & wmask; if (t != 0) do { *dst++ = VAL; } while (--t != 0); RETURN; } /* * Copyright (c) 1999 * David E. O'Brien * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #include #include char * stpcpy(char * __restrict to, const char * __restrict from) { for (; (*to = *from); ++from, ++to); return (to); } /* * Copyright (c) 2009 David Schultz * All rights reserved. * * 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. * * 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. */ #include #include char * stpncpy(char * __restrict dst, const char * __restrict src, size_t n) { for (; n--; dst++, src++) { if (!(*dst = *src)) { char *ret = dst; while (n--) *++dst = '\0'; return (ret); } } return (dst); } /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include char * strcat(char * __restrict s, const char * __restrict append) { char *save = s; for (; *s; ++s); while ((*s++ = *append++)); return(save); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)index.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include char * strchr(const char *p, int ch) { char c; c = ch; for (;; ++p) { if (*p == c) return ((char *)p); if (*p == '\0') return (NULL); } /* NOTREACHED */ } __weak_reference(strchr, index); /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Compare strings. */ int strcmp(const char *s1, const char *s2) { while (*s1 == *s2++) if (*s1++ == '\0') return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); } /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include char * strcpy(char * __restrict to, const char * __restrict from) { char *save = to; for (; (*to = *from); ++from, ++to); return(save); } /*- * Copyright (c) 2005 David Schultz * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #define IDX(c) ((u_char)(c) / LONG_BIT) #define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) size_t strcspn(const char *s, const char *charset) { /* * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to * generate better code. Without them, gcc gets a little confused. */ const char *s1; u_long bit; u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; int idx; if(*s == '\0') return (0); #if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ tbl[0] = 1; tbl[3] = tbl[2] = tbl[1] = 0; #else for (tbl[0] = idx = 1; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) tbl[idx] = 0; #endif for (; *charset != '\0'; charset++) { idx = IDX(*charset); bit = BIT(*charset); tbl[idx] |= bit; } for(s1 = s; ; s1++) { idx = IDX(*s1); bit = BIT(*s1); if ((tbl[idx] & bit) != 0) break; } return (s1 - s); } /* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */ /* * Copyright (c) 1998, 2015 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include __FBSDID("$FreeBSD$"); #include #include /* * Appends src to string dst of size dsize (unlike strncat, dsize is the * full size of dst, not space left). At most dsize-1 characters * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). * Returns strlen(src) + MIN(dsize, strlen(initial dst)). * If retval >= dsize, truncation occurred. */ size_t strlcat(char * __restrict dst, const char * __restrict src, size_t dsize) { const char *odst = dst; const char *osrc = src; size_t n = dsize; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end. */ while (n-- != 0 && *dst != '\0') dst++; dlen = dst - odst; n = dsize - dlen; if (n-- == 0) return(dlen + strlen(src)); while (*src != '\0') { if (n != 0) { *dst++ = *src; n--; } src++; } *dst = '\0'; return(dlen + (src - osrc)); /* count does not include NUL */ } /* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */ /* * Copyright (c) 1998, 2015 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include __FBSDID("$FreeBSD$"); #include #include /* * Copy string src to buffer dst of size dsize. At most dsize-1 * chars will be copied. Always NUL terminates (unless dsize == 0). * Returns strlen(src); if retval >= dsize, truncation occurred. */ size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize) { const char *osrc = src; size_t nleft = dsize; /* Copy as many bytes as will fit. */ if (nleft != 0) { while (--nleft != 0) { if ((*dst++ = *src++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src. */ if (nleft == 0) { if (dsize != 0) *dst = '\0'; /* NUL-terminate dst */ while (*src++) ; } return(src - osrc - 1); /* count does not include NUL */ } /*- * Copyright (c) 2009, 2010 Xin LI * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include /* * Portable strlen() for 32-bit and 64-bit systems. * * Rationale: it is generally much more efficient to do word length * operations and avoid branches on modern computer systems, as * compared to byte-length operations with a lot of branches. * * The expression: * * ((x - 0x01....01) & ~x & 0x80....80) * * would evaluate to a non-zero value iff any of the bytes in the * original word is zero. * * On multi-issue processors, we can divide the above expression into: * a) (x - 0x01....01) * b) (~x & 0x80....80) * c) a & b * * Where, a) and b) can be partially computed in parallel. * * The algorithm above is found on "Hacker's Delight" by * Henry S. Warren, Jr. */ /* Magic numbers for the algorithm */ #if LONG_BIT == 32 static const unsigned long mask01 = 0x01010101; static const unsigned long mask80 = 0x80808080; #elif LONG_BIT == 64 static const unsigned long mask01 = 0x0101010101010101; static const unsigned long mask80 = 0x8080808080808080; #else #error Unsupported word size #endif #define LONGPTR_MASK (sizeof(long) - 1) /* * Helper macro to return string length if we caught the zero * byte. */ #define testbyte(x) \ do { \ if (p[x] == '\0') \ return (p - str + x); \ } while (0) size_t strlen(const char *str) { const char *p; const unsigned long *lp; long va, vb; /* * Before trying the hard (unaligned byte-by-byte access) way * to figure out whether there is a nul character, try to see * if there is a nul character is within this accessible word * first. * * p and (p & ~LONGPTR_MASK) must be equally accessible since * they always fall in the same memory page, as long as page * boundaries is integral multiple of word size. */ lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK); va = (*lp - mask01); vb = ((~*lp) & mask80); lp++; if (va & vb) /* Check if we have \0 in the first part */ for (p = str; p < (const char *)lp; p++) if (*p == '\0') return (p - str); /* Scan the rest of the string using word sized operation */ for (; ; lp++) { va = (*lp - mask01); vb = ((~*lp) & mask80); if (va & vb) { p = (const char *)(lp); testbyte(0); testbyte(1); testbyte(2); testbyte(3); #if (LONG_BIT >= 64) testbyte(4); testbyte(5); testbyte(6); testbyte(7); #endif } } /* NOTREACHED */ return (0); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strncat.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes * are written at dst (at most n+1 bytes being appended). Return dst. */ char * strncat(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; const char *s = src; while (*d != 0) d++; do { if ((*d = *s++) == 0) break; d++; } while (--n != 0); *d = 0; } return (dst); } /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include int strncmp(const char *s1, const char *s2, size_t n) { if (n == 0) return (0); do { if (*s1 != *s2++) return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); if (*s1++ == '\0') break; } while (--n != 0); return (0); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strncpy.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Copy src to dst, truncating or null-padding to always copy n bytes. * Return dst. */ char * strncpy(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; const char *s = src; do { if ((*d++ = *s++) == '\0') { /* NUL pad the remaining n-1 bytes */ while (--n != 0) *d++ = '\0'; break; } } while (--n != 0); } return (dst); } /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2009 David Schultz * All rights reserved. * * 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. * * 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. */ #include #include size_t strnlen(const char *s, size_t maxlen) { size_t len; for (len = 0; len < maxlen; len++, s++) { if (*s == '\0') break; } return (len); } /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strpbrk.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Find the first occurrence in s1 of a character in s2 (excluding NUL). */ char * strpbrk(const char *s1, const char *s2) { const char *scanp; int c, sc; while ((c = *s1++) != 0) { for (scanp = s2; (sc = *scanp++) != '\0';) if (sc == c) return ((char *)(s1 - 1)); } return (NULL); } /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)rindex.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include char * strrchr(const char *p, int ch) { char *save; char c; c = ch; for (save = NULL;; ++p) { if (*p == c) save = (char *)p; if (*p == '\0') return (save); } /* NOTREACHED */ } __weak_reference(strrchr, rindex); /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * strsep(char **stringp, const char *delim) { char *s; const char *spanp; int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } /*- * Copyright (c) 2005 David Schultz * All rights reserved. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #define IDX(c) ((u_char)(c) / LONG_BIT) #define BIT(c) ((u_long)1 << ((u_char)(c) % LONG_BIT)) size_t strspn(const char *s, const char *charset) { /* * NB: idx and bit are temporaries whose use causes gcc 3.4.2 to * generate better code. Without them, gcc gets a little confused. */ const char *s1; u_long bit; u_long tbl[(UCHAR_MAX + 1) / LONG_BIT]; int idx; if(*s == '\0') return (0); #if LONG_BIT == 64 /* always better to unroll on 64-bit architectures */ tbl[3] = tbl[2] = tbl[1] = tbl[0] = 0; #else for (idx = 0; idx < sizeof(tbl) / sizeof(tbl[0]); idx++) tbl[idx] = 0; #endif for (; *charset != '\0'; charset++) { idx = IDX(*charset); bit = BIT(*charset); tbl[idx] |= bit; } for(s1 = s; ; s1++) { idx = IDX(*s1); bit = BIT(*s1); if ((tbl[idx] & bit) == 0) break; } return (s1 - s); } /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include /* * Find the first occurrence of find in s. */ char * strstr(const char *s, const char *find) { char c, sc; size_t len; if ((c = *find++) != '\0') { len = strlen(find); do { do { if ((sc = *s++) == '\0') return (NULL); } while (sc != c); } while (strncmp(s, find, len) != 0); s--; } return ((char *)s); } /*- * Copyright (c) 1998 Softweyr LLC. All rights reserved. * * strtok_r, from Berkeley strtok * Oct 13, 1998 by Wes Peters * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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 * notices, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS 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 SOFTWEYR LLC, THE * REGENTS, 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtok.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #ifdef DEBUG_STRTOK #include #endif #include char *__strtok_r(char *, const char *, char **); __weak_reference(__strtok_r, strtok_r); char * __strtok_r(char *s, const char *delim, char **last) { char *spanp, *tok; int c, sc; if (s == NULL && (s = *last) == NULL) return (NULL); /* * Skip (span) leading delimiters (s += strspn(s, delim), sort of). */ cont: c = *s++; for (spanp = (char *)delim; (sc = *spanp++) != 0;) { if (c == sc) goto cont; } if (c == 0) { /* no non-delimiter characters */ *last = NULL; return (NULL); } tok = s - 1; /* * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). * Note that delim must have one NUL; we stop if we see that, too. */ for (;;) { c = *s++; spanp = (char *)delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = '\0'; *last = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } char * strtok(char *s, const char *delim) { static char *last; return (__strtok_r(s, delim, &last)); } #ifdef DEBUG_STRTOK /* * Test the tokenizer. */ int main(void) { char blah[80], test[80]; char *brkb, *brkt, *phrase, *sep, *word; sep = "\\/:;=-"; phrase = "foo"; printf("String tokenizer test:\n"); strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function."); for (word = strtok(test, sep); word; word = strtok(NULL, sep)) printf("Next word is \"%s\".\n", word); strcpy(test, "This;is.a:test:of=the/string\\tokenizer-function."); for (word = strtok_r(test, sep, &brkt); word; word = strtok_r(NULL, sep, &brkt)) { strcpy(blah, "blah:blat:blab:blag"); for (phrase = strtok_r(blah, sep, &brkb); phrase; phrase = strtok_r(NULL, sep, &brkb)) printf("So far we're at %s:%s\n", word, phrase); } return (0); } #endif /* DEBUG_STRTOK */ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Jeffrey Mogul. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include void swab(const void * __restrict from, void * __restrict to, ssize_t len) { unsigned long temp; int n; char *fp, *tp; if (len <= 0) return; n = len >> 1; fp = (char *)from; tp = (char *)to; #define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp /* round to multiple of 8 */ for (; n & 0x7; --n) STEP; for (n >>= 3; n > 0; --n) { STEP; STEP; STEP; STEP; STEP; STEP; STEP; STEP; } } /* $NetBSD: tftp.c,v 1.4 1997/09/17 16:57:07 drochner Exp $ */ /* * Copyright (c) 1996 * Matthias Drochner. All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project * by Matthias Drochner. * 4. 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 ``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 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. */ #include /* * Simple TFTP implementation for libsa. * Assumes: * - socket descriptor (int) at dev->d_opendata, dev stored at * open_file->f_devdata * - server host IP in global rootip * Restrictions: * - read only * - lseek only with SEEK_SET or SEEK_CUR * - no big time differences between transfers ( #include #include #include #include #include #include #include "stand.h" #include "net.h" #include "netif.h" #include "tftp.h" struct tftp_handle; struct tftprecv_extra; static ssize_t recvtftp(struct iodesc *, void **, void **, time_t, void *); static int tftp_open(const char *, struct open_file *); static int tftp_close(struct open_file *); static int tftp_parse_oack(struct tftp_handle *, char *, size_t); static int tftp_read(struct open_file *, void *, size_t, size_t *); static off_t tftp_seek(struct open_file *, off_t, int); static int tftp_set_blksize(struct tftp_handle *, const char *); static int tftp_stat(struct open_file *, struct stat *); struct fs_ops tftp_fsops = { .fs_name = "tftp", .fo_open = tftp_open, .fo_close = tftp_close, .fo_read = tftp_read, .fo_write = null_write, .fo_seek = tftp_seek, .fo_stat = tftp_stat, .fo_readdir = null_readdir }; static int tftpport = 2000; static int is_open = 0; /* * The legacy TFTP_BLKSIZE value was SEGSIZE(512). * TFTP_REQUESTED_BLKSIZE of 1428 is (Ethernet MTU, less the TFTP, UDP and * IP header lengths). */ #define TFTP_REQUESTED_BLKSIZE 1428 /* * Choose a blksize big enough so we can test with Ethernet * Jumbo frames in the future. */ #define TFTP_MAX_BLKSIZE 9008 struct tftp_handle { struct iodesc *iodesc; int currblock; /* contents of lastdata */ int islastblock; /* flag */ int validsize; int off; char *path; /* saved for re-requests */ unsigned int tftp_blksize; unsigned long tftp_tsize; void *pkt; struct tftphdr *tftp_hdr; }; struct tftprecv_extra { struct tftp_handle *tftp_handle; unsigned short rtype; /* Received type */ }; #define TFTP_MAX_ERRCODE EOPTNEG static const int tftperrors[TFTP_MAX_ERRCODE + 1] = { 0, /* ??? */ ENOENT, EPERM, ENOSPC, EINVAL, /* ??? */ EINVAL, /* ??? */ EEXIST, EINVAL, /* ??? */ EINVAL, /* Option negotiation failed. */ }; static int tftp_getnextblock(struct tftp_handle *h); /* send error message back. */ static void tftp_senderr(struct tftp_handle *h, ushort_t errcode, const char *msg) { struct { uchar_t header[HEADER_SIZE]; struct tftphdr t; uchar_t space[63]; /* +1 from t */ } __packed __aligned(4) wbuf; char *wtail; int len; len = strlen(msg); if (len > sizeof (wbuf.space)) len = sizeof (wbuf.space); wbuf.t.th_opcode = htons((ushort_t)ERROR); wbuf.t.th_code = htons(errcode); wtail = wbuf.t.th_msg; bcopy(msg, wtail, len); wtail[len] = '\0'; wtail += len + 1; sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } static void tftp_sendack(struct tftp_handle *h, ushort_t block) { struct { uchar_t header[HEADER_SIZE]; struct tftphdr t; } __packed __aligned(4) wbuf; char *wtail; wbuf.t.th_opcode = htons((ushort_t)ACK); wtail = (char *)&wbuf.t.th_block; wbuf.t.th_block = htons(block); wtail += 2; sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } static ssize_t recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *recv_extra) { struct tftprecv_extra *extra; struct tftp_handle *h; struct tftphdr *t; void *ptr = NULL; ssize_t len; errno = 0; extra = recv_extra; h = extra->tftp_handle; len = readudp(d, &ptr, (void **)&t, tleft); if (len < 4) { free(ptr); return (-1); } extra->rtype = ntohs(t->th_opcode); switch (ntohs(t->th_opcode)) { case DATA: { int got; if (htons(t->th_block) < (ushort_t)d->xid) { /* * Apparently our ACK was missed, re-send. */ tftp_sendack(h, htons(t->th_block)); free(ptr); return (-1); } if (htons(t->th_block) != (ushort_t)d->xid) { /* * Packet from the future, drop this. */ free(ptr); return (-1); } if (d->xid == 1) { /* * First data packet from new port. */ struct udphdr *uh; uh = (struct udphdr *)t - 1; d->destport = uh->uh_sport; } got = len - (t->th_data - (char *)t); *pkt = ptr; *payload = t; return (got); } case ERROR: if ((unsigned)ntohs(t->th_code) > TFTP_MAX_ERRCODE) { printf("illegal tftp error %d\n", ntohs(t->th_code)); errno = EIO; } else { #ifdef TFTP_DEBUG printf("tftp-error %d\n", ntohs(t->th_code)); #endif errno = tftperrors[ntohs(t->th_code)]; } free(ptr); return (-1); case OACK: { struct udphdr *uh; int tftp_oack_len; /* * Unexpected OACK. TFTP transfer already in progress. * Drop the pkt. */ if (d->xid != 1) { free(ptr); return (-1); } /* * Remember which port this OACK came from, because we need * to send the ACK or errors back to it. */ uh = (struct udphdr *)t - 1; d->destport = uh->uh_sport; /* Parse options ACK-ed by the server. */ tftp_oack_len = len - sizeof (t->th_opcode); if (tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len) != 0) { tftp_senderr(h, EOPTNEG, "Malformed OACK"); errno = EIO; free(ptr); return (-1); } *pkt = ptr; *payload = t; return (0); } default: #ifdef TFTP_DEBUG printf("tftp type %d not handled\n", ntohs(t->th_opcode)); #endif free(ptr); return (-1); } } /* send request, expect first block (or error) */ static int tftp_makereq(struct tftp_handle *h) { struct { uchar_t header[HEADER_SIZE]; struct tftphdr t; uchar_t space[FNAME_SIZE + 6]; } __packed __aligned(4) wbuf; struct tftprecv_extra recv_extra; char *wtail; int l; ssize_t res; void *pkt; struct tftphdr *t; char *tftp_blksize = NULL; int blksize_l; /* * Allow overriding default TFTP block size by setting * a tftp.blksize environment variable. */ if ((tftp_blksize = getenv("tftp.blksize")) != NULL) { tftp_set_blksize(h, tftp_blksize); } wbuf.t.th_opcode = htons((ushort_t)RRQ); wtail = wbuf.t.th_stuff; l = strlen(h->path); #ifdef TFTP_PREPEND_PATH if (l > FNAME_SIZE - (sizeof (TFTP_PREPEND_PATH) - 1)) return (ENAMETOOLONG); bcopy(TFTP_PREPEND_PATH, wtail, sizeof (TFTP_PREPEND_PATH) - 1); wtail += sizeof (TFTP_PREPEND_PATH) - 1; #else if (l > FNAME_SIZE) return (ENAMETOOLONG); #endif bcopy(h->path, wtail, l + 1); wtail += l + 1; bcopy("octet", wtail, 6); wtail += 6; bcopy("blksize", wtail, 8); wtail += 8; blksize_l = sprintf(wtail, "%d", h->tftp_blksize); wtail += blksize_l + 1; bcopy("tsize", wtail, 6); wtail += 6; bcopy("0", wtail, 2); wtail += 2; h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff)); h->iodesc->destport = htons(IPPORT_TFTP); h->iodesc->xid = 1; /* expected block */ h->currblock = 0; h->islastblock = 0; h->validsize = 0; pkt = NULL; recv_extra.tftp_handle = h; res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { free(pkt); return (errno); } free(h->pkt); h->pkt = pkt; h->tftp_hdr = t; if (recv_extra.rtype == OACK) return (tftp_getnextblock(h)); /* Server ignored our blksize request, revert to TFTP default. */ h->tftp_blksize = SEGSIZE; switch (recv_extra.rtype) { case DATA: { h->currblock = 1; h->validsize = res; h->islastblock = 0; if (res < h->tftp_blksize) { h->islastblock = 1; /* very short file */ tftp_sendack(h, h->currblock); } return (0); } case ERROR: default: return (errno); } } /* ack block, expect next */ static int tftp_getnextblock(struct tftp_handle *h) { struct { uchar_t header[HEADER_SIZE]; struct tftphdr t; } __packed __aligned(4) wbuf; struct tftprecv_extra recv_extra; char *wtail; int res; void *pkt; struct tftphdr *t; wbuf.t.th_opcode = htons((ushort_t)ACK); wtail = (char *)&wbuf.t.th_block; wbuf.t.th_block = htons((ushort_t)h->currblock); wtail += 2; h->iodesc->xid = h->currblock + 1; /* expected block */ pkt = NULL; recv_extra.tftp_handle = h; res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { /* 0 is OK! */ free(pkt); return (errno); } free(h->pkt); h->pkt = pkt; h->tftp_hdr = t; h->currblock++; h->validsize = res; if (res < h->tftp_blksize) h->islastblock = 1; /* EOF */ if (h->islastblock == 1) { /* Send an ACK for the last block */ wbuf.t.th_block = htons((ushort_t)h->currblock); sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } return (0); } static int tftp_open(const char *path, struct open_file *f) { struct devdesc *dev; struct tftp_handle *tftpfile; struct iodesc *io; int res; size_t pathsize; const char *extraslash; if (netproto != NET_TFTP) return (EINVAL); if (f->f_dev->dv_type != DEVT_NET) return (EINVAL); if (is_open) return (EBUSY); tftpfile = calloc(1, sizeof (*tftpfile)); if (!tftpfile) return (ENOMEM); tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE; dev = f->f_devdata; tftpfile->iodesc = io = socktodesc(*(int *)(dev->d_opendata)); if (io == NULL) { free(tftpfile); return (EINVAL); } io->destip = rootip; tftpfile->off = 0; pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof (char); tftpfile->path = malloc(pathsize); if (tftpfile->path == NULL) { free(tftpfile); return (ENOMEM); } if (rootpath[strlen(rootpath) - 1] == '/' || path[0] == '/') extraslash = ""; else extraslash = "/"; res = snprintf(tftpfile->path, pathsize, "%s%s%s", rootpath, extraslash, path); if (res < 0 || res > pathsize) { free(tftpfile->path); free(tftpfile); return (ENOMEM); } res = tftp_makereq(tftpfile); if (res) { free(tftpfile->path); free(tftpfile->pkt); free(tftpfile); return (res); } f->f_fsdata = tftpfile; is_open = 1; return (0); } static int tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid /* out */) { struct tftp_handle *tftpfile; size_t res; int rc; rc = 0; res = size; tftpfile = f->f_fsdata; /* Make sure we will not read past file end */ if (tftpfile->tftp_tsize > 0 && tftpfile->off + size > tftpfile->tftp_tsize) { size = tftpfile->tftp_tsize - tftpfile->off; } while (size > 0) { int needblock, count; twiddle(32); needblock = tftpfile->off / tftpfile->tftp_blksize + 1; if (tftpfile->currblock > needblock) { /* seek backwards */ tftp_senderr(tftpfile, 0, "No error: read aborted"); rc = tftp_makereq(tftpfile); if (rc != 0) break; } while (tftpfile->currblock < needblock) { rc = tftp_getnextblock(tftpfile); if (rc) { /* no answer */ #ifdef TFTP_DEBUG printf("tftp: read error\n"); #endif return (rc); } if (tftpfile->islastblock) break; } if (tftpfile->currblock == needblock) { int offinblock, inbuffer; offinblock = tftpfile->off % tftpfile->tftp_blksize; inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { #ifdef TFTP_DEBUG printf("tftp: invalid offset %d\n", tftpfile->off); #endif return (EINVAL); } count = (size < inbuffer ? size : inbuffer); bcopy(tftpfile->tftp_hdr->th_data + offinblock, addr, count); addr = (char *)addr + count; tftpfile->off += count; size -= count; res -= count; if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ } else { #ifdef TFTP_DEBUG printf("tftp: block %d not found\n", needblock); #endif return (EINVAL); } } if (resid != NULL) *resid = res; return (rc); } static int tftp_close(struct open_file *f) { struct tftp_handle *tftpfile; tftpfile = f->f_fsdata; /* let it time out ... */ if (tftpfile) { free(tftpfile->path); free(tftpfile->pkt); free(tftpfile); } is_open = 0; return (0); } static int tftp_stat(struct open_file *f, struct stat *sb) { struct tftp_handle *tftpfile; tftpfile = f->f_fsdata; sb->st_mode = 0444 | S_IFREG; sb->st_nlink = 1; sb->st_uid = 0; sb->st_gid = 0; sb->st_size = tftpfile->tftp_tsize; return (0); } static off_t tftp_seek(struct open_file *f, off_t offset, int where) { struct tftp_handle *tftpfile; tftpfile = f->f_fsdata; switch (where) { case SEEK_SET: tftpfile->off = offset; break; case SEEK_CUR: tftpfile->off += offset; break; default: errno = EOFFSET; return (-1); } return (tftpfile->off); } static int tftp_set_blksize(struct tftp_handle *h, const char *str) { char *endptr; int new_blksize; int ret = 0; if (h == NULL || str == NULL) return (ret); new_blksize = (unsigned int)strtol(str, &endptr, 0); /* * Only accept blksize value if it is numeric. * RFC2348 specifies that acceptable values are 8-65464. * Let's choose a limit less than MAXRSPACE. */ if (*endptr == '\0' && new_blksize >= 8 && new_blksize <= TFTP_MAX_BLKSIZE) { h->tftp_blksize = new_blksize; ret = 1; } return (ret); } /* * In RFC2347, the TFTP Option Acknowledgement package (OACK) * is used to acknowledge a client's option negotiation request. * The format of an OACK packet is: * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ * * opc * The opcode field contains a 6, for Option Acknowledgment. * * opt1 * The first option acknowledgment, copied from the original * request. * * value1 * The acknowledged value associated with the first option. If * and how this value may differ from the original request is * detailed in the specification for the option. * * optN, valueN * The final option/value acknowledgment pair. */ static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) { /* * We parse the OACK strings into an array * of name-value pairs. */ char *tftp_options[128] = { 0 }; char *val = buf; int i = 0; int option_idx = 0; int blksize_is_set = 0; int tsize = 0; unsigned int orig_blksize; while (option_idx < 128 && i < len) { if (buf[i] == '\0') { if (&buf[i] > val) { tftp_options[option_idx] = val; val = &buf[i] + 1; ++option_idx; } } ++i; } /* Save the block size we requested for sanity check later. */ orig_blksize = h->tftp_blksize; /* * Parse individual TFTP options. * * "blksize" is specified in RFC2348. * * "tsize" is specified in RFC2349. */ for (i = 0; i < option_idx; i += 2) { if (strcasecmp(tftp_options[i], "blksize") == 0) { if (i + 1 < option_idx) blksize_is_set = tftp_set_blksize(h, tftp_options[i + 1]); } else if (strcasecmp(tftp_options[i], "tsize") == 0) { if (i + 1 < option_idx) tsize = strtol(tftp_options[i + 1], NULL, 10); if (tsize != 0) h->tftp_tsize = tsize; } else { /* * Do not allow any options we did not expect to be * ACKed. */ printf("unexpected tftp option '%s'\n", tftp_options[i]); return (-1); } } if (!blksize_is_set) { /* * If TFTP blksize was not set, try defaulting * to the legacy TFTP blksize of SEGSIZE(512) */ h->tftp_blksize = SEGSIZE; } else if (h->tftp_blksize > orig_blksize) { /* * Server should not be proposing block sizes that * exceed what we said we can handle. */ printf("unexpected blksize %u\n", h->tftp_blksize); return (-1); } #ifdef TFTP_DEBUG printf("tftp_blksize: %u\n", h->tftp_blksize); printf("tftp_tsize: %lu\n", h->tftp_tsize); #endif return (0); } /* $NetBSD: tftp.h,v 1.1.1.1 1997/03/14 02:40:31 perry Exp $ */ /* * Copyright (c) 1996 * Matthias Drochner. All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project * by Matthias Drochner. * 4. 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 ``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 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. * */ #define IPPORT_TFTP 69 /*- * Copyright (c) 1986, 1988, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ #include #include #include "stand.h" /* Extra functions from NetBSD standalone printf.c */ static uint_t globaldiv = 16; void twiddle(uint_t callerdiv) { static uint_t callercnt, globalcnt, pos; callercnt++; if (callerdiv > 1 && (callercnt % callerdiv) != 0) return; globalcnt++; if (globaldiv > 1 && (globalcnt % globaldiv) != 0) return; putchar("|/-\\"[pos++ & 3]); putchar('\b'); } void twiddle_divisor(uint_t gdiv) { globaldiv = gdiv; } /* Taken from $NetBSD: net.c,v 1.20 1997/12/26 22:41:30 scottr Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) */ #include #include #include #include #include #include #include #include #include #include #include #include #include "stand.h" #include "net.h" /* Caller must leave room for ethernet, ip and udp headers in front!! */ ssize_t sendudp(struct iodesc *d, void *pkt, size_t len) { ssize_t cc; struct udpiphdr *ui; struct udphdr *uh; #ifdef NET_DEBUG if (debug) { printf("sendudp: d=%lx called.\n", (long)d); if (d) { printf("saddr: %s:%d", inet_ntoa(d->myip), ntohs(d->myport)); printf(" daddr: %s:%d\n", inet_ntoa(d->destip), ntohs(d->destport)); } } #endif ui = (struct udpiphdr *)pkt - 1; bzero(ui, sizeof (*ui)); uh = (struct udphdr *)pkt - 1; len += sizeof (*uh); uh->uh_sport = d->myport; uh->uh_dport = d->destport; uh->uh_ulen = htons(len); ui->ui_pr = IPPROTO_UDP; ui->ui_len = uh->uh_ulen; ui->ui_src = d->myip; ui->ui_dst = d->destip; #ifndef UDP_NO_CKSUM uh->uh_sum = in_cksum(ui, len + sizeof (struct ip)); #endif cc = sendip(d, uh, len, IPPROTO_UDP); if (cc == -1) return (-1); if (cc != len) panic("sendudp: bad write (%zd != %zd)", cc, len); return (cc - sizeof (*uh)); } /* * Receive a UDP packet and validate it is for us. */ ssize_t readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft) { ssize_t n; struct udphdr *uh; void *ptr; #ifdef NET_DEBUG if (debug) printf("readudp: called\n"); #endif uh = NULL; ptr = NULL; n = readip(d, &ptr, (void **)&uh, tleft, IPPROTO_UDP); if (n == -1 || n < sizeof (*uh) || n != ntohs(uh->uh_ulen)) { free(ptr); return (-1); } if (uh->uh_dport != d->myport) { #ifdef NET_DEBUG if (debug) printf("readudp: bad dport %d != %d\n", d->myport, ntohs(uh->uh_dport)); #endif free(ptr); return (-1); } #ifndef UDP_NO_CKSUM if (uh->uh_sum) { struct udpiphdr *ui; void *ip; struct ip tip; n = ntohs(uh->uh_ulen) + sizeof (struct ip); /* * Check checksum (must save and restore ip header). * Note we do use void *ip here to make gcc to stop * complaining about possibly unaligned pointer values. * We do allocate buffer in pxe.c/efinet.c and care is * taken to get headers aligned properly. */ ip = (struct ip *)uh - 1; tip = *(struct ip *)ip; ui = ip; bzero(&ui->ui_x1, sizeof (ui->ui_x1)); ui->ui_len = uh->uh_ulen; if (in_cksum(ui, n) != 0) { #ifdef NET_DEBUG if (debug) printf("readudp: bad cksum\n"); #endif free(ptr); return (-1); } *(struct ip *)ip = tip; } #endif if (ntohs(uh->uh_ulen) < sizeof (*uh)) { #ifdef NET_DEBUG if (debug) printf("readudp: bad udp len %d < %d\n", ntohs(uh->uh_ulen), (int)sizeof (*uh)); #endif free(ptr); return (-1); } n = (n > (ntohs(uh->uh_ulen) - sizeof (*uh))) ? ntohs(uh->uh_ulen) - sizeof (*uh) : n; *pkt = ptr; *payload = (void *)((uintptr_t)uh + sizeof (*uh)); return (n); } /* $NetBSD: ufs.c,v 1.20 1998/03/01 07:15:39 ross Exp $ */ /* * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Marshall * Kirk McKusick and Network Associates Laboratories, the Security * Research Division of Network Associates, Inc. under DARPA/SPAWAR * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS * research program * * Copyright (c) 1982, 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * * Copyright (c) 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: David Golub * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include /* * Stand-alone file reading package. */ #include #include #include #include #include #include #include "stand.h" #include "string.h" static int ufs_open(const char *, struct open_file *); static int ufs_write(struct open_file *, const void *, size_t, size_t *); static int ufs_close(struct open_file *); static int ufs_read(struct open_file *, void *, size_t, size_t *); static off_t ufs_seek(struct open_file *, off_t, int); static int ufs_stat(struct open_file *, struct stat *); static int ufs_readdir(struct open_file *, struct dirent *); struct fs_ops ufs_fsops = { "ufs", ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat, ufs_readdir }; /* * In-core open file. */ struct file { off_t f_seekp; /* seek pointer */ struct fs *f_fs; /* pointer to super-block */ union dinode { struct ufs1_dinode di1; struct ufs2_dinode di2; } f_di; /* copy of on-disk inode */ int f_nindir[NIADDR]; /* * number of blocks mapped by * indirect block at level i */ char *f_blk[NIADDR]; /* * buffer for indirect block at * level i */ size_t f_blksize[NIADDR]; /* size of buffer */ ufs2_daddr_t f_blkno[NIADDR]; /* disk address of block in buffer */ ufs2_daddr_t f_buf_blkno; /* block number of data block */ char *f_buf; /* buffer for data block */ size_t f_buf_size; /* size of data block */ }; #define DIP(fp, field) \ ((fp)->f_fs->fs_magic == FS_UFS1_MAGIC ? \ (fp)->f_di.di1.field : (fp)->f_di.di2.field) static int read_inode(ino_t, struct open_file *); static int block_map(struct open_file *, ufs2_daddr_t, ufs2_daddr_t *); static int buf_read_file(struct open_file *, char **, size_t *); static int buf_write_file(struct open_file *, const char *, size_t *); static int search_directory(char *, struct open_file *, ino_t *); /* * Read a new inode into a file structure. */ static int read_inode(ino_t inumber, struct open_file *f) { struct file *fp = (struct file *)f->f_fsdata; struct fs *fs = fp->f_fs; char *buf; size_t rsize; int rc; if (fs == NULL) panic("fs == NULL"); /* * Read inode and save it. */ buf = malloc(fs->fs_bsize); twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, buf, &rsize); if (rc) goto out; if (rsize != fs->fs_bsize) { rc = EIO; goto out; } if (fp->f_fs->fs_magic == FS_UFS1_MAGIC) fp->f_di.di1 = ((struct ufs1_dinode *)buf) [ino_to_fsbo(fs, inumber)]; else fp->f_di.di2 = ((struct ufs2_dinode *)buf) [ino_to_fsbo(fs, inumber)]; /* * Clear out the old buffers */ { int level; for (level = 0; level < NIADDR; level++) fp->f_blkno[level] = -1; fp->f_buf_blkno = -1; } fp->f_seekp = 0; out: free(buf); return (rc); } /* * Given an offset in a file, find the disk block number that * contains that block. */ static int block_map(struct open_file *f, ufs2_daddr_t file_block, ufs2_daddr_t *disk_block_p) { struct file *fp = (struct file *)f->f_fsdata; struct fs *fs = fp->f_fs; int level; int idx; ufs2_daddr_t ind_block_num; int rc; /* * Index structure of an inode: * * di_db[0..NDADDR-1] hold block numbers for blocks * 0..NDADDR-1 * * di_ib[0] index block 0 is the single indirect block * holds block numbers for blocks * NDADDR .. NDADDR + NINDIR(fs)-1 * * di_ib[1] index block 1 is the double indirect block * holds block numbers for INDEX blocks for blocks * NDADDR + NINDIR(fs) .. * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1 * * di_ib[2] index block 2 is the triple indirect block * holds block numbers for double-indirect * blocks for blocks * NDADDR + NINDIR(fs) + NINDIR(fs)**2 .. * NDADDR + NINDIR(fs) + NINDIR(fs)**2 * + NINDIR(fs)**3 - 1 */ if (file_block < NDADDR) { /* Direct block. */ *disk_block_p = DIP(fp, di_db[file_block]); return (0); } file_block -= NDADDR; /* * nindir[0] = NINDIR * nindir[1] = NINDIR**2 * nindir[2] = NINDIR**3 * etc */ for (level = 0; level < NIADDR; level++) { if (file_block < fp->f_nindir[level]) break; file_block -= fp->f_nindir[level]; } if (level == NIADDR) { /* Block number too high */ return (EFBIG); } ind_block_num = DIP(fp, di_ib[level]); for (; level >= 0; level--) { if (ind_block_num == 0) { *disk_block_p = 0; /* missing */ return (0); } if (fp->f_blkno[level] != ind_block_num) { if (fp->f_blk[level] == NULL) fp->f_blk[level] = malloc(fs->fs_bsize); twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fp->f_fs, ind_block_num), fs->fs_bsize, fp->f_blk[level], &fp->f_blksize[level]); if (rc) return (rc); if (fp->f_blksize[level] != fs->fs_bsize) return (EIO); fp->f_blkno[level] = ind_block_num; } if (level > 0) { idx = file_block / fp->f_nindir[level - 1]; file_block %= fp->f_nindir[level - 1]; } else idx = file_block; if (fp->f_fs->fs_magic == FS_UFS1_MAGIC) ind_block_num = ((ufs1_daddr_t *)fp->f_blk[level])[idx]; else ind_block_num = ((ufs2_daddr_t *)fp->f_blk[level])[idx]; } *disk_block_p = ind_block_num; return (0); } /* * Write a portion of a file from an internal buffer. */ static int buf_write_file(struct open_file *f, const char *buf_p, size_t *size_p) { struct file *fp = (struct file *)f->f_fsdata; struct fs *fs = fp->f_fs; long off; ufs_lbn_t file_block; ufs2_daddr_t disk_block; size_t block_size; int rc; /* * Calculate the starting block address and offset. */ off = blkoff(fs, fp->f_seekp); file_block = lblkno(fs, fp->f_seekp); block_size = sblksize(fs, DIP(fp, di_size), file_block); rc = block_map(f, file_block, &disk_block); if (rc) return (rc); if (disk_block == 0) /* Because we can't allocate space on the drive */ return (EFBIG); /* * Truncate buffer at end of file, and at the end of * this block. */ if (*size_p > DIP(fp, di_size) - fp->f_seekp) *size_p = DIP(fp, di_size) - fp->f_seekp; if (*size_p > block_size - off) *size_p = block_size - off; /* * If we don't entirely occlude the block and it's not * in memory already, read it in first. */ if (((off > 0) || (*size_p + off < block_size)) && (file_block != fp->f_buf_blkno)) { if (fp->f_buf == (char *)0) fp->f_buf = malloc(fs->fs_bsize); twiddle(8); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); if (rc) return (rc); fp->f_buf_blkno = file_block; } /* * Copy the user data into the cached block. */ bcopy(buf_p, fp->f_buf + off, *size_p); /* * Write the block out to storage. */ twiddle(4); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); return (rc); } /* * Read a portion of a file into an internal buffer. Return * the location in the buffer and the amount in the buffer. */ static int buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) { struct file *fp = (struct file *)f->f_fsdata; struct fs *fs = fp->f_fs; long off; ufs_lbn_t file_block; ufs2_daddr_t disk_block; size_t block_size; int rc; off = blkoff(fs, fp->f_seekp); file_block = lblkno(fs, fp->f_seekp); block_size = sblksize(fs, DIP(fp, di_size), file_block); if (file_block != fp->f_buf_blkno) { if (fp->f_buf == (char *)0) fp->f_buf = malloc(fs->fs_bsize); rc = block_map(f, file_block, &disk_block); if (rc) return (rc); if (disk_block == 0) { bzero(fp->f_buf, block_size); fp->f_buf_size = block_size; } else { twiddle(4); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); if (rc) return (rc); } fp->f_buf_blkno = file_block; } /* * Return address of byte in buffer corresponding to * offset, and size of remainder of buffer after that * byte. */ *buf_p = fp->f_buf + off; *size_p = block_size - off; /* * But truncate buffer at end of file. */ if (*size_p > DIP(fp, di_size) - fp->f_seekp) *size_p = DIP(fp, di_size) - fp->f_seekp; return (0); } /* * Search a directory for a name and return its * i_number. */ static int search_directory(char *name, struct open_file *f, ino_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp; struct direct *edp; char *buf; size_t buf_size; int namlen, length; int rc; length = strlen(name); fp->f_seekp = 0; while (fp->f_seekp < DIP(fp, di_size)) { rc = buf_read_file(f, &buf, &buf_size); if (rc) return (rc); dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); while (dp < edp) { if (dp->d_ino == (ino_t)0) goto next; namlen = dp->d_namlen; if (namlen == length && strcmp(name, dp->d_name) == 0) { /* found entry */ *inumber_p = dp->d_ino; return (0); } next: dp = (struct direct *)((char *)dp + dp->d_reclen); } fp->f_seekp += buf_size; } return (ENOENT); } static int sblock_try[] = SBLOCKSEARCH; /* * Open a file. */ static int ufs_open(const char *upath, struct open_file *f) { char *cp, *ncp; int c; ino_t inumber, parent_inumber; struct file *fp; struct fs *fs; int i, rc; size_t buf_size; int nlinks = 0; char namebuf[MAXPATHLEN+1]; char *buf = NULL; char *path = NULL; /* allocate file system specific data structure */ fp = malloc(sizeof (struct file)); bzero(fp, sizeof (struct file)); f->f_fsdata = (void *)fp; /* allocate space and read super block */ fs = malloc(SBLOCKSIZE); fp->f_fs = fs; twiddle(1); /* * Try reading the superblock in each of its possible locations. */ for (i = 0; sblock_try[i] != -1; i++) { rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE, (char *)fs, &buf_size); if (rc) goto out; if ((fs->fs_magic == FS_UFS1_MAGIC || (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc == sblock_try[i])) && buf_size == SBLOCKSIZE && fs->fs_bsize <= MAXBSIZE && fs->fs_bsize >= sizeof (struct fs)) break; } if (sblock_try[i] == -1) { rc = EINVAL; goto out; } /* * Calculate indirect block levels. */ { ufs2_daddr_t mult; int level; mult = 1; for (level = 0; level < NIADDR; level++) { mult *= NINDIR(fs); fp->f_nindir[level] = mult; } } inumber = ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; cp = path = strdup(upath); if (path == NULL) { rc = ENOMEM; goto out; } while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if ((DIP(fp, di_mode) & IFMT) != IFDIR) { rc = ENOTDIR; goto out; } /* * Get next component of path name. */ { int len = 0; ncp = cp; while ((c = *cp) != '\0' && c != '/') { if (++len > UFS_MAXNAMLEN) { rc = ENOENT; goto out; } cp++; } *cp = '\0'; } /* * Look up component in current directory. * Save directory inumber in case we find a * symbolic link. */ parent_inumber = inumber; rc = search_directory(ncp, f, &inumber); *cp = c; if (rc) goto out; /* * Open next component. */ if ((rc = read_inode(inumber, f)) != 0) goto out; /* * Check for symbolic link. */ if ((DIP(fp, di_mode) & IFMT) == IFLNK) { int link_len = DIP(fp, di_size); int len; len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { rc = ENOENT; goto out; } bcopy(cp, &namebuf[link_len], len + 1); if (link_len < fs->fs_maxsymlinklen) { if (fp->f_fs->fs_magic == FS_UFS1_MAGIC) cp = (caddr_t)(fp->f_di.di1.di_db); else cp = (caddr_t)(fp->f_di.di2.di_db); bcopy(cp, namebuf, (unsigned)link_len); } else { /* * Read file for symbolic link */ size_t buf_size; ufs2_daddr_t disk_block; struct fs *fs = fp->f_fs; if (!buf) buf = malloc(fs->fs_bsize); rc = block_map(f, (ufs2_daddr_t)0, &disk_block); if (rc) goto out; twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), fs->fs_bsize, buf, &buf_size); if (rc) goto out; bcopy((char *)buf, namebuf, (unsigned)link_len); } /* * If relative pathname, restart at parent directory. * If absolute pathname, restart at root. */ cp = namebuf; if (*cp != '/') inumber = parent_inumber; else inumber = (ino_t)ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; } } /* * Found terminal component. */ rc = 0; fp->f_seekp = 0; out: if (buf) free(buf); if (path) free(path); if (rc) { if (fp->f_buf) free(fp->f_buf); free(fp->f_fs); free(fp); } return (rc); } static int ufs_close(struct open_file *f) { struct file *fp = (struct file *)f->f_fsdata; int level; f->f_fsdata = (void *)0; if (fp == (struct file *)0) return (0); for (level = 0; level < NIADDR; level++) { if (fp->f_blk[level]) free(fp->f_blk[level]); } if (fp->f_buf) free(fp->f_buf); free(fp->f_fs); free(fp); return (0); } /* * Copy a portion of a file into kernel memory. * Cross block boundaries when necessary. */ static int ufs_read(struct open_file *f, void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; size_t csize; char *buf; size_t buf_size; int rc = 0; char *addr = start; while (size != 0) { if (fp->f_seekp >= DIP(fp, di_size)) break; rc = buf_read_file(f, &buf, &buf_size); if (rc) break; csize = size; if (csize > buf_size) csize = buf_size; bcopy(buf, addr, csize); fp->f_seekp += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (rc); } /* * Write to a portion of an already allocated file. * Cross block boundaries when necessary. Can not * extend the file. */ static int ufs_write(struct open_file *f, const void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; size_t csize; int rc = 0; const char *addr = start; csize = size; while ((size != 0) && (csize != 0)) { if (fp->f_seekp >= DIP(fp, di_size)) break; if (csize >= 512) csize = 512; /* XXX */ rc = buf_write_file(f, addr, &csize); if (rc) break; fp->f_seekp += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (rc); } static off_t ufs_seek(struct open_file *f, off_t offset, int where) { struct file *fp = (struct file *)f->f_fsdata; switch (where) { case SEEK_SET: fp->f_seekp = offset; break; case SEEK_CUR: fp->f_seekp += offset; break; case SEEK_END: fp->f_seekp = DIP(fp, di_size) - offset; break; default: errno = EINVAL; return (-1); } return (fp->f_seekp); } static int ufs_stat(struct open_file *f, struct stat *sb) { struct file *fp = (struct file *)f->f_fsdata; /* only important stuff */ sb->st_mode = DIP(fp, di_mode); sb->st_uid = DIP(fp, di_uid); sb->st_gid = DIP(fp, di_gid); sb->st_size = DIP(fp, di_size); return (0); } static int ufs_readdir(struct open_file *f, struct dirent *d) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp; char *buf; size_t buf_size; int error; /* * assume that a directory entry will not be split across blocks */ again: if (fp->f_seekp >= DIP(fp, di_size)) return (ENOENT); error = buf_read_file(f, &buf, &buf_size); if (error) return (error); dp = (struct direct *)buf; fp->f_seekp += dp->d_reclen; if (dp->d_ino == (ino_t)0) goto again; d->d_type = 0; /* illumos ufs does not have type in direct */ strcpy(d->d_name, dp->d_name); return (0); } /*- * Copyright (c) 2002 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #include #include /* * uuid_create_nil() - create a nil UUID. * See also: * http://www.opengroup.org/onlinepubs/009629399/uuid_create_nil.htm */ void uuid_create_nil(uuid_t *u, uint32_t *status) { if (status) *status = uuid_s_ok; bzero(u, sizeof(*u)); } /*- * Copyright (c) 2002,2005 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #include #include /* * uuid_equal() - compare for equality. * See also: * http://www.opengroup.org/onlinepubs/009629399/uuid_equal.htm */ int32_t uuid_equal(const uuid_t *a, const uuid_t *b, uint32_t *status) { if (status != NULL) *status = uuid_s_ok; /* Deal with equal or NULL pointers. */ if (a == b) return (1); if (a == NULL) return (uuid_is_nil(b, NULL)); if (b == NULL) return (uuid_is_nil(a, NULL)); /* Do a byte for byte comparison. */ return ((memcmp(a, b, sizeof(uuid_t))) ? 0 : 1); } /*- * Copyright (c) 2002,2005 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #include /* * uuid_is_nil() - return whether the UUID is a nil UUID. * See also: * http://www.opengroup.org/onlinepubs/009629399/uuid_is_nil.htm */ int32_t uuid_is_nil(const uuid_t *u, uint32_t *status) { const uint32_t *p; if (status) *status = uuid_s_ok; if (!u) return (1); /* * Pick the largest type that has equivalent alignment constraints * as an UUID and use it to test if the UUID consists of all zeroes. */ p = (const uint32_t*)u; return ((p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0) ? 1 : 0); } /*- * Copyright (c) 2015 M. Warner Losh * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ /* * Note: some comments taken from lib/libc/uuid/uuid_from_string.c * Copyright (c) 2002 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya */ #include #include static int hex2int(int ch) { if (ch >= '0' && ch <= '9') return ch - '0'; if (ch >= 'a' && ch <= 'f') return 10 + ch - 'a'; if (ch >= 'A' && ch <= 'F') return 10 + ch - 'A'; return 16; } static uint32_t fromhex(const char *s, int len, int *ok) { uint32_t v; int i, h; if (!*ok) return 0; v = 0; for (i = 0; i < len; i++) { h = hex2int(s[i]); if (h == 16) { *ok = 0; return v; } v = (v << 4) | h; } return v; } /* * uuid_from_string() - convert a string representation of an UUID into * a binary representation. * See also: * http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm * * NOTE: The sequence field is in big-endian, while the time fields are in * native byte order. * * 01234567-89ab-cdef-0123-456789abcdef * 000000000011111111112222222222333333 * 012345678901234567890123456789012345 * - - - - * hhhhhhhh-hhhh-hhhh-bbbb-bbbbbbbbbbbb * */ void uuid_from_string(const char *s, uuid_t *u, uint32_t *status) { int ok = 1; int n; if (s == NULL || *s == '\0') { uuid_create_nil(u, status); return; } if (status != NULL) *status = uuid_s_invalid_string_uuid; if (strlen(s) != 36) return; /* Only support new format, check for all the right dashes */ if (s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') return; /* native byte order */ u->time_low = fromhex(s , 8, &ok); u->time_mid = fromhex(s + 9, 4, &ok); u->time_hi_and_version = fromhex(s + 14, 4, &ok); /* Big endian, but presented as a whole number so decode as such */ u->clock_seq_hi_and_reserved = fromhex(s + 19, 2, &ok); u->clock_seq_low = fromhex(s + 21, 2, &ok); u->node[0] = fromhex(s + 24, 2, &ok); u->node[1] = fromhex(s + 26, 2, &ok); u->node[2] = fromhex(s + 28, 2, &ok); u->node[3] = fromhex(s + 30, 2, &ok); u->node[4] = fromhex(s + 32, 2, &ok); u->node[5] = fromhex(s + 34, 2, &ok); if (!ok) return; /* We have a successful scan. Check semantics... */ n = u->clock_seq_hi_and_reserved; if ((n & 0x80) != 0x00 && /* variant 0? */ (n & 0xc0) != 0x80 && /* variant 1? */ (n & 0xe0) != 0xc0) { /* variant 2? */ if (status != NULL) *status = uuid_s_bad_version; } else { if (status != NULL) *status = uuid_s_ok; } } /*- * Copyright (c) 2015 M. Warner Losh * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ /* * Note: some comments taken from lib/libc/uuid/uuid_to_string.c * Copyright (c) 2002,2005 Marcel Moolenaar * Copyright (c) 2002 Hiten Mahesh Pandya */ #include #include /* * Dump len characters into *buf from val as hex and update *buf */ static void tohex(char **buf, int len, uint32_t val) { static const char *hexstr = "0123456789abcdef"; char *walker = *buf; int i; for (i = len - 1; i >= 0; i--) { walker[i] = hexstr[val & 0xf]; val >>= 4; } *buf = walker + len; } /* * uuid_to_string() - Convert a binary UUID into a string representation. * See also: * http://www.opengroup.org/onlinepubs/009629399/uuid_to_string.htm * * NOTE: The references given above do not have a status code for when * the string could not be allocated. The status code has been * taken from the Hewlett-Packard implementation. * * NOTE: we don't support u == NULL for a nil UUID, sorry. * * NOTE: The sequence field is in big-endian, while the time fields are in * native byte order. * * hhhhhhhh-hhhh-hhhh-bbbb-bbbbbbbbbbbb * 01234567-89ab-cdef-0123-456789abcdef */ void uuid_to_string(const uuid_t *u, char **s, uint32_t *status) { uuid_t nil; char *w; if (status != NULL) *status = uuid_s_ok; if (s == NULL) /* Regular version does this odd-ball behavior too */ return; w = *s = malloc(37); if (*s == NULL) { if (status != NULL) *status = uuid_s_no_memory; return; } if (u == NULL) { u = &nil; uuid_create_nil(&nil, NULL); } /* native */ tohex(&w, 8, u->time_low); *w++ = '-'; tohex(&w, 4, u->time_mid); *w++ = '-'; tohex(&w, 4, u->time_hi_and_version); *w++ = '-'; /* Big endian, so do a byte at a time */ tohex(&w, 2, u->clock_seq_hi_and_reserved); tohex(&w, 2, u->clock_seq_low); *w++ = '-'; tohex(&w, 2, u->node[0]); tohex(&w, 2, u->node[1]); tohex(&w, 2, u->node[2]); tohex(&w, 2, u->node[3]); tohex(&w, 2, u->node[4]); tohex(&w, 2, u->node[5]); *w++ = '\0'; } /* $NetBSD: write.c,v 1.7 1996/06/21 20:29:30 pk Exp $ */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * The Mach Operating System project at Carnegie-Mellon University. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)write.c 8.1 (Berkeley) 6/11/93 * * * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University * All Rights Reserved. * * Author: Alessandro Forin * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #include #include "stand.h" ssize_t write(int fd, const void *dest, size_t bcount) { struct open_file *f; size_t resid; f = fd2open_file(fd); if (f == NULL || !(f->f_flags & F_WRITE)) { errno = EBADF; return (-1); } if (f->f_flags & F_RAW) { twiddle(4); errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, btodb(f->f_offset), bcount, __DECONST(void *, dest), &resid); if (errno) return (-1); f->f_offset += resid; return (resid); } resid = bcount; if ((errno = (f->f_ops->fo_write)(f, dest, bcount, &resid))) return (-1); return (bcount - resid); } /* * Copyright (c) 2013-2019 Juniper Networks, Inc. * All rights reserved. * * 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. * * 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. */ #include #include #include #include const char * x86_hypervisor(void) { static union { struct { uint_t high; char name[13]; } hv; uint_t regs[4]; } u; /* Return NULL when no hypervisor is present. */ do_cpuid(1, u.regs); if ((u.regs[2] & CPUID2_HV) == 0) return (NULL); /* Return the hypervisor's identification. */ do_cpuid(0x40000000, u.regs); return (u.hv.name); } /* * This module derived from code donated to the FreeBSD Project by * Matthew Dillon * * Copyright (c) 1998 The FreeBSD Project * All rights reserved. * * 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. * * 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. */ #include #include /* * LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation * subsystem * * This subsystem implements memory pools and memory allocation * routines. * * Pools are managed via a linked list of 'free' areas. Allocating * memory creates holes in the freelist, freeing memory fills them. * Since the freelist consists only of free memory areas, it is possible * to allocate the entire pool without incuring any structural overhead. * * The system works best when allocating similarly-sized chunks of * memory. Care must be taken to avoid fragmentation when * allocating/deallocating dissimilar chunks. * * When a memory pool is first allocated, the entire pool is marked as * allocated. This is done mainly because we do not want to modify any * portion of a pool's data area until we are given permission. The * caller must explicitly deallocate portions of the pool to make them * available. * * z[n]xalloc() works like z[n]alloc() but the allocation is made from * within the specified address range. If the segment could not be * allocated, NULL is returned. WARNING! The address range will be * aligned to an 8 or 16 byte boundry depending on the cpu so if you * give an unaligned address range, unexpected results may occur. * * If a standard allocation fails, the reclaim function will be called * to recover some space. This usually causes other portions of the * same pool to be released. Memory allocations at this low level * should not block but you can do that too in your reclaim function * if you want. Reclaim does not function when z[n]xalloc() is used, * only for z[n]alloc(). * * Allocation and frees of 0 bytes are valid operations. */ #include "zalloc_defs.h" /* * Objects in the pool must be aligned to at least the size of struct MemNode. * They must also be aligned to MALLOCALIGN, which should normally be larger * than the struct, so assert that to be so at compile time. */ typedef char assert_align[(sizeof (struct MemNode) <= MALLOCALIGN) ? 1 : -1]; #define MEMNODE_SIZE_MASK MALLOCALIGN_MASK /* * znalloc() - allocate memory (without zeroing) from pool. Call reclaim * and retry if appropriate, return NULL if unable to allocate * memory. */ void * znalloc(MemPool *mp, uintptr_t bytes, size_t align) { MemNode **pmn; MemNode *mn; /* * align according to pool object size (can be 0). This is * inclusive of the MEMNODE_SIZE_MASK minimum alignment. * */ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK; if (bytes == 0) return ((void *)-1); /* * locate freelist entry big enough to hold the object. If all objects * are the same size, this is a constant-time function. */ if (bytes > mp->mp_Size - mp->mp_Used) return (NULL); for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) { char *ptr = (char *)mn; uintptr_t dptr; char *aligned; size_t extra; dptr = (uintptr_t)(ptr + MALLOCALIGN); /* pointer to data */ aligned = (char *)(roundup2(dptr, align) - MALLOCALIGN); extra = aligned - ptr; if (bytes + extra > mn->mr_Bytes) continue; /* * Cut extra from head and create new memory node from * remainder. */ if (extra != 0) { MemNode *new; new = (MemNode *)aligned; new->mr_Next = mn->mr_Next; new->mr_Bytes = mn->mr_Bytes - extra; /* And update current memory node */ mn->mr_Bytes = extra; mn->mr_Next = new; /* In next iteration, we will get our aligned address */ continue; } /* * Cut a chunk of memory out of the beginning of this * block and fixup the link appropriately. */ if (mn->mr_Bytes == bytes) { *pmn = mn->mr_Next; } else { mn = (MemNode *)((char *)mn + bytes); mn->mr_Next = ((MemNode *)ptr)->mr_Next; mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes; *pmn = mn; } mp->mp_Used += bytes; return (ptr); } /* * Memory pool is full, return NULL. */ return (NULL); } /* * zfree() - free previously allocated memory */ void zfree(MemPool *mp, void *ptr, uintptr_t bytes) { MemNode **pmn; MemNode *mn; /* * align according to pool object size (can be 0). This is * inclusive of the MEMNODE_SIZE_MASK minimum alignment. */ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK; if (bytes == 0) return; /* * panic if illegal pointer */ if ((char *)ptr < (char *)mp->mp_Base || (char *)ptr + bytes > (char *)mp->mp_End || ((uintptr_t)ptr & MEMNODE_SIZE_MASK) != 0) panic("zfree(%p,%ju): wild pointer", ptr, (uintmax_t)bytes); /* * free the segment */ mp->mp_Used -= bytes; for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) { /* * If area between last node and current node * - check range * - check merge with next area * - check merge with previous area */ if ((char *)ptr <= (char *)mn) { /* * range check */ if ((char *)ptr + bytes > (char *)mn) { panic("zfree(%p,%ju): corrupt memlist1", ptr, (uintmax_t)bytes); } /* * merge against next area or create independant area */ if ((char *)ptr + bytes == (char *)mn) { ((MemNode *)ptr)->mr_Next = mn->mr_Next; ((MemNode *)ptr)->mr_Bytes = bytes + mn->mr_Bytes; } else { ((MemNode *)ptr)->mr_Next = mn; ((MemNode *)ptr)->mr_Bytes = bytes; } *pmn = mn = (MemNode *)ptr; /* * merge against previous area (if there is a previous * area). */ if (pmn != &mp->mp_First) { if ((char *)pmn + ((MemNode*)pmn)->mr_Bytes == (char *)ptr) { ((MemNode *)pmn)->mr_Next = mn->mr_Next; ((MemNode *)pmn)->mr_Bytes += mn->mr_Bytes; mn = (MemNode *)pmn; } } return; } if ((char *)ptr < (char *)mn + mn->mr_Bytes) { panic("zfree(%p,%ju): corrupt memlist2", ptr, (uintmax_t)bytes); } } /* * We are beyond the last MemNode, append new MemNode. Merge against * previous area if possible. */ if (pmn == &mp->mp_First || (char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr) { ((MemNode *)ptr)->mr_Next = NULL; ((MemNode *)ptr)->mr_Bytes = bytes; *pmn = (MemNode *)ptr; mn = (MemNode *)ptr; } else { ((MemNode *)pmn)->mr_Bytes += bytes; mn = (MemNode *)pmn; } } /* * zextendPool() - extend memory pool to cover additional space. * * Note: the added memory starts out as allocated, you * must free it to make it available to the memory subsystem. * * Note: mp_Size may not reflect (mp_End - mp_Base) range * due to other parts of the system doing their own sbrk() * calls. */ void zextendPool(MemPool *mp, void *base, uintptr_t bytes) { if (mp->mp_Size == 0) { mp->mp_Base = base; mp->mp_Used = bytes; mp->mp_End = (char *)base + bytes; mp->mp_Size = bytes; } else { void *pend = (char *)mp->mp_Base + mp->mp_Size; if (base < mp->mp_Base) { mp->mp_Size += (char *)mp->mp_Base - (char *)base; mp->mp_Used += (char *)mp->mp_Base - (char *)base; mp->mp_Base = base; } base = (char *)base + bytes; if (base > pend) { mp->mp_Size += (char *)base - (char *)pend; mp->mp_Used += (char *)base - (char *)pend; mp->mp_End = (char *)base; } } } #ifdef ZALLOCDEBUG void zallocstats(MemPool *mp) { int abytes = 0; int hbytes = 0; int fcount = 0; MemNode *mn; printf("%d bytes reserved", (int)mp->mp_Size); mn = mp->mp_First; if ((void *)mn != (void *)mp->mp_Base) { abytes += (char *)mn - (char *)mp->mp_Base; } while (mn != NULL) { if ((char *)mn + mn->mr_Bytes != mp->mp_End) { hbytes += mn->mr_Bytes; ++fcount; } if (mn->mr_Next != NULL) { abytes += (char *)mn->mr_Next - ((char *)mn + mn->mr_Bytes); } mn = mn->mr_Next; } printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n", abytes, fcount, hbytes); } #endif /* * This module derived from code donated to the FreeBSD Project by * Matthew Dillon * * Copyright (c) 1998 The FreeBSD Project * All rights reserved. * * 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. * * 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. */ /* * DEFS.H */ #ifndef _ZALLOC_DEFS_H #define _ZALLOC_DEFS_H #define USEGUARD /* use stard/end guard bytes */ #define USEENDGUARD #define DMALLOCDEBUG /* add debugging code to gather stats */ #define ZALLOCDEBUG #include #include "stand.h" #include "zalloc_mem.h" #define Library extern /* * block extension for sbrk() */ #define BLKEXTEND (4 * 1024) #define BLKEXTENDMASK (BLKEXTEND - 1) /* * Required malloc alignment. * * Embedded platforms using the u-boot API drivers require that all I/O buffers * be on a cache line sized boundary. The worst case size for that is 64 bytes. * For other platforms, 16 bytes works fine. The alignment also must be at * least sizeof(struct MemNode); this is asserted in zalloc.c. */ #if defined(__arm__) || defined(__mips__) || defined(__powerpc__) #define MALLOCALIGN 64 #else #define MALLOCALIGN 16 #endif #define MALLOCALIGN_MASK (MALLOCALIGN - 1) typedef struct Guard { size_t ga_Bytes; size_t ga_Magic; /* must be at least 32 bits */ } Guard; #define GAMAGIC 0x55FF44FD #define GAFREE 0x5F54F4DF #include "zalloc_protos.h" #endif /* _ZALLOC_DEFS_H */ /* * This module derived from code donated to the FreeBSD Project by * Matthew Dillon * * Copyright (c) 1998 The FreeBSD Project * All rights reserved. * * 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. * * 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. */ #include /* * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk */ #include "zalloc_defs.h" static MemPool MallocPool; #ifdef DMALLOCDEBUG static int MallocMax; static int MallocCount; void mallocstats(void); #endif #ifdef malloc #undef malloc #undef free #endif static void *Malloc_align(size_t, size_t); void * Malloc(size_t bytes, const char *file __unused, int line __unused) { return (Malloc_align(bytes, 1)); } void * Memalign(size_t alignment, size_t bytes, const char *file __unused, int line __unused) { if (alignment == 0) alignment = 1; return (Malloc_align(bytes, alignment)); } static void * Malloc_align(size_t bytes, size_t alignment) { Guard *res; #ifdef USEENDGUARD bytes += MALLOCALIGN + 1; #else bytes += MALLOCALIGN; #endif while ((res = znalloc(&MallocPool, bytes, alignment)) == NULL) { int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK; char *base; if ((base = sbrk(incr)) == (char *)-1) return (NULL); zextendPool(&MallocPool, base, incr); zfree(&MallocPool, base, incr); } #ifdef DMALLOCDEBUG if (++MallocCount > MallocMax) MallocMax = MallocCount; #endif #ifdef USEGUARD res->ga_Magic = GAMAGIC; #endif res->ga_Bytes = bytes; #ifdef USEENDGUARD *((signed char *)res + bytes - 1) = -2; #endif return ((char *)res + MALLOCALIGN); } void Free(void *ptr, const char *file, int line) { size_t bytes; if (ptr != NULL) { Guard *res = (void *)((char *)ptr - MALLOCALIGN); if (file == NULL) file = "unknown"; #ifdef USEGUARD if (res->ga_Magic == GAFREE) { printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line); return; } if (res->ga_Magic != GAMAGIC) panic("free: guard1 fail @ %p from %s:%d", ptr, file, line); res->ga_Magic = GAFREE; #endif #ifdef USEENDGUARD if (*((signed char *)res + res->ga_Bytes - 1) == -1) { printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line); return; } if (*((signed char *)res + res->ga_Bytes - 1) != -2) panic("free: guard2 fail @ %p + %zu from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line); *((signed char *)res + res->ga_Bytes - 1) = -1; #endif bytes = res->ga_Bytes; zfree(&MallocPool, res, bytes); #ifdef DMALLOCDEBUG --MallocCount; #endif } } void * Calloc(size_t n1, size_t n2, const char *file, int line) { uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2; void *res; if ((res = Malloc(bytes, file, line)) != NULL) { bzero(res, bytes); #ifdef DMALLOCDEBUG if (++MallocCount > MallocMax) MallocMax = MallocCount; #endif } return (res); } /* * realloc() - I could be fancier here and free the old buffer before * allocating the new one (saving potential fragmentation * and potential buffer copies). But I don't bother. */ void * Realloc(void *ptr, size_t size, const char *file, int line) { void *res; size_t old; if ((res = Malloc(size, file, line)) != NULL) { if (ptr != NULL) { Guard *g = (Guard *)((char *)ptr - MALLOCALIGN); old = g->ga_Bytes - MALLOCALIGN; if (old < size) bcopy(ptr, res, old); else bcopy(ptr, res, size); Free(ptr, file, line); } else { #ifdef DMALLOCDEBUG if (++MallocCount > MallocMax) MallocMax = MallocCount; #ifdef EXITSTATS if (DidAtExit == 0) { DidAtExit = 1; atexit(mallocstats); } #endif #endif } } return (res); } void * Reallocf(void *ptr, size_t size, const char *file, int line) { void *res; if ((res = Realloc(ptr, size, file, line)) == NULL) Free(ptr, file, line); return (res); } #ifdef DMALLOCDEBUG void mallocstats(void) { printf("Active Allocations: %d/%d\n", MallocCount, MallocMax); #ifdef ZALLOCDEBUG zallocstats(&MallocPool); #endif } #endif /* * This module derived from code donated to the FreeBSD Project by * Matthew Dillon * * Copyright (c) 1998 The FreeBSD Project * All rights reserved. * * 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. * * 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. */ /* * H/MEM.H * * Basic memory pool / memory node structures. */ #ifndef _ZALLOC_MEM_H #define _ZALLOC_MEM_H typedef struct MemNode { struct MemNode *mr_Next; uintptr_t mr_Bytes; } MemNode; typedef struct MemPool { void *mp_Base; void *mp_End; MemNode *mp_First; uintptr_t mp_Size; uintptr_t mp_Used; } MemPool; #define ZNOTE_FREE 0 #define ZNOTE_REUSE 1 #endif /* _ZALLOC_MEM_H */ /* * This module derived from code donated to the FreeBSD Project by * Matthew Dillon * * Copyright (c) 1998 The FreeBSD Project * All rights reserved. * * 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. * * 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 _ZALLOC_PROTOS_H #define _ZALLOC_PROTOS_H Library void *znalloc(struct MemPool *mpool, uintptr_t bytes, size_t align); Library void zfree(struct MemPool *mpool, void *ptr, uintptr_t bytes); Library void zextendPool(MemPool *mp, void *base, uintptr_t bytes); Library void zallocstats(struct MemPool *mp); #endif /* _ZALLOC_PROTOS_H */ # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # # Copyright 2021 Toomas Soome # SRCS += $(ZFSSRC)/zfs.c SRCS += $(ZFSSRC)/gzip.c SRCS += $(SRC)/common/list/list.c OBJECTS += zfs.o OBJECTS += gzip.o OBJECTS += nvlist.o OBJECTS += list.o objs/zfs.o: CPPFLAGS += -I../../common pics/zfs.o: CPPFLAGS += -I../../common objs/zfs.o: CPPFLAGS += -I../../sys/cddl/boot/zfs -I$(LZ4) pics/zfs.o: CPPFLAGS += -I../../sys/cddl/boot/zfs -I$(LZ4) objs/zfs.o: CPPFLAGS += -I$(SRC)/uts/common/fs/zfs pics/zfs.o: CPPFLAGS += -I$(SRC)/uts/common/fs/zfs objs/zfs.o: CPPFLAGS += -I$(CRYPTOSRC) pics/zfs.o: CPPFLAGS += -I$(CRYPTOSRC) objs/nvlist.o: CPPFLAGS += -I../../common pics/nvlist.o: CPPFLAGS += -I../../common objs/nvlist.o: CPPFLAGS += -I../../sys/cddl/boot/zfs pics/nvlist.o: CPPFLAGS += -I../../sys/cddl/boot/zfs pics/%.o: $(ZFSSRC)/%.c $(COMPILE.c) -o $@ $< objs/%.o: $(ZFSSRC)/%.c $(COMPILE.c) -o $@ $< pics/%.o: $(SRC)/common/list/%.c $(COMPILE.c) -DNDEBUG -o $@ $< objs/%.o: $(SRC)/common/list/%.c $(COMPILE.c) -DNDEBUG -o $@ $< zfs.o: $(ZFSSRC)/zfsimpl.c /* * Copyright (c) 2012 Andriy Gapon * All rights reserved. * * 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. * * 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. */ #include #include #include "libzfs.h" __attribute__((weak)) int zfs_parsedev(struct zfs_devdesc *dev __unused, const char *devspec __unused, const char **path __unused) { return (EINVAL); } __attribute__((weak)) char * zfs_fmtdev(void *vdev __unused) { static char buf[128]; return (buf); } /* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2015 Toomas Soome * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include int gzip_decompress(void *, void *, size_t, size_t, int); /* * Uncompress the buffer 'src' into the buffer 'dst'. The caller must store * the expected decompressed data size externally so it can be passed in. * The resulting decompressed size is then returned through dstlen. This * function return Z_OK on success, or another error code on failure. */ static int z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen) { z_stream zs; int err; bzero(&zs, sizeof (zs)); zs.next_in = (unsigned char *)src; zs.avail_in = srclen; zs.next_out = dst; zs.avail_out = *dstlen; /* * Call inflateInit2() specifying a window size of DEF_WBITS * with the 6th bit set to indicate that the compression format * type (zlib or gzip) should be automatically detected. */ if ((err = inflateInit2(&zs, 15 | 0x20)) != Z_OK) return (err); if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) { (void) inflateEnd(&zs); return (err == Z_OK ? Z_BUF_ERROR : err); } *dstlen = zs.total_out; return (inflateEnd(&zs)); } int gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n __unused) { size_t dstlen = d_len; if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK) return (-1); return (0); } /* * Copyright (c) 2012 Andriy Gapon * All rights reserved. * * 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. * * 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 _BOOT_LIBZFS_H_ #define _BOOT_LIBZFS_H_ #include #define ZFS_MAXNAMELEN 256 /* * ZFS fully-qualified device descriptor. */ struct zfs_devdesc { struct devdesc dd; /* Must be first. */ uint64_t pool_guid; uint64_t root_guid; }; /* nvp implementation version */ #define NV_VERSION 0 /* nvlist persistent unique name flags, stored in nvl_nvflags */ #define NV_UNIQUE_NAME 0x1 #define NV_UNIQUE_NAME_TYPE 0x2 #define NV_ALIGN4(x) (((x) + 3) & ~3) #define NV_ALIGN(x) (((x) + 7) & ~7) /* * nvlist header. * nvlist has 4 bytes header followed by version and flags, then nvpairs * and the list is terminated by double zero. */ typedef struct { char nvh_encoding; char nvh_endian; char nvh_reserved1; char nvh_reserved2; } nvs_header_t; typedef struct { nvs_header_t nv_header; size_t nv_asize; size_t nv_size; uint8_t *nv_data; uint8_t *nv_idx; } nvlist_t; /* * nvpair header. * nvpair has encoded and decoded size * name string (size and data) * data type and number of elements * data */ typedef struct { unsigned encoded_size; unsigned decoded_size; } nvp_header_t; /* * nvlist stream head. */ typedef struct { unsigned nvl_version; unsigned nvl_nvflag; nvp_header_t nvl_pair; } nvs_data_t; typedef struct { unsigned nv_size; uint8_t nv_data[]; /* NV_ALIGN4(string) */ } nv_string_t; typedef struct { unsigned nv_type; /* data_type_t */ unsigned nv_nelem; /* number of elements */ uint8_t nv_data[]; /* data stream */ } nv_pair_data_t; nvlist_t *nvlist_create(int); void nvlist_destroy(nvlist_t *); nvlist_t *nvlist_import(const char *, size_t); int nvlist_export(nvlist_t *); int nvlist_remove(nvlist_t *, const char *, data_type_t); int nvpair_type_from_name(const char *); nvp_header_t *nvpair_find(nvlist_t *, const char *); void nvpair_print(nvp_header_t *, unsigned int); void nvlist_print(const nvlist_t *, unsigned int); char *nvstring_get(nv_string_t *); int nvlist_find(const nvlist_t *, const char *, data_type_t, int *, void *, int *); nvp_header_t *nvlist_next_nvpair(nvlist_t *, nvp_header_t *); int nvlist_add_boolean_value(nvlist_t *, const char *, boolean_t); int nvlist_add_byte(nvlist_t *, const char *, uint8_t); int nvlist_add_int8(nvlist_t *, const char *, int8_t); int nvlist_add_uint8(nvlist_t *, const char *, uint8_t); int nvlist_add_int16(nvlist_t *, const char *, int16_t); int nvlist_add_uint16(nvlist_t *, const char *, uint16_t); int nvlist_add_int32(nvlist_t *, const char *, int32_t); int nvlist_add_uint32(nvlist_t *, const char *, uint32_t); int nvlist_add_int64(nvlist_t *, const char *, int64_t); int nvlist_add_uint64(nvlist_t *, const char *, uint64_t); int nvlist_add_string(nvlist_t *, const char *, const char *); int nvlist_add_boolean_array(nvlist_t *, const char *, boolean_t *, uint32_t); int nvlist_add_byte_array(nvlist_t *, const char *, uint8_t *, uint32_t); int nvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint32_t); int nvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint32_t); int nvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint32_t); int nvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint32_t); int nvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint32_t); int nvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint32_t); int nvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint32_t); int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint32_t); int nvlist_add_string_array(nvlist_t *, const char *, char * const *, uint32_t); int nvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *); int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint32_t); int zfs_parsedev(struct zfs_devdesc *, const char *, const char **); char *zfs_bootfs(void *); char *zfs_fmtdev(void *); int zfs_probe_dev(const char *, uint64_t *); int zfs_list(const char *); int zfs_get_bootonce(void *, const char *, char *, size_t); int zfs_get_bootenv(void *, nvlist_t **); int zfs_set_bootenv(void *, nvlist_t *); int zfs_attach_nvstore(void *); uint64_t ldi_get_size(void *); nvlist_t *vdev_read_bootenv(vdev_t *); extern struct devsw zfs_dev; extern struct fs_ops zfs_fsops; #endif /* _BOOT_LIBZFS_H_ */ /* * Copyright 2020 Toomas Soome * * 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. * * 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. */ #include #include #include #include #include #include #include #include "libzfs.h" enum xdr_op { XDR_OP_ENCODE = 1, XDR_OP_DECODE = 2 }; typedef struct xdr { enum xdr_op xdr_op; int (*xdr_getint)(struct xdr *, int *); int (*xdr_putint)(struct xdr *, int); int (*xdr_getuint)(struct xdr *, unsigned *); int (*xdr_putuint)(struct xdr *, unsigned); const uint8_t *xdr_buf; uint8_t *xdr_idx; size_t xdr_buf_size; } xdr_t; static int nvlist_xdr_nvlist(xdr_t *, nvlist_t *); static bool nvlist_size_xdr(xdr_t *, size_t *); static bool nvlist_size_native(xdr_t *, size_t *); static bool xdr_int(xdr_t *, int *); static bool xdr_u_int(xdr_t *, unsigned *); typedef bool (*xdrproc_t)(xdr_t *, void *); /* Basic primitives for XDR translation operations, getint and putint. */ static int _getint(struct xdr *xdr, int *ip) { *ip = be32dec(xdr->xdr_idx); return (sizeof (int)); } static int _putint(struct xdr *xdr, int i) { int *ip = (int *)xdr->xdr_idx; *ip = htobe32(i); return (sizeof (int)); } static int _getuint(struct xdr *xdr, unsigned *ip) { *ip = be32dec(xdr->xdr_idx); return (sizeof (unsigned)); } static int _putuint(struct xdr *xdr, unsigned i) { unsigned *up = (unsigned *)xdr->xdr_idx; *up = htobe32(i); return (sizeof (int)); } static int _getint_mem(struct xdr *xdr, int *ip) { *ip = *(int *)xdr->xdr_idx; return (sizeof (int)); } static int _putint_mem(struct xdr *xdr, int i) { int *ip = (int *)xdr->xdr_idx; *ip = i; return (sizeof (int)); } static int _getuint_mem(struct xdr *xdr, unsigned *ip) { *ip = *(unsigned *)xdr->xdr_idx; return (sizeof (unsigned)); } static int _putuint_mem(struct xdr *xdr, unsigned i) { unsigned *up = (unsigned *)xdr->xdr_idx; *up = i; return (sizeof (int)); } /* * XDR data translations. */ static bool xdr_short(xdr_t *xdr, short *ip) { int i; bool rv; i = *ip; if ((rv = xdr_int(xdr, &i))) { if (xdr->xdr_op == XDR_OP_DECODE) *ip = i; } return (rv); } static bool xdr_u_short(xdr_t *xdr, unsigned short *ip) { unsigned u; bool rv; u = *ip; if ((rv = xdr_u_int(xdr, &u))) { if (xdr->xdr_op == XDR_OP_DECODE) *ip = u; } return (rv); } /* * translate xdr->xdr_idx, increment it by size of int. */ static bool xdr_int(xdr_t *xdr, int *ip) { bool rv = false; int *i = (int *)xdr->xdr_idx; if (xdr->xdr_idx + sizeof (int) > xdr->xdr_buf + xdr->xdr_buf_size) return (rv); switch (xdr->xdr_op) { case XDR_OP_ENCODE: /* Encode value *ip, store to buf */ xdr->xdr_idx += xdr->xdr_putint(xdr, *ip); rv = true; break; case XDR_OP_DECODE: /* Decode buf, return value to *ip */ xdr->xdr_idx += xdr->xdr_getint(xdr, i); *ip = *i; rv = true; break; } return (rv); } /* * translate xdr->xdr_idx, increment it by size of unsigned int. */ static bool xdr_u_int(xdr_t *xdr, unsigned *ip) { bool rv = false; unsigned *u = (unsigned *)xdr->xdr_idx; if (xdr->xdr_idx + sizeof (unsigned) > xdr->xdr_buf + xdr->xdr_buf_size) return (rv); switch (xdr->xdr_op) { case XDR_OP_ENCODE: /* Encode value *ip, store to buf */ xdr->xdr_idx += xdr->xdr_putuint(xdr, *ip); rv = true; break; case XDR_OP_DECODE: /* Decode buf, return value to *ip */ xdr->xdr_idx += xdr->xdr_getuint(xdr, u); *ip = *u; rv = true; break; } return (rv); } static bool xdr_int64(xdr_t *xdr, int64_t *lp) { bool rv = false; if (xdr->xdr_idx + sizeof (int64_t) > xdr->xdr_buf + xdr->xdr_buf_size) return (rv); switch (xdr->xdr_op) { case XDR_OP_ENCODE: /* Encode value *lp, store to buf */ if (xdr->xdr_putint == _putint) *(int64_t *)xdr->xdr_idx = htobe64(*lp); else *(int64_t *)xdr->xdr_idx = *lp; xdr->xdr_idx += sizeof (int64_t); rv = true; break; case XDR_OP_DECODE: /* Decode buf, return value to *ip */ if (xdr->xdr_getint == _getint) *lp = be64toh(*(int64_t *)xdr->xdr_idx); else *lp = *(int64_t *)xdr->xdr_idx; xdr->xdr_idx += sizeof (int64_t); rv = true; } return (rv); } static bool xdr_uint64(xdr_t *xdr, uint64_t *lp) { bool rv = false; if (xdr->xdr_idx + sizeof (uint64_t) > xdr->xdr_buf + xdr->xdr_buf_size) return (rv); switch (xdr->xdr_op) { case XDR_OP_ENCODE: /* Encode value *ip, store to buf */ if (xdr->xdr_putint == _putint) *(uint64_t *)xdr->xdr_idx = htobe64(*lp); else *(uint64_t *)xdr->xdr_idx = *lp; xdr->xdr_idx += sizeof (uint64_t); rv = true; break; case XDR_OP_DECODE: /* Decode buf, return value to *ip */ if (xdr->xdr_getuint == _getuint) *lp = be64toh(*(uint64_t *)xdr->xdr_idx); else *lp = *(uint64_t *)xdr->xdr_idx; xdr->xdr_idx += sizeof (uint64_t); rv = true; } return (rv); } static bool xdr_char(xdr_t *xdr, char *cp) { int i; bool rv = false; i = *cp; if ((rv = xdr_int(xdr, &i))) { if (xdr->xdr_op == XDR_OP_DECODE) *cp = i; } return (rv); } static bool xdr_string(xdr_t *xdr, nv_string_t *s) { int size = 0; bool rv = false; switch (xdr->xdr_op) { case XDR_OP_ENCODE: size = s->nv_size; if (xdr->xdr_idx + sizeof (unsigned) + NV_ALIGN4(size) > xdr->xdr_buf + xdr->xdr_buf_size) break; xdr->xdr_idx += xdr->xdr_putuint(xdr, s->nv_size); xdr->xdr_idx += NV_ALIGN4(size); rv = true; break; case XDR_OP_DECODE: if (xdr->xdr_idx + sizeof (unsigned) > xdr->xdr_buf + xdr->xdr_buf_size) break; size = xdr->xdr_getuint(xdr, &s->nv_size); size = NV_ALIGN4(size + s->nv_size); if (xdr->xdr_idx + size > xdr->xdr_buf + xdr->xdr_buf_size) break; xdr->xdr_idx += size; rv = true; break; } return (rv); } static bool xdr_array(xdr_t *xdr, const unsigned nelem, const xdrproc_t elproc) { bool rv = true; unsigned c = nelem; if (!xdr_u_int(xdr, &c)) return (false); for (unsigned i = 0; i < nelem; i++) { if (!elproc(xdr, xdr->xdr_idx)) return (false); } return (rv); } /* * nvlist management functions. */ void nvlist_destroy(nvlist_t *nvl) { if (nvl != NULL) { /* Free data if it was allocated by us. */ if (nvl->nv_asize > 0) free(nvl->nv_data); } free(nvl); } char * nvstring_get(nv_string_t *nvs) { char *s; s = malloc(nvs->nv_size + 1); if (s != NULL) { bcopy(nvs->nv_data, s, nvs->nv_size); s[nvs->nv_size] = '\0'; } return (s); } /* * Create empty nvlist. * The nvlist is terminated by 2x zeros (8 bytes). */ nvlist_t * nvlist_create(int flag) { nvlist_t *nvl; nvs_data_t *nvs; nvl = calloc(1, sizeof (*nvl)); if (nvl == NULL) return (nvl); nvl->nv_header.nvh_encoding = NV_ENCODE_XDR; nvl->nv_header.nvh_endian = _BYTE_ORDER == _LITTLE_ENDIAN; nvl->nv_asize = nvl->nv_size = sizeof (*nvs); nvs = calloc(1, nvl->nv_asize); if (nvs == NULL) { free(nvl); return (NULL); } /* data in nvlist is byte stream */ nvl->nv_data = (uint8_t *)nvs; nvs->nvl_version = NV_VERSION; nvs->nvl_nvflag = flag; return (nvl); } static bool nvlist_xdr_nvp(xdr_t *xdr, nvlist_t *nvl) { nv_string_t *nv_string; nv_pair_data_t *nvp_data; nvlist_t nvlist; unsigned type, nelem; xdr_t nv_xdr; nv_string = (nv_string_t *)xdr->xdr_idx; if (!xdr_string(xdr, nv_string)) { return (false); } nvp_data = (nv_pair_data_t *)xdr->xdr_idx; type = nvp_data->nv_type; nelem = nvp_data->nv_nelem; if (!xdr_u_int(xdr, &type) || !xdr_u_int(xdr, &nelem)) return (false); switch (type) { case DATA_TYPE_NVLIST: case DATA_TYPE_NVLIST_ARRAY: bzero(&nvlist, sizeof (nvlist)); nvlist.nv_data = xdr->xdr_idx; nvlist.nv_idx = nvlist.nv_data; /* Set up xdr for this nvlist. */ nv_xdr = *xdr; nv_xdr.xdr_buf = nvlist.nv_data; nv_xdr.xdr_idx = nvlist.nv_data; nv_xdr.xdr_buf_size = nvl->nv_data + nvl->nv_size - nvlist.nv_data; for (unsigned i = 0; i < nelem; i++) { if (xdr->xdr_op == XDR_OP_ENCODE) { if (!nvlist_size_native(&nv_xdr, &nvlist.nv_size)) return (false); } else { if (!nvlist_size_xdr(&nv_xdr, &nvlist.nv_size)) return (false); } if (nvlist_xdr_nvlist(xdr, &nvlist) != 0) return (false); nvlist.nv_data = nv_xdr.xdr_idx; nvlist.nv_idx = nv_xdr.xdr_idx; nv_xdr.xdr_buf = nv_xdr.xdr_idx; nv_xdr.xdr_buf_size = nvl->nv_data + nvl->nv_size - nvlist.nv_data; } break; case DATA_TYPE_BOOLEAN: /* BOOLEAN does not take value space */ break; case DATA_TYPE_BYTE: case DATA_TYPE_INT8: case DATA_TYPE_UINT8: if (!xdr_char(xdr, (char *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_INT16: if (!xdr_short(xdr, (short *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_UINT16: if (!xdr_u_short(xdr, (unsigned short *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_INT32: if (!xdr_int(xdr, (int *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_UINT32: if (!xdr_u_int(xdr, (unsigned *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_HRTIME: case DATA_TYPE_INT64: if (!xdr_int64(xdr, (int64_t *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_UINT64: if (!xdr_uint64(xdr, (uint64_t *)&nvp_data->nv_data[0])) return (false); break; case DATA_TYPE_BYTE_ARRAY: case DATA_TYPE_STRING: nv_string = (nv_string_t *)&nvp_data->nv_data[0]; if (!xdr_string(xdr, nv_string)) return (false); break; case DATA_TYPE_STRING_ARRAY: nv_string = (nv_string_t *)&nvp_data->nv_data[0]; for (unsigned i = 0; i < nelem; i++) { if (!xdr_string(xdr, nv_string)) return (false); nv_string = (nv_string_t *)xdr->xdr_idx; } break; case DATA_TYPE_INT8_ARRAY: case DATA_TYPE_UINT8_ARRAY: case DATA_TYPE_INT16_ARRAY: case DATA_TYPE_UINT16_ARRAY: case DATA_TYPE_BOOLEAN_ARRAY: case DATA_TYPE_INT32_ARRAY: case DATA_TYPE_UINT32_ARRAY: if (!xdr_array(xdr, nelem, (xdrproc_t)xdr_u_int)) return (false); break; case DATA_TYPE_INT64_ARRAY: case DATA_TYPE_UINT64_ARRAY: if (!xdr_array(xdr, nelem, (xdrproc_t)xdr_uint64)) return (false); break; } return (true); } static int nvlist_xdr_nvlist(xdr_t *xdr, nvlist_t *nvl) { nvp_header_t *nvph; nvs_data_t *nvs; unsigned encoded_size, decoded_size; int rv; nvs = (nvs_data_t *)xdr->xdr_idx; nvph = &nvs->nvl_pair; if (!xdr_u_int(xdr, &nvs->nvl_version)) return (EINVAL); if (!xdr_u_int(xdr, &nvs->nvl_nvflag)) return (EINVAL); encoded_size = nvph->encoded_size; decoded_size = nvph->decoded_size; if (xdr->xdr_op == XDR_OP_ENCODE) { if (!xdr_u_int(xdr, &nvph->encoded_size)) return (EINVAL); if (!xdr_u_int(xdr, &nvph->decoded_size)) return (EINVAL); } else { xdr->xdr_idx += 2 * sizeof (unsigned); } rv = 0; while (encoded_size && decoded_size) { if (!nvlist_xdr_nvp(xdr, nvl)) return (EINVAL); nvph = (nvp_header_t *)(xdr->xdr_idx); encoded_size = nvph->encoded_size; decoded_size = nvph->decoded_size; if (xdr->xdr_op == XDR_OP_ENCODE) { if (!xdr_u_int(xdr, &nvph->encoded_size)) return (EINVAL); if (!xdr_u_int(xdr, &nvph->decoded_size)) return (EINVAL); } else { xdr->xdr_idx += 2 * sizeof (unsigned); } } return (rv); } /* * Calculate nvlist size, translating encoded_size and decoded_size. */ static bool nvlist_size_xdr(xdr_t *xdr, size_t *size) { uint8_t *pair; unsigned encoded_size, decoded_size; xdr->xdr_idx += 2 * sizeof (unsigned); pair = xdr->xdr_idx; if (!xdr_u_int(xdr, &encoded_size) || !xdr_u_int(xdr, &decoded_size)) return (false); while (encoded_size && decoded_size) { xdr->xdr_idx = pair + encoded_size; pair = xdr->xdr_idx; if (!xdr_u_int(xdr, &encoded_size) || !xdr_u_int(xdr, &decoded_size)) return (false); } *size = xdr->xdr_idx - xdr->xdr_buf; return (true); } nvp_header_t * nvlist_next_nvpair(nvlist_t *nvl, nvp_header_t *nvh) { uint8_t *pair; unsigned encoded_size, decoded_size; xdr_t xdr; if (nvl == NULL) return (NULL); xdr.xdr_buf = nvl->nv_data; xdr.xdr_idx = nvl->nv_data; xdr.xdr_buf_size = nvl->nv_size; xdr.xdr_idx += 2 * sizeof (unsigned); /* Skip tp current pair */ if (nvh != NULL) { xdr.xdr_idx = (uint8_t *)nvh; } pair = xdr.xdr_idx; if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); encoded_size = *(unsigned *)xdr.xdr_idx; xdr.xdr_idx += sizeof (unsigned); if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); decoded_size = *(unsigned *)xdr.xdr_idx; xdr.xdr_idx += sizeof (unsigned); if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); while (encoded_size && decoded_size) { if (nvh == NULL) return ((nvp_header_t *)pair); xdr.xdr_idx = pair + encoded_size; nvh = (nvp_header_t *)xdr.xdr_idx; if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); encoded_size = *(unsigned *)xdr.xdr_idx; xdr.xdr_idx += sizeof (unsigned); if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); decoded_size = *(unsigned *)xdr.xdr_idx; xdr.xdr_idx += sizeof (unsigned); if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size) return (NULL); if (encoded_size != 0 && decoded_size != 0) { return (nvh); } } return (NULL); } /* * Calculate nvlist size by walking in memory data. */ static bool nvlist_size_native(xdr_t *xdr, size_t *size) { uint8_t *pair; unsigned encoded_size, decoded_size; xdr->xdr_idx += 2 * sizeof (unsigned); pair = xdr->xdr_idx; if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size) return (false); encoded_size = *(unsigned *)xdr->xdr_idx; xdr->xdr_idx += sizeof (unsigned); if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size) return (false); decoded_size = *(unsigned *)xdr->xdr_idx; xdr->xdr_idx += sizeof (unsigned); while (encoded_size && decoded_size) { xdr->xdr_idx = pair + encoded_size; pair = xdr->xdr_idx; if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size) return (false); encoded_size = *(unsigned *)xdr->xdr_idx; xdr->xdr_idx += sizeof (unsigned); if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size) return (false); decoded_size = *(unsigned *)xdr->xdr_idx; xdr->xdr_idx += sizeof (unsigned); } *size = xdr->xdr_idx - xdr->xdr_buf; return (true); } /* * Export nvlist to byte stream format. */ int nvlist_export(nvlist_t *nvl) { int rv; xdr_t xdr = { .xdr_op = XDR_OP_ENCODE, .xdr_putint = _putint, .xdr_putuint = _putuint, .xdr_buf = nvl->nv_data, .xdr_idx = nvl->nv_data, .xdr_buf_size = nvl->nv_size }; if (nvl->nv_header.nvh_encoding != NV_ENCODE_XDR) return (ENOTSUP); nvl->nv_idx = nvl->nv_data; rv = nvlist_xdr_nvlist(&xdr, nvl); return (rv); } /* * Import nvlist from byte stream. * Determine the stream size and allocate private copy. * Then translate the data. */ nvlist_t * nvlist_import(const char *stream, size_t size) { nvlist_t *nvl; xdr_t xdr = { .xdr_op = XDR_OP_DECODE, .xdr_getint = _getint, .xdr_getuint = _getuint }; /* Check the nvlist head. */ if (stream[0] != NV_ENCODE_XDR || (stream[1] != '\0' && stream[1] != '\1') || stream[2] != '\0' || stream[3] != '\0' || be32toh(*(uint32_t *)(stream + 4)) != NV_VERSION || be32toh(*(uint32_t *)(stream + 8)) != NV_UNIQUE_NAME) return (NULL); nvl = malloc(sizeof (*nvl)); if (nvl == NULL) return (nvl); nvl->nv_header.nvh_encoding = stream[0]; nvl->nv_header.nvh_endian = stream[1]; nvl->nv_header.nvh_reserved1 = stream[2]; nvl->nv_header.nvh_reserved2 = stream[3]; xdr.xdr_buf = xdr.xdr_idx = (uint8_t *)stream + 4; xdr.xdr_buf_size = size - 4; if (!nvlist_size_xdr(&xdr, &nvl->nv_asize)) { free(nvl); return (NULL); } nvl->nv_size = nvl->nv_asize; nvl->nv_data = malloc(nvl->nv_asize); if (nvl->nv_data == NULL) { free(nvl); return (NULL); } nvl->nv_idx = nvl->nv_data; bcopy(stream + 4, nvl->nv_data, nvl->nv_asize); xdr.xdr_buf = xdr.xdr_idx = nvl->nv_data; xdr.xdr_buf_size = nvl->nv_asize; if (nvlist_xdr_nvlist(&xdr, nvl) != 0) { free(nvl->nv_data); free(nvl); nvl = NULL; } return (nvl); } /* * remove pair from this nvlist. */ int nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type) { uint8_t *head, *tail; nvs_data_t *data; nvp_header_t *nvp; nv_string_t *nvp_name; nv_pair_data_t *nvp_data; size_t size; xdr_t xdr; if (nvl == NULL || nvl->nv_data == NULL || name == NULL) return (EINVAL); /* Make sure the nvlist size is set correct */ xdr.xdr_idx = nvl->nv_data; xdr.xdr_buf = xdr.xdr_idx; xdr.xdr_buf_size = nvl->nv_size; if (!nvlist_size_native(&xdr, &nvl->nv_size)) return (EINVAL); data = (nvs_data_t *)nvl->nv_data; nvp = &data->nvl_pair; /* first pair in nvlist */ head = (uint8_t *)nvp; while (nvp->encoded_size != 0 && nvp->decoded_size != 0) { nvp_name = (nv_string_t *)(nvp + 1); nvp_data = (nv_pair_data_t *)(&nvp_name->nv_data[0] + NV_ALIGN4(nvp_name->nv_size)); if (strlen(name) == nvp_name->nv_size && memcmp(nvp_name->nv_data, name, nvp_name->nv_size) == 0 && (nvp_data->nv_type == type || type == DATA_TYPE_UNKNOWN)) { /* * set tail to point to next nvpair and size * is the length of the tail. */ tail = head + nvp->encoded_size; size = nvl->nv_size - (tail - nvl->nv_data); /* adjust the size of the nvlist. */ nvl->nv_size -= nvp->encoded_size; bcopy(tail, head, size); return (0); } /* Not our pair, skip to next. */ head = head + nvp->encoded_size; nvp = (nvp_header_t *)head; } return (ENOENT); } static int clone_nvlist(const nvlist_t *nvl, const uint8_t *ptr, unsigned size, nvlist_t **nvlist) { nvlist_t *nv; nv = calloc(1, sizeof (*nv)); if (nv == NULL) return (ENOMEM); nv->nv_header = nvl->nv_header; nv->nv_asize = size; nv->nv_size = size; nv->nv_data = malloc(nv->nv_asize); if (nv->nv_data == NULL) { free(nv); return (ENOMEM); } bcopy(ptr, nv->nv_data, nv->nv_asize); *nvlist = nv; return (0); } /* * Return the next nvlist in an nvlist array. */ static uint8_t * nvlist_next(const uint8_t *ptr) { nvs_data_t *data; nvp_header_t *nvp; data = (nvs_data_t *)ptr; nvp = &data->nvl_pair; /* first pair in nvlist */ while (nvp->encoded_size != 0 && nvp->decoded_size != 0) { nvp = (nvp_header_t *)((uint8_t *)nvp + nvp->encoded_size); } return ((uint8_t *)nvp + sizeof (*nvp)); } /* * Note: nvlist and nvlist array must be freed by caller. */ int nvlist_find(const nvlist_t *nvl, const char *name, data_type_t type, int *elementsp, void *valuep, int *sizep) { nvs_data_t *data; nvp_header_t *nvp; nv_string_t *nvp_name; nv_pair_data_t *nvp_data; nvlist_t **nvlist, *nv; uint8_t *ptr; int rv; if (nvl == NULL || nvl->nv_data == NULL || name == NULL) return (EINVAL); data = (nvs_data_t *)nvl->nv_data; nvp = &data->nvl_pair; /* first pair in nvlist */ while (nvp->encoded_size != 0 && nvp->decoded_size != 0) { nvp_name = (nv_string_t *)((uint8_t *)nvp + sizeof (*nvp)); if (nvl->nv_data + nvl->nv_size < nvp_name->nv_data + nvp_name->nv_size) return (EIO); nvp_data = (nv_pair_data_t *) NV_ALIGN4((uintptr_t)&nvp_name->nv_data[0] + nvp_name->nv_size); if (strlen(name) == nvp_name->nv_size && memcmp(nvp_name->nv_data, name, nvp_name->nv_size) == 0 && (nvp_data->nv_type == type || type == DATA_TYPE_UNKNOWN)) { if (elementsp != NULL) *elementsp = nvp_data->nv_nelem; switch (nvp_data->nv_type) { case DATA_TYPE_UINT64: bcopy(nvp_data->nv_data, valuep, sizeof (uint64_t)); return (0); case DATA_TYPE_STRING: nvp_name = (nv_string_t *)nvp_data->nv_data; if (sizep != NULL) { *sizep = nvp_name->nv_size; } *(const uint8_t **)valuep = &nvp_name->nv_data[0]; return (0); case DATA_TYPE_NVLIST: ptr = &nvp_data->nv_data[0]; rv = clone_nvlist(nvl, ptr, nvlist_next(ptr) - ptr, &nv); if (rv == 0) { *(nvlist_t **)valuep = nv; } return (rv); case DATA_TYPE_NVLIST_ARRAY: nvlist = calloc(nvp_data->nv_nelem, sizeof (nvlist_t *)); if (nvlist == NULL) return (ENOMEM); ptr = &nvp_data->nv_data[0]; rv = 0; for (unsigned i = 0; i < nvp_data->nv_nelem; i++) { rv = clone_nvlist(nvl, ptr, nvlist_next(ptr) - ptr, &nvlist[i]); if (rv != 0) goto error; ptr = nvlist_next(ptr); } *(nvlist_t ***)valuep = nvlist; return (rv); } return (EIO); } /* Not our pair, skip to next. */ nvp = (nvp_header_t *)((uint8_t *)nvp + nvp->encoded_size); if (nvl->nv_data + nvl->nv_size < (uint8_t *)nvp) return (EIO); } return (ENOENT); error: for (unsigned i = 0; i < nvp_data->nv_nelem; i++) { free(nvlist[i]->nv_data); free(nvlist[i]); } free(nvlist); return (rv); } static int get_value_size(data_type_t type, const void *data, uint32_t nelem) { uint64_t value_sz = 0; switch (type) { case DATA_TYPE_BOOLEAN: value_sz = 0; break; case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_BYTE: case DATA_TYPE_INT8: case DATA_TYPE_UINT8: case DATA_TYPE_INT16: case DATA_TYPE_UINT16: case DATA_TYPE_INT32: case DATA_TYPE_UINT32: /* Our smallest data unit is 32-bit */ value_sz = sizeof (uint32_t); break; case DATA_TYPE_HRTIME: case DATA_TYPE_INT64: value_sz = sizeof (int64_t); break; case DATA_TYPE_UINT64: value_sz = sizeof (uint64_t); break; case DATA_TYPE_STRING: if (data == NULL) value_sz = 0; else value_sz = strlen(data) + 1; break; case DATA_TYPE_BYTE_ARRAY: value_sz = nelem * sizeof (uint8_t); break; case DATA_TYPE_BOOLEAN_ARRAY: case DATA_TYPE_INT8_ARRAY: case DATA_TYPE_UINT8_ARRAY: case DATA_TYPE_INT16_ARRAY: case DATA_TYPE_UINT16_ARRAY: case DATA_TYPE_INT32_ARRAY: case DATA_TYPE_UINT32_ARRAY: value_sz = (uint64_t)nelem * sizeof (uint32_t); break; case DATA_TYPE_INT64_ARRAY: value_sz = (uint64_t)nelem * sizeof (int64_t); break; case DATA_TYPE_UINT64_ARRAY: value_sz = (uint64_t)nelem * sizeof (uint64_t); break; case DATA_TYPE_STRING_ARRAY: value_sz = (uint64_t)nelem * sizeof (uint64_t); if (data != NULL) { char *const *strs = data; uint32_t i; for (i = 0; i < nelem; i++) { if (strs[i] == NULL) return (-1); value_sz += strlen(strs[i]) + 1; } } break; case DATA_TYPE_NVLIST: /* * The decoded size of nvlist is constant. */ value_sz = NV_ALIGN(6 * 4); /* sizeof nvlist_t */ break; case DATA_TYPE_NVLIST_ARRAY: value_sz = (uint64_t)nelem * sizeof (uint64_t) + (uint64_t)nelem * NV_ALIGN(6 * 4); /* sizeof nvlist_t */ break; default: return (-1); } return (value_sz > INT32_MAX ? -1 : (int)value_sz); } static int get_nvp_data_size(data_type_t type, const void *data, uint32_t nelem) { uint64_t value_sz = 0; xdr_t xdr; size_t size; switch (type) { case DATA_TYPE_BOOLEAN: value_sz = 0; break; case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_BYTE: case DATA_TYPE_INT8: case DATA_TYPE_UINT8: case DATA_TYPE_INT16: case DATA_TYPE_UINT16: case DATA_TYPE_INT32: case DATA_TYPE_UINT32: /* Our smallest data unit is 32-bit */ value_sz = sizeof (uint32_t); break; case DATA_TYPE_HRTIME: case DATA_TYPE_INT64: case DATA_TYPE_UINT64: value_sz = sizeof (uint64_t); break; case DATA_TYPE_STRING: value_sz = 4 + NV_ALIGN4(strlen(data)); break; case DATA_TYPE_BYTE_ARRAY: value_sz = NV_ALIGN4(nelem); break; case DATA_TYPE_BOOLEAN_ARRAY: case DATA_TYPE_INT8_ARRAY: case DATA_TYPE_UINT8_ARRAY: case DATA_TYPE_INT16_ARRAY: case DATA_TYPE_UINT16_ARRAY: case DATA_TYPE_INT32_ARRAY: case DATA_TYPE_UINT32_ARRAY: value_sz = 4 + (uint64_t)nelem * sizeof (uint32_t); break; case DATA_TYPE_INT64_ARRAY: case DATA_TYPE_UINT64_ARRAY: value_sz = 4 + (uint64_t)nelem * sizeof (uint64_t); break; case DATA_TYPE_STRING_ARRAY: if (data != NULL) { char *const *strs = data; uint32_t i; for (i = 0; i < nelem; i++) { value_sz += 4 + NV_ALIGN4(strlen(strs[i])); } } break; case DATA_TYPE_NVLIST: xdr.xdr_idx = ((nvlist_t *)data)->nv_data; xdr.xdr_buf = xdr.xdr_idx; xdr.xdr_buf_size = ((nvlist_t *)data)->nv_size; if (!nvlist_size_native(&xdr, &size)) return (-1); value_sz = size; break; case DATA_TYPE_NVLIST_ARRAY: value_sz = 0; for (uint32_t i = 0; i < nelem; i++) { xdr.xdr_idx = ((nvlist_t **)data)[i]->nv_data; xdr.xdr_buf = xdr.xdr_idx; xdr.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size; if (!nvlist_size_native(&xdr, &size)) return (-1); value_sz += size; } break; default: return (-1); } return (value_sz > INT32_MAX ? -1 : (int)value_sz); } #define NVPE_SIZE(name_len, data_len) \ (4 + 4 + 4 + NV_ALIGN4(name_len) + 4 + 4 + data_len) #define NVP_SIZE(name_len, data_len) \ (NV_ALIGN((4 * 4) + (name_len)) + NV_ALIGN(data_len)) static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type, uint32_t nelem, const void *data) { nvs_data_t *nvs; nvp_header_t head, *hp; uint8_t *ptr; size_t namelen; int decoded_size, encoded_size; xdr_t xdr = { .xdr_op = XDR_OP_ENCODE, .xdr_putint = _putint_mem, .xdr_putuint = _putuint_mem, .xdr_buf = nvl->nv_data, .xdr_idx = nvl->nv_data, .xdr_buf_size = nvl->nv_size }; nvs = (nvs_data_t *)nvl->nv_data; if (nvs->nvl_nvflag & NV_UNIQUE_NAME) (void) nvlist_remove(nvl, name, type); if (!nvlist_size_native(&xdr, &nvl->nv_size)) return (EINVAL); namelen = strlen(name); if ((decoded_size = get_value_size(type, data, nelem)) < 0) return (EINVAL); if ((encoded_size = get_nvp_data_size(type, data, nelem)) < 0) return (EINVAL); /* * The encoded size is calculated as: * encode_size (4) + decode_size (4) + * name string size (4 + NV_ALIGN4(namelen) + * data type (4) + nelem size (4) + datalen * * The decoded size is calculated as: * Note: namelen is with terminating 0. * NV_ALIGN(sizeof (nvpair_t) (4 * 4) + namelen + 1) + * NV_ALIGN(data_len) */ head.encoded_size = NVPE_SIZE(namelen, encoded_size); head.decoded_size = NVP_SIZE(namelen + 1, decoded_size); if (nvl->nv_asize - nvl->nv_size < head.encoded_size + 8) { ptr = realloc(nvl->nv_data, nvl->nv_asize + head.encoded_size); if (ptr == NULL) return (ENOMEM); nvl->nv_data = ptr; nvl->nv_asize += head.encoded_size; } nvl->nv_idx = nvl->nv_data + nvl->nv_size - sizeof (*hp); bzero(nvl->nv_idx, head.encoded_size + 8); hp = (nvp_header_t *)nvl->nv_idx; *hp = head; nvl->nv_idx += sizeof (*hp); xdr.xdr_buf = nvl->nv_data; xdr.xdr_buf_size = nvl->nv_asize; xdr.xdr_idx = nvl->nv_idx; xdr.xdr_idx += xdr.xdr_putuint(&xdr, namelen); strlcpy((char *)xdr.xdr_idx, name, namelen + 1); xdr.xdr_idx += NV_ALIGN4(namelen); xdr.xdr_idx += xdr.xdr_putuint(&xdr, type); xdr.xdr_idx += xdr.xdr_putuint(&xdr, nelem); switch (type) { case DATA_TYPE_BOOLEAN: break; case DATA_TYPE_BYTE_ARRAY: xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size); bcopy(data, xdr.xdr_idx, nelem); xdr.xdr_idx += NV_ALIGN4(encoded_size); break; case DATA_TYPE_STRING: encoded_size = strlen(data); xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size); strlcpy((char *)xdr.xdr_idx, data, encoded_size + 1); xdr.xdr_idx += NV_ALIGN4(encoded_size); break; case DATA_TYPE_STRING_ARRAY: for (uint32_t i = 0; i < nelem; i++) { encoded_size = strlen(((char **)data)[i]); xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size); strlcpy((char *)xdr.xdr_idx, ((char **)data)[i], encoded_size + 1); xdr.xdr_idx += NV_ALIGN4(encoded_size); } break; case DATA_TYPE_BYTE: case DATA_TYPE_INT8: case DATA_TYPE_UINT8: xdr_char(&xdr, (char *)data); break; case DATA_TYPE_INT8_ARRAY: case DATA_TYPE_UINT8_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_char); break; case DATA_TYPE_INT16: xdr_short(&xdr, (short *)data); break; case DATA_TYPE_UINT16: xdr_u_short(&xdr, (unsigned short *)data); break; case DATA_TYPE_INT16_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_short); break; case DATA_TYPE_UINT16_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_u_short); break; case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_INT32: xdr_int(&xdr, (int *)data); break; case DATA_TYPE_UINT32: xdr_u_int(&xdr, (unsigned int *)data); break; case DATA_TYPE_BOOLEAN_ARRAY: case DATA_TYPE_INT32_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_int); break; case DATA_TYPE_UINT32_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_u_int); break; case DATA_TYPE_INT64: xdr_int64(&xdr, (int64_t *)data); break; case DATA_TYPE_UINT64: xdr_uint64(&xdr, (uint64_t *)data); break; case DATA_TYPE_INT64_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_int64); break; case DATA_TYPE_UINT64_ARRAY: xdr_array(&xdr, nelem, (xdrproc_t)xdr_uint64); break; case DATA_TYPE_NVLIST: bcopy(((nvlist_t *)data)->nv_data, xdr.xdr_idx, encoded_size); break; case DATA_TYPE_NVLIST_ARRAY: { size_t size; xdr_t xdr_nv; for (uint32_t i = 0; i < nelem; i++) { xdr_nv.xdr_idx = ((nvlist_t **)data)[i]->nv_data; xdr_nv.xdr_buf = xdr_nv.xdr_idx; xdr_nv.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size; if (!nvlist_size_native(&xdr_nv, &size)) return (EINVAL); bcopy(((nvlist_t **)data)[i]->nv_data, xdr.xdr_idx, size); xdr.xdr_idx += size; } break; } default: bcopy(data, xdr.xdr_idx, encoded_size); } nvl->nv_size += head.encoded_size; return (0); } int nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1, &value)); } int nvlist_add_byte(nvlist_t *nvl, const char *name, uint8_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE, 1, &value)); } int nvlist_add_int8(nvlist_t *nvl, const char *name, int8_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT8, 1, &value)); } int nvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8, 1, &value)); } int nvlist_add_int16(nvlist_t *nvl, const char *name, int16_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT16, 1, &value)); } int nvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16, 1, &value)); } int nvlist_add_int32(nvlist_t *nvl, const char *name, int32_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT32, 1, &value)); } int nvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32, 1, &value)); } int nvlist_add_int64(nvlist_t *nvl, const char *name, int64_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT64, 1, &value)); } int nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t value) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &value)); } int nvlist_add_string(nvlist_t *nvl, const char *name, const char *value) { return (nvlist_add_common(nvl, name, DATA_TYPE_STRING, 1, value)); } int nvlist_add_boolean_array(nvlist_t *nvl, const char *name, boolean_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a)); } int nvlist_add_byte_array(nvlist_t *nvl, const char *name, uint8_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a)); } int nvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a)); } int nvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a)); } int nvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a)); } int nvlist_add_uint16_array(nvlist_t *nvl, const char *name, uint16_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a)); } int nvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a)); } int nvlist_add_uint32_array(nvlist_t *nvl, const char *name, uint32_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a)); } int nvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a)); } int nvlist_add_uint64_array(nvlist_t *nvl, const char *name, uint64_t *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a)); } int nvlist_add_string_array(nvlist_t *nvl, const char *name, char * const *a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a)); } int nvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val) { return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val)); } int nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **a, uint32_t n) { return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a)); } static const char *typenames[] = { "DATA_TYPE_UNKNOWN", "DATA_TYPE_BOOLEAN", "DATA_TYPE_BYTE", "DATA_TYPE_INT16", "DATA_TYPE_UINT16", "DATA_TYPE_INT32", "DATA_TYPE_UINT32", "DATA_TYPE_INT64", "DATA_TYPE_UINT64", "DATA_TYPE_STRING", "DATA_TYPE_BYTE_ARRAY", "DATA_TYPE_INT16_ARRAY", "DATA_TYPE_UINT16_ARRAY", "DATA_TYPE_INT32_ARRAY", "DATA_TYPE_UINT32_ARRAY", "DATA_TYPE_INT64_ARRAY", "DATA_TYPE_UINT64_ARRAY", "DATA_TYPE_STRING_ARRAY", "DATA_TYPE_HRTIME", "DATA_TYPE_NVLIST", "DATA_TYPE_NVLIST_ARRAY", "DATA_TYPE_BOOLEAN_VALUE", "DATA_TYPE_INT8", "DATA_TYPE_UINT8", "DATA_TYPE_BOOLEAN_ARRAY", "DATA_TYPE_INT8_ARRAY", "DATA_TYPE_UINT8_ARRAY" }; int nvpair_type_from_name(const char *name) { unsigned i; for (i = 0; i < nitems(typenames); i++) { if (strcmp(name, typenames[i]) == 0) return (i); } return (0); } nvp_header_t * nvpair_find(nvlist_t *nv, const char *name) { nvp_header_t *nvh; nvh = NULL; while ((nvh = nvlist_next_nvpair(nv, nvh)) != NULL) { nv_string_t *nvp_name; nvp_name = (nv_string_t *)(nvh + 1); if (nvp_name->nv_size == strlen(name) && memcmp(nvp_name->nv_data, name, nvp_name->nv_size) == 0) break; } return (nvh); } void nvpair_print(nvp_header_t *nvp, unsigned int indent) { nv_string_t *nvp_name; nv_pair_data_t *nvp_data; nvlist_t nvlist; unsigned i, j; xdr_t xdr = { .xdr_op = XDR_OP_DECODE, .xdr_getint = _getint_mem, .xdr_getuint = _getuint_mem, .xdr_buf = (const uint8_t *)nvp, .xdr_idx = NULL, .xdr_buf_size = nvp->encoded_size }; nvp_name = (nv_string_t *)((uintptr_t)nvp + sizeof (*nvp)); nvp_data = (nv_pair_data_t *) NV_ALIGN4((uintptr_t)&nvp_name->nv_data[0] + nvp_name->nv_size); for (i = 0; i < indent; i++) printf(" "); printf("%s [%d] %.*s", typenames[nvp_data->nv_type], nvp_data->nv_nelem, nvp_name->nv_size, nvp_name->nv_data); xdr.xdr_idx = nvp_data->nv_data; switch (nvp_data->nv_type) { case DATA_TYPE_BYTE: case DATA_TYPE_INT8: case DATA_TYPE_UINT8: { char c; if (xdr_char(&xdr, &c)) printf(" = 0x%x\n", c); break; } case DATA_TYPE_INT16: case DATA_TYPE_UINT16: { unsigned short u; if (xdr_u_short(&xdr, &u)) printf(" = 0x%hx\n", u); break; } case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_INT32: case DATA_TYPE_UINT32: { unsigned u; if (xdr_u_int(&xdr, &u)) printf(" = 0x%x\n", u); break; } case DATA_TYPE_INT64: case DATA_TYPE_UINT64: { uint64_t u; if (xdr_uint64(&xdr, &u)) printf(" = 0x%jx\n", (uintmax_t)u); break; } case DATA_TYPE_INT64_ARRAY: case DATA_TYPE_UINT64_ARRAY: { uint64_t *u; if (xdr_array(&xdr, nvp_data->nv_nelem, (xdrproc_t)xdr_uint64)) { u = (uint64_t *)(nvp_data->nv_data + sizeof (unsigned)); for (i = 0; i < nvp_data->nv_nelem; i++) printf(" [%u] = 0x%jx", i, (uintmax_t)u[i]); printf("\n"); } break; } case DATA_TYPE_STRING: case DATA_TYPE_STRING_ARRAY: nvp_name = (nv_string_t *)&nvp_data->nv_data[0]; for (i = 0; i < nvp_data->nv_nelem; i++) { printf(" = \"%.*s\"\n", nvp_name->nv_size, nvp_name->nv_data); } break; case DATA_TYPE_NVLIST: printf("\n"); nvlist.nv_data = &nvp_data->nv_data[0]; nvlist_print(&nvlist, indent + 2); break; case DATA_TYPE_NVLIST_ARRAY: nvlist.nv_data = &nvp_data->nv_data[0]; for (j = 0; j < nvp_data->nv_nelem; j++) { size_t size; printf("[%d]\n", j); nvlist_print(&nvlist, indent + 2); if (j != nvp_data->nv_nelem - 1) { for (i = 0; i < indent; i++) printf(" "); printf("%s %.*s", typenames[nvp_data->nv_type], nvp_name->nv_size, nvp_name->nv_data); } xdr.xdr_idx = nvlist.nv_data; xdr.xdr_buf = xdr.xdr_idx; xdr.xdr_buf_size = nvp->encoded_size - (xdr.xdr_idx - (uint8_t *)nvp); if (!nvlist_size_native(&xdr, &size)) return; nvlist.nv_data += size; } break; default: printf("\n"); } } void nvlist_print(const nvlist_t *nvl, unsigned int indent) { nvs_data_t *data; nvp_header_t *nvp; data = (nvs_data_t *)nvl->nv_data; nvp = &data->nvl_pair; /* first pair in nvlist */ while (nvp->encoded_size != 0 && nvp->decoded_size != 0) { nvpair_print(nvp, indent); nvp = (nvp_header_t *)((uint8_t *)nvp + nvp->encoded_size); } printf("%*s\n", indent + 13, "End of nvlist"); } /* * Copyright (c) 2007 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include /* * Stand-alone file reading package. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "libzfs.h" #include "zfsimpl.c" /* Define the range of indexes to be populated with ZFS Boot Environments */ #define ZFS_BE_FIRST 4 #define ZFS_BE_LAST 8 static int zfs_open(const char *, struct open_file *); static int zfs_close(struct open_file *); static int zfs_read(struct open_file *, void *, size_t, size_t *); static off_t zfs_seek(struct open_file *, off_t, int); static int zfs_stat(struct open_file *, struct stat *); static int zfs_readdir(struct open_file *, struct dirent *); struct devsw zfs_dev; struct fs_ops zfs_fsops = { "zfs", zfs_open, zfs_close, zfs_read, null_write, zfs_seek, zfs_stat, zfs_readdir }; /* * In-core open file. */ struct file { off_t f_seekp; /* seek pointer */ dnode_phys_t f_dnode; uint64_t f_zap_type; /* zap type for readdir */ uint64_t f_num_leafs; /* number of fzap leaf blocks */ zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */ }; SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head); struct zfs_be_list *zfs_be_headp; struct zfs_be_entry { const char *name; SLIST_ENTRY(zfs_be_entry) entries; } *zfs_be, *zfs_be_tmp; /* * Open a file. */ static int zfs_open(const char *upath, struct open_file *f) { struct zfsmount *mount = (struct zfsmount *)f->f_devdata; struct file *fp; int rc; if (f->f_dev != &zfs_dev) return (EINVAL); /* allocate file system specific data structure */ fp = calloc(1, sizeof (struct file)); if (fp == NULL) return (ENOMEM); f->f_fsdata = fp; rc = zfs_lookup(mount, upath, &fp->f_dnode); fp->f_seekp = 0; if (rc) { f->f_fsdata = NULL; free(fp); } return (rc); } static int zfs_close(struct open_file *f) { struct file *fp = (struct file *)f->f_fsdata; dnode_cache_obj = NULL; f->f_fsdata = NULL; free(fp); return (0); } /* * Copy a portion of a file into kernel memory. * Cross block boundaries when necessary. */ static int zfs_read(struct open_file *f, void *start, size_t size, size_t *resid) { const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; struct stat sb; size_t n; int rc; rc = zfs_stat(f, &sb); if (rc) return (rc); n = size; if (fp->f_seekp + n > sb.st_size) n = sb.st_size - fp->f_seekp; rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n); if (rc) return (rc); fp->f_seekp += n; if (resid) *resid = size - n; return (0); } static off_t zfs_seek(struct open_file *f, off_t offset, int where) { struct file *fp = (struct file *)f->f_fsdata; struct stat sb; int error; switch (where) { case SEEK_SET: fp->f_seekp = offset; break; case SEEK_CUR: fp->f_seekp += offset; break; case SEEK_END: error = zfs_stat(f, &sb); if (error != 0) { errno = error; return (-1); } fp->f_seekp = sb.st_size - offset; break; default: errno = EINVAL; return (-1); } return (fp->f_seekp); } static int zfs_stat(struct open_file *f, struct stat *sb) { const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; return (zfs_dnode_stat(spa, &fp->f_dnode, sb)); } static int zfs_readdir(struct open_file *f, struct dirent *d) { const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa; struct file *fp = (struct file *)f->f_fsdata; mzap_ent_phys_t mze; struct stat sb; size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT; int rc; rc = zfs_stat(f, &sb); if (rc) return (rc); if (!S_ISDIR(sb.st_mode)) return (ENOTDIR); /* * If this is the first read, get the zap type. */ if (fp->f_seekp == 0) { rc = dnode_read(spa, &fp->f_dnode, 0, &fp->f_zap_type, sizeof (fp->f_zap_type)); if (rc) return (rc); if (fp->f_zap_type == ZBT_MICRO) { fp->f_seekp = offsetof(mzap_phys_t, mz_chunk); } else { rc = dnode_read(spa, &fp->f_dnode, offsetof(zap_phys_t, zap_num_leafs), &fp->f_num_leafs, sizeof (fp->f_num_leafs)); if (rc) return (rc); fp->f_seekp = bsize; fp->f_zap_leaf = malloc(bsize); if (fp->f_zap_leaf == NULL) return (ENOMEM); rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, fp->f_zap_leaf, bsize); if (rc) return (rc); } } if (fp->f_zap_type == ZBT_MICRO) { mzap_next: if (fp->f_seekp >= bsize) return (ENOENT); rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, &mze, sizeof (mze)); if (rc) return (rc); fp->f_seekp += sizeof (mze); if (!mze.mze_name[0]) goto mzap_next; d->d_fileno = ZFS_DIRENT_OBJ(mze.mze_value); d->d_type = ZFS_DIRENT_TYPE(mze.mze_value); strcpy(d->d_name, mze.mze_name); d->d_namlen = strlen(d->d_name); return (0); } else { zap_leaf_t zl; zap_leaf_chunk_t *zc, *nc; int chunk; size_t namelen; char *p; uint64_t value; /* * Initialise this so we can use the ZAP size * calculating macros. */ zl.l_bs = ilog2(bsize); zl.l_phys = fp->f_zap_leaf; /* * Figure out which chunk we are currently looking at * and consider seeking to the next leaf. We use the * low bits of f_seekp as a simple chunk index. */ fzap_next: chunk = fp->f_seekp & (bsize - 1); if (chunk == ZAP_LEAF_NUMCHUNKS(&zl)) { fp->f_seekp = (fp->f_seekp & ~(bsize - 1)) + bsize; chunk = 0; /* * Check for EOF and read the new leaf. */ if (fp->f_seekp >= bsize * fp->f_num_leafs) return (ENOENT); rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, fp->f_zap_leaf, bsize); if (rc) return (rc); } zc = &ZAP_LEAF_CHUNK(&zl, chunk); fp->f_seekp++; if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY) goto fzap_next; namelen = zc->l_entry.le_name_numints; if (namelen > sizeof (d->d_name)) namelen = sizeof (d->d_name); /* * Paste the name back together. */ nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk); p = d->d_name; while (namelen > 0) { int len; len = namelen; if (len > ZAP_LEAF_ARRAY_BYTES) len = ZAP_LEAF_ARRAY_BYTES; memcpy(p, nc->l_array.la_array, len); p += len; namelen -= len; nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next); } d->d_name[sizeof (d->d_name) - 1] = 0; /* * Assume the first eight bytes of the value are * a uint64_t. */ value = fzap_leaf_value(&zl, zc); d->d_fileno = ZFS_DIRENT_OBJ(value); d->d_type = ZFS_DIRENT_TYPE(value); d->d_namlen = strlen(d->d_name); return (0); } } static int vdev_read(vdev_t *vdev __unused, void *priv, off_t offset, void *buf, size_t bytes) { int fd, ret; size_t res, head, tail, total_size, full_sec_size; unsigned secsz, do_tail_read; off_t start_sec; char *outbuf, *bouncebuf; fd = (uintptr_t)priv; outbuf = (char *)buf; bouncebuf = NULL; ret = ioctl(fd, DIOCGSECTORSIZE, &secsz); if (ret != 0) return (ret); /* BEGIN CSTYLED */ /* * Handling reads of arbitrary offset and size - multi-sector case * and single-sector case. * * Multi-sector Case * (do_tail_read = true if tail > 0) * * |<----------------------total_size--------------------->| * | | * |<--head-->|<--------------bytes------------>|<--tail-->| * | | | | * | | |<~full_sec_size~>| | | * +------------------+ +------------------+ * | |0101010| . . . |0101011| | * +------------------+ +------------------+ * start_sec start_sec + n * * * Single-sector Case * (do_tail_read = false) * * |<------total_size = secsz----->| * | | * |<-head->|<---bytes--->|<-tail->| * +-------------------------------+ * | |0101010101010| | * +-------------------------------+ * start_sec */ /* END CSTYLED */ start_sec = offset / secsz; head = offset % secsz; total_size = roundup2(head + bytes, secsz); tail = total_size - (head + bytes); do_tail_read = ((tail > 0) && (head + bytes > secsz)); full_sec_size = total_size; if (head > 0) full_sec_size -= secsz; if (do_tail_read) full_sec_size -= secsz; /* Return of partial sector data requires a bounce buffer. */ if ((head > 0) || do_tail_read || bytes < secsz) { bouncebuf = malloc(secsz); if (bouncebuf == NULL) { printf("vdev_read: out of memory\n"); return (ENOMEM); } } if (lseek(fd, start_sec * secsz, SEEK_SET) == -1) { ret = errno; goto error; } /* Partial data return from first sector */ if (head > 0) { res = read(fd, bouncebuf, secsz); if (res != secsz) { ret = EIO; goto error; } memcpy(outbuf, bouncebuf + head, min(secsz - head, bytes)); outbuf += min(secsz - head, bytes); } /* Full data return from read sectors */ if (full_sec_size > 0) { if (bytes < full_sec_size) { res = read(fd, bouncebuf, secsz); if (res != secsz) { ret = EIO; goto error; } memcpy(outbuf, bouncebuf, bytes); } else { res = read(fd, outbuf, full_sec_size); if (res != full_sec_size) { ret = EIO; goto error; } outbuf += full_sec_size; } } /* Partial data return from last sector */ if (do_tail_read) { res = read(fd, bouncebuf, secsz); if (res != secsz) { ret = EIO; goto error; } memcpy(outbuf, bouncebuf, secsz - tail); } ret = 0; error: free(bouncebuf); return (ret); } static int vdev_write(vdev_t *vdev, off_t offset, void *buf, size_t bytes) { int fd, ret; size_t head, tail, total_size, full_sec_size; unsigned secsz, do_tail_write; off_t start_sec; ssize_t res; char *outbuf, *bouncebuf; fd = (uintptr_t)vdev->v_priv; outbuf = (char *)buf; bouncebuf = NULL; ret = ioctl(fd, DIOCGSECTORSIZE, &secsz); if (ret != 0) return (ret); start_sec = offset / secsz; head = offset % secsz; total_size = roundup2(head + bytes, secsz); tail = total_size - (head + bytes); do_tail_write = ((tail > 0) && (head + bytes > secsz)); full_sec_size = total_size; if (head > 0) full_sec_size -= secsz; if (do_tail_write) full_sec_size -= secsz; /* Partial sector write requires a bounce buffer. */ if ((head > 0) || do_tail_write || bytes < secsz) { bouncebuf = malloc(secsz); if (bouncebuf == NULL) { printf("vdev_write: out of memory\n"); return (ENOMEM); } } if (lseek(fd, start_sec * secsz, SEEK_SET) == -1) { ret = errno; goto error; } /* Partial data for first sector */ if (head > 0) { res = read(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } memcpy(bouncebuf + head, outbuf, min(secsz - head, bytes)); (void) lseek(fd, -secsz, SEEK_CUR); res = write(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } outbuf += min(secsz - head, bytes); } /* * Full data write to sectors. * Note, there is still corner case where we write * to sector boundary, but less than sector size, e.g. write 512B * to 4k sector. */ if (full_sec_size > 0) { if (bytes < full_sec_size) { res = read(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } memcpy(bouncebuf, outbuf, bytes); (void) lseek(fd, -secsz, SEEK_CUR); res = write(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } } else { res = write(fd, outbuf, full_sec_size); if ((unsigned)res != full_sec_size) { ret = EIO; goto error; } outbuf += full_sec_size; } } /* Partial data write to last sector */ if (do_tail_write) { res = read(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } memcpy(bouncebuf, outbuf, secsz - tail); (void) lseek(fd, -secsz, SEEK_CUR); res = write(fd, bouncebuf, secsz); if ((unsigned)res != secsz) { ret = EIO; goto error; } } ret = 0; error: free(bouncebuf); return (ret); } static int zfs_dev_init(void) { spa_t *spa; spa_t *next; spa_t *prev; zfs_init(); if (archsw.arch_zfs_probe == NULL) return (ENXIO); archsw.arch_zfs_probe(); prev = NULL; spa = STAILQ_FIRST(&zfs_pools); while (spa != NULL) { next = STAILQ_NEXT(spa, spa_link); if (zfs_spa_init(spa)) { if (prev == NULL) STAILQ_REMOVE_HEAD(&zfs_pools, spa_link); else STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link); } else prev = spa; spa = next; } return (0); } struct zfs_probe_args { int fd; const char *devname; uint64_t *pool_guid; unsigned secsz; }; static int zfs_diskread(void *arg, void *buf, size_t blocks, uint64_t offset) { struct zfs_probe_args *ppa; ppa = (struct zfs_probe_args *)arg; return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd, offset * ppa->secsz, buf, blocks * ppa->secsz)); } static int zfs_probe(int fd, uint64_t *pool_guid) { spa_t *spa; int ret; spa = NULL; ret = vdev_probe(vdev_read, vdev_write, (void *)(uintptr_t)fd, &spa); if (ret == 0 && pool_guid != NULL) *pool_guid = spa->spa_guid; return (ret); } static int zfs_probe_partition(void *arg, const char *partname, const struct ptable_entry *part) { struct zfs_probe_args *ppa, pa; struct ptable *table; char devname[32]; int ret = 0; /* filter out partitions *not* used by zfs */ switch (part->type) { case PART_EFI: /* efi system partition */ case PART_RESERVED: /* efi reserverd */ case PART_VTOC_BOOT: /* vtoc boot area */ case PART_VTOC_SWAP: return (ret); default: break; } ppa = (struct zfs_probe_args *)arg; strncpy(devname, ppa->devname, strlen(ppa->devname) - 1); devname[strlen(ppa->devname) - 1] = '\0'; snprintf(devname, sizeof (devname), "%s%s:", devname, partname); pa.fd = open(devname, O_RDWR); if (pa.fd == -1) return (ret); ret = zfs_probe(pa.fd, ppa->pool_guid); if (ret == 0) return (ret); if (part->type == PART_SOLARIS2) { pa.devname = devname; pa.pool_guid = ppa->pool_guid; pa.secsz = ppa->secsz; table = ptable_open(&pa, part->end - part->start + 1, ppa->secsz, zfs_diskread); if (table != NULL) { enum ptable_type pt = ptable_gettype(table); if (pt == PTABLE_VTOC8 || pt == PTABLE_VTOC) ptable_iterate(table, &pa, zfs_probe_partition); ptable_close(table); } } close(pa.fd); return (0); } /* * Return bootenv nvlist from pool label. */ int zfs_get_bootenv(void *vdev, nvlist_t **benvp) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; nvlist_t *benv = NULL; vdev_t *vd; spa_t *spa; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) { STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, v_childlink) { benv = vdev_read_bootenv(vd); if (benv != NULL) break; } spa->spa_bootenv = benv; } else { benv = spa->spa_bootenv; } if (benv == NULL) return (ENOENT); *benvp = benv; return (0); } /* * Store nvlist to pool label bootenv area. Also updates cached pointer in spa. */ int zfs_set_bootenv(void *vdev, nvlist_t *benv) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; vdev_t *vd; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, v_childlink) { vdev_write_bootenv(vd, benv); } spa->spa_bootenv = benv; return (0); } /* * Get bootonce value by key. The bootonce pair is removed * from the bootenv nvlist and the remaining nvlist is committed back to disk. */ int zfs_get_bootonce(void *vdev, const char *key, char *buf, size_t size) { nvlist_t *benv; char *result = NULL; int result_size, rv; if ((rv = zfs_get_bootenv(vdev, &benv)) != 0) return (rv); if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL, &result, &result_size)) == 0) { if (result_size == 0) { /* ignore empty string */ rv = ENOENT; } else { size = MIN((size_t)result_size + 1, size); strlcpy(buf, result, size); } (void) nvlist_remove(benv, key, DATA_TYPE_STRING); (void) zfs_set_bootenv(vdev, benv); } return (rv); } /* * nvstore backend. */ static int zfs_nvstore_setter(void *, int, const char *, const void *, size_t); static int zfs_nvstore_setter_str(void *, const char *, const char *, const char *); static int zfs_nvstore_unset_impl(void *, const char *, bool); static int zfs_nvstore_setenv(void *, void *); /* * nvstore is only present for current rootfs pool. */ static int zfs_nvstore_sethook(struct env_var *ev, int flags __unused, const void *value) { struct zfs_devdesc *dev; int rv; archsw.arch_getdev((void **)&dev, NULL, NULL); if (dev == NULL) return (ENXIO); rv = zfs_nvstore_setter_str(dev, NULL, ev->ev_name, value); free(dev); return (rv); } /* * nvstore is only present for current rootfs pool. */ static int zfs_nvstore_unsethook(struct env_var *ev) { struct zfs_devdesc *dev; int rv; archsw.arch_getdev((void **)&dev, NULL, NULL); if (dev == NULL) return (ENXIO); rv = zfs_nvstore_unset_impl(dev, ev->ev_name, false); free(dev); return (rv); } static int zfs_nvstore_getter(void *vdev, const char *name, void **data) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; nvlist_t *nv; char *str, **ptr; int size; int rv; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) return (ENXIO); if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST, NULL, &nv, NULL) != 0) return (ENOENT); rv = nvlist_find(nv, name, DATA_TYPE_STRING, NULL, &str, &size); if (rv == 0) { ptr = (char **)data; asprintf(ptr, "%.*s", size, str); if (*data == NULL) rv = ENOMEM; } nvlist_destroy(nv); return (rv); } static int zfs_nvstore_setter(void *vdev, int type, const char *name, const void *data, size_t size) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; nvlist_t *nv; int rv; bool env_set = true; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) return (ENXIO); if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST, NULL, &nv, NULL) != 0) { nv = nvlist_create(NV_UNIQUE_NAME); if (nv == NULL) return (ENOMEM); } rv = 0; switch (type) { case DATA_TYPE_INT8: if (size != sizeof (int8_t)) { rv = EINVAL; break; } rv = nvlist_add_int8(nv, name, *(int8_t *)data); break; case DATA_TYPE_INT16: if (size != sizeof (int16_t)) { rv = EINVAL; break; } rv = nvlist_add_int16(nv, name, *(int16_t *)data); break; case DATA_TYPE_INT32: if (size != sizeof (int32_t)) { rv = EINVAL; break; } rv = nvlist_add_int32(nv, name, *(int32_t *)data); break; case DATA_TYPE_INT64: if (size != sizeof (int64_t)) { rv = EINVAL; break; } rv = nvlist_add_int64(nv, name, *(int64_t *)data); break; case DATA_TYPE_BYTE: if (size != sizeof (uint8_t)) { rv = EINVAL; break; } rv = nvlist_add_byte(nv, name, *(int8_t *)data); break; case DATA_TYPE_UINT8: if (size != sizeof (uint8_t)) { rv = EINVAL; break; } rv = nvlist_add_uint8(nv, name, *(int8_t *)data); break; case DATA_TYPE_UINT16: if (size != sizeof (uint16_t)) { rv = EINVAL; break; } rv = nvlist_add_uint16(nv, name, *(uint16_t *)data); break; case DATA_TYPE_UINT32: if (size != sizeof (uint32_t)) { rv = EINVAL; break; } rv = nvlist_add_uint32(nv, name, *(uint32_t *)data); break; case DATA_TYPE_UINT64: if (size != sizeof (uint64_t)) { rv = EINVAL; break; } rv = nvlist_add_uint64(nv, name, *(uint64_t *)data); break; case DATA_TYPE_STRING: rv = nvlist_add_string(nv, name, data); break; case DATA_TYPE_BOOLEAN_VALUE: if (size != sizeof (boolean_t)) { rv = EINVAL; break; } rv = nvlist_add_boolean_value(nv, name, *(boolean_t *)data); break; default: rv = EINVAL; break; } if (rv == 0) { rv = nvlist_add_nvlist(spa->spa_bootenv, OS_NVSTORE, nv); if (rv == 0) { rv = zfs_set_bootenv(vdev, spa->spa_bootenv); } if (rv == 0) { if (env_set) { rv = zfs_nvstore_setenv(vdev, nvpair_find(nv, name)); } else { env_discard(env_getenv(name)); rv = 0; } } } nvlist_destroy(nv); return (rv); } static int get_int64(const char *data, int64_t *ip) { char *end; int64_t val; errno = 0; val = strtoll(data, &end, 0); if (errno != 0 || *data == '\0' || *end != '\0') return (EINVAL); *ip = val; return (0); } static int get_uint64(const char *data, uint64_t *ip) { char *end; uint64_t val; errno = 0; val = strtoull(data, &end, 0); if (errno != 0 || *data == '\0' || *end != '\0') return (EINVAL); *ip = val; return (0); } /* * Translate textual data to data type. If type is not set, and we are * creating new pair, use DATA_TYPE_STRING. */ static int zfs_nvstore_setter_str(void *vdev, const char *type, const char *name, const char *data) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; nvlist_t *nv; int rv; data_type_t dt; int64_t val; uint64_t uval; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) return (ENXIO); if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST, NULL, &nv, NULL) != 0) { nv = NULL; } if (type == NULL) { nvp_header_t *nvh; /* * if there is no existing pair, default to string. * Otherwise, use type from existing pair. */ nvh = nvpair_find(nv, name); if (nvh == NULL) { dt = DATA_TYPE_STRING; } else { nv_string_t *nvp_name; nv_pair_data_t *nvp_data; nvp_name = (nv_string_t *)(nvh + 1); nvp_data = (nv_pair_data_t *)(&nvp_name->nv_data[0] + NV_ALIGN4(nvp_name->nv_size)); dt = nvp_data->nv_type; } } else { dt = nvpair_type_from_name(type); } nvlist_destroy(nv); rv = 0; switch (dt) { case DATA_TYPE_INT8: rv = get_int64(data, &val); if (rv == 0) { int8_t v = val; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_INT16: rv = get_int64(data, &val); if (rv == 0) { int16_t v = val; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_INT32: rv = get_int64(data, &val); if (rv == 0) { int32_t v = val; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_INT64: rv = get_int64(data, &val); if (rv == 0) { rv = zfs_nvstore_setter(vdev, dt, name, &val, sizeof (val)); } break; case DATA_TYPE_BYTE: rv = get_uint64(data, &uval); if (rv == 0) { uint8_t v = uval; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_UINT8: rv = get_uint64(data, &uval); if (rv == 0) { uint8_t v = uval; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_UINT16: rv = get_uint64(data, &uval); if (rv == 0) { uint16_t v = uval; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_UINT32: rv = get_uint64(data, &uval); if (rv == 0) { uint32_t v = uval; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; case DATA_TYPE_UINT64: rv = get_uint64(data, &uval); if (rv == 0) { rv = zfs_nvstore_setter(vdev, dt, name, &uval, sizeof (uval)); } break; case DATA_TYPE_STRING: rv = zfs_nvstore_setter(vdev, dt, name, data, strlen(data) + 1); break; case DATA_TYPE_BOOLEAN_VALUE: rv = get_int64(data, &val); if (rv == 0) { boolean_t v = val; rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v)); } break; default: rv = EINVAL; } return (rv); } static int zfs_nvstore_unset_impl(void *vdev, const char *name, bool unset_env) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; nvlist_t *nv; int rv; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) return (ENXIO); if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST, NULL, &nv, NULL) != 0) return (ENOENT); rv = nvlist_remove(nv, name, DATA_TYPE_UNKNOWN); if (rv == 0) { if (nvlist_next_nvpair(nv, NULL) == NULL) { rv = nvlist_remove(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST); } else { rv = nvlist_add_nvlist(spa->spa_bootenv, OS_NVSTORE, nv); } if (rv == 0) rv = zfs_set_bootenv(vdev, spa->spa_bootenv); } if (unset_env) { struct env_var *ev = env_getenv(name); if (ev != NULL) env_discard(ev); } return (rv); } static int zfs_nvstore_unset(void *vdev, const char *name) { return (zfs_nvstore_unset_impl(vdev, name, true)); } static int zfs_nvstore_print(void *vdev __unused, void *ptr) { nvpair_print(ptr, 0); return (0); } /* * Create environment variable from nvpair. * set hook will update nvstore with new value, unset hook will remove * variable from nvstore. */ static int zfs_nvstore_setenv(void *vdev __unused, void *ptr) { nvp_header_t *nvh = ptr; nv_string_t *nvp_name, *nvp_value; nv_pair_data_t *nvp_data; char *name, *value; int rv = 0; if (nvh == NULL) return (ENOENT); nvp_name = (nv_string_t *)(nvh + 1); nvp_data = (nv_pair_data_t *)(&nvp_name->nv_data[0] + NV_ALIGN4(nvp_name->nv_size)); if ((name = nvstring_get(nvp_name)) == NULL) return (ENOMEM); value = NULL; switch (nvp_data->nv_type) { case DATA_TYPE_BYTE: case DATA_TYPE_UINT8: (void) asprintf(&value, "%uc", *(unsigned *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_INT8: (void) asprintf(&value, "%c", *(int *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_INT16: (void) asprintf(&value, "%hd", *(short *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_UINT16: (void) asprintf(&value, "%hu", *(unsigned short *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_BOOLEAN_VALUE: case DATA_TYPE_INT32: (void) asprintf(&value, "%d", *(int *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_UINT32: (void) asprintf(&value, "%u", *(unsigned *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_INT64: (void) asprintf(&value, "%jd", (intmax_t)*(int64_t *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_UINT64: (void) asprintf(&value, "%ju", (uintmax_t)*(uint64_t *)&nvp_data->nv_data[0]); if (value == NULL) rv = ENOMEM; break; case DATA_TYPE_STRING: nvp_value = (nv_string_t *)&nvp_data->nv_data[0]; if ((value = nvstring_get(nvp_value)) == NULL) { rv = ENOMEM; break; } break; default: rv = EINVAL; break; } if (value != NULL) { rv = env_setenv(name, EV_VOLATILE | EV_NOHOOK, value, zfs_nvstore_sethook, zfs_nvstore_unsethook); free(value); } free(name); return (rv); } static int zfs_nvstore_iterate(void *vdev, int (*cb)(void *, void *)) { struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; nvlist_t *nv; nvp_header_t *nvh; int rv; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); if (spa->spa_bootenv == NULL) return (ENXIO); if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST, NULL, &nv, NULL) != 0) return (ENOENT); rv = 0; nvh = NULL; while ((nvh = nvlist_next_nvpair(nv, nvh)) != NULL) { rv = cb(vdev, nvh); if (rv != 0) break; } return (rv); } nvs_callbacks_t nvstore_zfs_cb = { .nvs_getter = zfs_nvstore_getter, .nvs_setter = zfs_nvstore_setter, .nvs_setter_str = zfs_nvstore_setter_str, .nvs_unset = zfs_nvstore_unset, .nvs_print = zfs_nvstore_print, .nvs_iterate = zfs_nvstore_iterate }; int zfs_attach_nvstore(void *vdev) { struct zfs_devdesc *dev = vdev; spa_t *spa; uint64_t version; int rv; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (ENOTSUP); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); rv = nvlist_find(spa->spa_bootenv, BOOTENV_VERSION, DATA_TYPE_UINT64, NULL, &version, NULL); if (rv != 0 || version != VB_NVLIST) { return (ENXIO); } dev = malloc(sizeof (*dev)); if (dev == NULL) return (ENOMEM); memcpy(dev, vdev, sizeof (*dev)); rv = nvstore_init(spa->spa_name, &nvstore_zfs_cb, dev); if (rv != 0) free(dev); else rv = zfs_nvstore_iterate(dev, zfs_nvstore_setenv); return (rv); } int zfs_probe_dev(const char *devname, uint64_t *pool_guid) { struct disk_devdesc *dev; struct ptable *table; struct zfs_probe_args pa; uint64_t mediasz; int ret; if (pool_guid) *pool_guid = 0; pa.fd = open(devname, O_RDWR); if (pa.fd == -1) return (ENXIO); /* * We will not probe the whole disk, we can not boot from such * disks and some systems will misreport the disk sizes and will * hang while accessing the disk. */ if (archsw.arch_getdev((void **)&dev, devname, NULL) == 0) { int partition = dev->d_partition; int slice = dev->d_slice; free(dev); if (partition != D_PARTNONE && slice != D_SLICENONE) { ret = zfs_probe(pa.fd, pool_guid); if (ret == 0) return (0); } } /* Probe each partition */ ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz); if (ret == 0) ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz); if (ret == 0) { pa.devname = devname; pa.pool_guid = pool_guid; table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz, zfs_diskread); if (table != NULL) { ptable_iterate(table, &pa, zfs_probe_partition); ptable_close(table); } } close(pa.fd); if (pool_guid && *pool_guid == 0) ret = ENXIO; return (ret); } /* * Print information about ZFS pools */ static int zfs_dev_print(int verbose) { spa_t *spa; char line[80]; int ret = 0; if (STAILQ_EMPTY(&zfs_pools)) return (0); printf("%s devices:", zfs_dev.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); if (verbose) { return (spa_all_status()); } STAILQ_FOREACH(spa, &zfs_pools, spa_link) { snprintf(line, sizeof (line), " zfs:%s\n", spa->spa_name); ret = pager_output(line); if (ret != 0) break; } return (ret); } /* * Attempt to open the pool described by (dev) for use by (f). */ static int zfs_dev_open(struct open_file *f, ...) { va_list args; struct zfs_devdesc *dev; struct zfsmount *mount; spa_t *spa; int rv; va_start(args, f); dev = va_arg(args, struct zfs_devdesc *); va_end(args); if ((spa = spa_find_by_dev(dev)) == NULL) return (ENXIO); mount = malloc(sizeof (*mount)); if (mount == NULL) rv = ENOMEM; else rv = zfs_mount(spa, dev->root_guid, mount); if (rv != 0) { free(mount); return (rv); } if (mount->objset.os_type != DMU_OST_ZFS) { printf("Unexpected object set type %ju\n", (uintmax_t)mount->objset.os_type); free(mount); return (EIO); } f->f_devdata = mount; free(dev); return (0); } static int zfs_dev_close(struct open_file *f) { free(f->f_devdata); f->f_devdata = NULL; return (0); } static int zfs_dev_strategy(void *devdata __unused, int rw __unused, daddr_t dblk __unused, size_t size __unused, char *buf __unused, size_t *rsize __unused) { return (ENOSYS); } struct devsw zfs_dev = { .dv_name = "zfs", .dv_type = DEVT_ZFS, .dv_init = zfs_dev_init, .dv_strategy = zfs_dev_strategy, .dv_open = zfs_dev_open, .dv_close = zfs_dev_close, .dv_ioctl = noioctl, .dv_print = zfs_dev_print, .dv_cleanup = NULL }; int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path) { static char rootname[ZFS_MAXNAMELEN]; static char poolname[ZFS_MAXNAMELEN]; spa_t *spa; const char *end; const char *np; const char *sep; int rv; np = devspec; if (*np != ':') return (EINVAL); np++; end = strrchr(np, ':'); if (end == NULL) return (EINVAL); sep = strchr(np, '/'); if (sep == NULL || sep >= end) sep = end; memcpy(poolname, np, sep - np); poolname[sep - np] = '\0'; if (sep < end) { sep++; memcpy(rootname, sep, end - sep); rootname[end - sep] = '\0'; } else rootname[0] = '\0'; spa = spa_find_by_name(poolname); if (!spa) return (ENXIO); dev->pool_guid = spa->spa_guid; rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid); if (rv != 0) return (rv); if (path != NULL) *path = (*end == '\0') ? end : end + 1; dev->dd.d_dev = &zfs_dev; return (0); } char * zfs_bootfs(void *zdev) { static char rootname[ZFS_MAXNAMELEN]; static char buf[2 * ZFS_MAXNAMELEN]; struct zfs_devdesc *dev = (struct zfs_devdesc *)zdev; uint64_t objnum; spa_t *spa; int n; buf[0] = '\0'; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (buf); spa = spa_find_by_guid(dev->pool_guid); if (spa == NULL) { printf("ZFS: can't find pool by guid\n"); return (buf); } if (zfs_rlookup(spa, dev->root_guid, rootname)) { printf("ZFS: can't find filesystem by guid\n"); return (buf); } if (zfs_lookup_dataset(spa, rootname, &objnum)) { printf("ZFS: can't find filesystem by name\n"); return (buf); } /* Set the environment. */ snprintf(buf, sizeof (buf), "%" PRIu64, dev->pool_guid); setenv("zfs-bootpool", buf, 1); snprintf(buf, sizeof (buf), "%" PRIu64, spa->spa_boot_vdev->v_guid); setenv("zfs-bootvdev", buf, 1); snprintf(buf, sizeof (buf), "%s/%" PRIu64, spa->spa_name, objnum); setenv("zfs-bootfs", buf, 1); if (spa->spa_boot_vdev->v_phys_path != NULL) setenv("bootpath", spa->spa_boot_vdev->v_phys_path, 1); if (spa->spa_boot_vdev->v_devid != NULL) setenv("diskdevid", spa->spa_boot_vdev->v_devid, 1); /* * Build the command line string. Once our kernel will read * the environment and we can stop caring about old kernels, * we can remove this part. */ snprintf(buf, sizeof (buf), "zfs-bootfs=%s/%" PRIu64, spa->spa_name, objnum); n = strlen(buf); if (spa->spa_boot_vdev->v_phys_path != NULL) { snprintf(buf+n, sizeof (buf) - n, ",bootpath=\"%s\"", spa->spa_boot_vdev->v_phys_path); n = strlen(buf); } if (spa->spa_boot_vdev->v_devid != NULL) { snprintf(buf+n, sizeof (buf) - n, ",diskdevid=\"%s\"", spa->spa_boot_vdev->v_devid); } return (buf); } char * zfs_fmtdev(void *vdev) { static char rootname[ZFS_MAXNAMELEN]; static char buf[2 * ZFS_MAXNAMELEN + 8]; struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev; spa_t *spa; buf[0] = '\0'; if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (buf); /* Do we have any pools? */ spa = STAILQ_FIRST(&zfs_pools); if (spa == NULL) return (buf); if (dev->pool_guid == 0) dev->pool_guid = spa->spa_guid; else spa = spa_find_by_guid(dev->pool_guid); if (spa == NULL) { printf("ZFS: can't find pool by guid\n"); return (buf); } if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) { printf("ZFS: can't find root filesystem\n"); return (buf); } if (zfs_rlookup(spa, dev->root_guid, rootname)) { printf("ZFS: can't find filesystem by guid\n"); return (buf); } if (rootname[0] == '\0') snprintf(buf, sizeof (buf), "%s:%s:", dev->dd.d_dev->dv_name, spa->spa_name); else snprintf(buf, sizeof (buf), "%s:%s/%s:", dev->dd.d_dev->dv_name, spa->spa_name, rootname); return (buf); } int zfs_list(const char *name) { static char poolname[ZFS_MAXNAMELEN]; uint64_t objid; spa_t *spa; const char *dsname; int len; int rv; len = strlen(name); dsname = strchr(name, '/'); if (dsname != NULL) { len = dsname - name; dsname++; } else dsname = ""; memcpy(poolname, name, len); poolname[len] = '\0'; spa = spa_find_by_name(poolname); if (!spa) return (ENXIO); rv = zfs_lookup_dataset(spa, dsname, &objid); if (rv != 0) return (rv); return (zfs_list_dataset(spa, objid)); } /* * Copyright (c) 2007 Doug Rabson * All rights reserved. * * 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. * * 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. */ #include /* * Stand-alone ZFS file reader. */ #include #include #include #include #include #include #include #include "zfsimpl.h" #include "zfssubr.c" struct zfsmount { const spa_t *spa; objset_phys_t objset; uint64_t rootobj; }; /* * The indirect_child_t represents the vdev that we will read from, when we * need to read all copies of the data (e.g. for scrub or reconstruction). * For plain (non-mirror) top-level vdevs (i.e. is_vdev is not a mirror), * ic_vdev is the same as is_vdev. However, for mirror top-level vdevs, * ic_vdev is a child of the mirror. */ typedef struct indirect_child { void *ic_data; vdev_t *ic_vdev; } indirect_child_t; /* * The indirect_split_t represents one mapped segment of an i/o to the * indirect vdev. For non-split (contiguously-mapped) blocks, there will be * only one indirect_split_t, with is_split_offset==0 and is_size==io_size. * For split blocks, there will be several of these. */ typedef struct indirect_split { list_node_t is_node; /* link on iv_splits */ /* * is_split_offset is the offset into the i/o. * This is the sum of the previous splits' is_size's. */ uint64_t is_split_offset; vdev_t *is_vdev; /* top-level vdev */ uint64_t is_target_offset; /* offset on is_vdev */ uint64_t is_size; int is_children; /* number of entries in is_child[] */ /* * is_good_child is the child that we are currently using to * attempt reconstruction. */ int is_good_child; indirect_child_t is_child[1]; /* variable-length */ } indirect_split_t; /* * The indirect_vsd_t is associated with each i/o to the indirect vdev. * It is the "Vdev-Specific Data" in the zio_t's io_vsd. */ typedef struct indirect_vsd { boolean_t iv_split_block; boolean_t iv_reconstruct; list_t iv_splits; /* list of indirect_split_t's */ } indirect_vsd_t; /* * List of all vdevs, chained through v_alllink. */ static vdev_list_t zfs_vdevs; /* * List of ZFS features supported for read */ static const char *features_for_read[] = { "org.illumos:lz4_compress", "com.delphix:hole_birth", "com.delphix:extensible_dataset", "com.delphix:embedded_data", "org.open-zfs:large_blocks", "org.illumos:sha512", "org.illumos:skein", "org.illumos:edonr", "org.zfsonlinux:large_dnode", "com.joyent:multi_vdev_crash_dump", "com.delphix:spacemap_histogram", "com.delphix:zpool_checkpoint", "com.delphix:spacemap_v2", "com.datto:encryption", "com.datto:bookmark_v2", "org.zfsonlinux:allocation_classes", "com.datto:resilver_defer", "com.delphix:device_removal", "com.delphix:obsolete_counts", NULL }; /* * List of all pools, chained through spa_link. */ static spa_list_t zfs_pools; static const dnode_phys_t *dnode_cache_obj; static uint64_t dnode_cache_bn; static char *dnode_cache_buf; static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf); static int zfs_get_root(const spa_t *spa, uint64_t *objid); static int zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result); static int zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t integer_size, uint64_t num_integers, void *value); static int objset_get_dnode(const spa_t *, const objset_phys_t *, uint64_t, dnode_phys_t *); static int dnode_read(const spa_t *, const dnode_phys_t *, off_t, void *, size_t); static int vdev_indirect_read(vdev_t *, const blkptr_t *, void *, off_t, size_t); static int vdev_mirror_read(vdev_t *, const blkptr_t *, void *, off_t, size_t); static void zfs_init(void) { STAILQ_INIT(&zfs_vdevs); STAILQ_INIT(&zfs_pools); dnode_cache_buf = malloc(SPA_MAXBLOCKSIZE); zfs_init_crc(); } static int nvlist_check_features_for_read(nvlist_t *nvl) { nvlist_t *features = NULL; nvs_data_t *data; nvp_header_t *nvp; nv_string_t *nvp_name; int rc; /* * We may have all features disabled. */ rc = nvlist_find(nvl, ZPOOL_CONFIG_FEATURES_FOR_READ, DATA_TYPE_NVLIST, NULL, &features, NULL); switch (rc) { case 0: break; /* Continue with checks */ case ENOENT: return (0); /* All features are disabled */ default: return (rc); /* Error while reading nvlist */ } data = (nvs_data_t *)features->nv_data; nvp = &data->nvl_pair; /* first pair in nvlist */ while (nvp->encoded_size != 0 && nvp->decoded_size != 0) { int i, found; nvp_name = (nv_string_t *)((uintptr_t)nvp + sizeof (*nvp)); found = 0; for (i = 0; features_for_read[i] != NULL; i++) { if (memcmp(nvp_name->nv_data, features_for_read[i], nvp_name->nv_size) == 0) { found = 1; break; } } if (!found) { printf("ZFS: unsupported feature: %.*s\n", nvp_name->nv_size, nvp_name->nv_data); rc = EIO; } nvp = (nvp_header_t *)((uint8_t *)nvp + nvp->encoded_size); } nvlist_destroy(features); return (rc); } static int vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset, size_t size) { size_t psize; int rc; if (vdev->v_phys_read == NULL) return (ENOTSUP); if (bp) { psize = BP_GET_PSIZE(bp); } else { psize = size; } rc = vdev->v_phys_read(vdev, vdev->v_priv, offset, buf, psize); if (rc == 0) { if (bp != NULL) rc = zio_checksum_verify(vdev->v_spa, bp, buf); } return (rc); } static int vdev_write_phys(vdev_t *vdev, void *buf, off_t offset, size_t size) { if (vdev->v_phys_write == NULL) return (ENOTSUP); return (vdev->v_phys_write(vdev, offset, buf, size)); } typedef struct remap_segment { vdev_t *rs_vd; uint64_t rs_offset; uint64_t rs_asize; uint64_t rs_split_offset; list_node_t rs_node; } remap_segment_t; static remap_segment_t * rs_alloc(vdev_t *vd, uint64_t offset, uint64_t asize, uint64_t split_offset) { remap_segment_t *rs = malloc(sizeof (remap_segment_t)); if (rs != NULL) { rs->rs_vd = vd; rs->rs_offset = offset; rs->rs_asize = asize; rs->rs_split_offset = split_offset; } return (rs); } vdev_indirect_mapping_t * vdev_indirect_mapping_open(spa_t *spa, objset_phys_t *os, uint64_t mapping_object) { vdev_indirect_mapping_t *vim; vdev_indirect_mapping_phys_t *vim_phys; int rc; vim = calloc(1, sizeof (*vim)); if (vim == NULL) return (NULL); vim->vim_dn = calloc(1, sizeof (*vim->vim_dn)); if (vim->vim_dn == NULL) { free(vim); return (NULL); } rc = objset_get_dnode(spa, os, mapping_object, vim->vim_dn); if (rc != 0) { free(vim->vim_dn); free(vim); return (NULL); } vim->vim_spa = spa; vim->vim_phys = malloc(sizeof (*vim->vim_phys)); if (vim->vim_phys == NULL) { free(vim->vim_dn); free(vim); return (NULL); } vim_phys = (vdev_indirect_mapping_phys_t *)DN_BONUS(vim->vim_dn); *vim->vim_phys = *vim_phys; vim->vim_objset = os; vim->vim_object = mapping_object; vim->vim_entries = NULL; vim->vim_havecounts = (vim->vim_dn->dn_bonuslen > VDEV_INDIRECT_MAPPING_SIZE_V0); return (vim); } /* * Compare an offset with an indirect mapping entry; there are three * possible scenarios: * * 1. The offset is "less than" the mapping entry; meaning the * offset is less than the source offset of the mapping entry. In * this case, there is no overlap between the offset and the * mapping entry and -1 will be returned. * * 2. The offset is "greater than" the mapping entry; meaning the * offset is greater than the mapping entry's source offset plus * the entry's size. In this case, there is no overlap between * the offset and the mapping entry and 1 will be returned. * * NOTE: If the offset is actually equal to the entry's offset * plus size, this is considered to be "greater" than the entry, * and this case applies (i.e. 1 will be returned). Thus, the * entry's "range" can be considered to be inclusive at its * start, but exclusive at its end: e.g. [src, src + size). * * 3. The last case to consider is if the offset actually falls * within the mapping entry's range. If this is the case, the * offset is considered to be "equal to" the mapping entry and * 0 will be returned. * * NOTE: If the offset is equal to the entry's source offset, * this case applies and 0 will be returned. If the offset is * equal to the entry's source plus its size, this case does * *not* apply (see "NOTE" above for scenario 2), and 1 will be * returned. */ static int dva_mapping_overlap_compare(const void *v_key, const void *v_array_elem) { const uint64_t *key = v_key; const vdev_indirect_mapping_entry_phys_t *array_elem = v_array_elem; uint64_t src_offset = DVA_MAPPING_GET_SRC_OFFSET(array_elem); if (*key < src_offset) { return (-1); } else if (*key < src_offset + DVA_GET_ASIZE(&array_elem->vimep_dst)) { return (0); } else { return (1); } } /* * Return array entry. */ static vdev_indirect_mapping_entry_phys_t * vdev_indirect_mapping_entry(vdev_indirect_mapping_t *vim, uint64_t index) { uint64_t size; off_t offset = 0; int rc; if (vim->vim_phys->vimp_num_entries == 0) return (NULL); if (vim->vim_entries == NULL) { uint64_t bsize; bsize = vim->vim_dn->dn_datablkszsec << SPA_MINBLOCKSHIFT; size = vim->vim_phys->vimp_num_entries * sizeof (*vim->vim_entries); if (size > bsize) { size = bsize / sizeof (*vim->vim_entries); size *= sizeof (*vim->vim_entries); } vim->vim_entries = malloc(size); if (vim->vim_entries == NULL) return (NULL); vim->vim_num_entries = size / sizeof (*vim->vim_entries); offset = index * sizeof (*vim->vim_entries); } /* We have data in vim_entries */ if (offset == 0) { if (index >= vim->vim_entry_offset && index <= vim->vim_entry_offset + vim->vim_num_entries) { index -= vim->vim_entry_offset; return (&vim->vim_entries[index]); } offset = index * sizeof (*vim->vim_entries); } vim->vim_entry_offset = index; size = vim->vim_num_entries * sizeof (*vim->vim_entries); rc = dnode_read(vim->vim_spa, vim->vim_dn, offset, vim->vim_entries, size); if (rc != 0) { /* Read error, invalidate vim_entries. */ free(vim->vim_entries); vim->vim_entries = NULL; return (NULL); } index -= vim->vim_entry_offset; return (&vim->vim_entries[index]); } /* * Returns the mapping entry for the given offset. * * It's possible that the given offset will not be in the mapping table * (i.e. no mapping entries contain this offset), in which case, the * return value value depends on the "next_if_missing" parameter. * * If the offset is not found in the table and "next_if_missing" is * B_FALSE, then NULL will always be returned. The behavior is intended * to allow consumers to get the entry corresponding to the offset * parameter, iff the offset overlaps with an entry in the table. * * If the offset is not found in the table and "next_if_missing" is * B_TRUE, then the entry nearest to the given offset will be returned, * such that the entry's source offset is greater than the offset * passed in (i.e. the "next" mapping entry in the table is returned, if * the offset is missing from the table). If there are no entries whose * source offset is greater than the passed in offset, NULL is returned. */ static vdev_indirect_mapping_entry_phys_t * vdev_indirect_mapping_entry_for_offset(vdev_indirect_mapping_t *vim, uint64_t offset) { ASSERT(vim->vim_phys->vimp_num_entries > 0); vdev_indirect_mapping_entry_phys_t *entry; uint64_t last = vim->vim_phys->vimp_num_entries - 1; uint64_t base = 0; /* * We don't define these inside of the while loop because we use * their value in the case that offset isn't in the mapping. */ uint64_t mid; int result; while (last >= base) { mid = base + ((last - base) >> 1); entry = vdev_indirect_mapping_entry(vim, mid); if (entry == NULL) break; result = dva_mapping_overlap_compare(&offset, entry); if (result == 0) { break; } else if (result < 0) { last = mid - 1; } else { base = mid + 1; } } return (entry); } /* * Given an indirect vdev and an extent on that vdev, it duplicates the * physical entries of the indirect mapping that correspond to the extent * to a new array and returns a pointer to it. In addition, copied_entries * is populated with the number of mapping entries that were duplicated. * * Finally, since we are doing an allocation, it is up to the caller to * free the array allocated in this function. */ vdev_indirect_mapping_entry_phys_t * vdev_indirect_mapping_duplicate_adjacent_entries(vdev_t *vd, uint64_t offset, uint64_t asize, uint64_t *copied_entries) { vdev_indirect_mapping_entry_phys_t *duplicate_mappings = NULL; vdev_indirect_mapping_t *vim = vd->v_mapping; uint64_t entries = 0; vdev_indirect_mapping_entry_phys_t *first_mapping = vdev_indirect_mapping_entry_for_offset(vim, offset); ASSERT3P(first_mapping, !=, NULL); vdev_indirect_mapping_entry_phys_t *m = first_mapping; while (asize > 0) { uint64_t size = DVA_GET_ASIZE(&m->vimep_dst); uint64_t inner_offset = offset - DVA_MAPPING_GET_SRC_OFFSET(m); uint64_t inner_size = MIN(asize, size - inner_offset); offset += inner_size; asize -= inner_size; entries++; m++; } size_t copy_length = entries * sizeof (*first_mapping); duplicate_mappings = malloc(copy_length); if (duplicate_mappings != NULL) bcopy(first_mapping, duplicate_mappings, copy_length); else entries = 0; *copied_entries = entries; return (duplicate_mappings); } static vdev_t * vdev_lookup_top(spa_t *spa, uint64_t vdev) { vdev_t *rvd; vdev_list_t *vlist; vlist = &spa->spa_root_vdev->v_children; STAILQ_FOREACH(rvd, vlist, v_childlink) if (rvd->v_id == vdev) break; return (rvd); } /* * This is a callback for vdev_indirect_remap() which allocates an * indirect_split_t for each split segment and adds it to iv_splits. */ static void vdev_indirect_gather_splits(uint64_t split_offset, vdev_t *vd, uint64_t offset, uint64_t size, void *arg) { int n = 1; zio_t *zio = arg; indirect_vsd_t *iv = zio->io_vsd; if (vd->v_read == vdev_indirect_read) return; if (vd->v_read == vdev_mirror_read) n = vd->v_nchildren; indirect_split_t *is = malloc(offsetof(indirect_split_t, is_child[n])); if (is == NULL) { zio->io_error = ENOMEM; return; } bzero(is, offsetof(indirect_split_t, is_child[n])); is->is_children = n; is->is_size = size; is->is_split_offset = split_offset; is->is_target_offset = offset; is->is_vdev = vd; /* * Note that we only consider multiple copies of the data for * *mirror* vdevs. We don't for "replacing" or "spare" vdevs, even * though they use the same ops as mirror, because there's only one * "good" copy under the replacing/spare. */ if (vd->v_read == vdev_mirror_read) { int i = 0; vdev_t *kid; STAILQ_FOREACH(kid, &vd->v_children, v_childlink) { is->is_child[i++].ic_vdev = kid; } } else { is->is_child[0].ic_vdev = vd; } list_insert_tail(&iv->iv_splits, is); } static void vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint64_t asize, void *arg) { list_t stack; spa_t *spa = vd->v_spa; zio_t *zio = arg; remap_segment_t *rs; list_create(&stack, sizeof (remap_segment_t), offsetof(remap_segment_t, rs_node)); rs = rs_alloc(vd, offset, asize, 0); if (rs == NULL) { printf("vdev_indirect_remap: out of memory.\n"); zio->io_error = ENOMEM; } for (; rs != NULL; rs = list_remove_head(&stack)) { vdev_t *v = rs->rs_vd; uint64_t num_entries = 0; /* vdev_indirect_mapping_t *vim = v->v_mapping; */ vdev_indirect_mapping_entry_phys_t *mapping = vdev_indirect_mapping_duplicate_adjacent_entries(v, rs->rs_offset, rs->rs_asize, &num_entries); if (num_entries == 0) zio->io_error = ENOMEM; for (uint64_t i = 0; i < num_entries; i++) { vdev_indirect_mapping_entry_phys_t *m = &mapping[i]; uint64_t size = DVA_GET_ASIZE(&m->vimep_dst); uint64_t dst_offset = DVA_GET_OFFSET(&m->vimep_dst); uint64_t dst_vdev = DVA_GET_VDEV(&m->vimep_dst); uint64_t inner_offset = rs->rs_offset - DVA_MAPPING_GET_SRC_OFFSET(m); uint64_t inner_size = MIN(rs->rs_asize, size - inner_offset); vdev_t *dst_v = vdev_lookup_top(spa, dst_vdev); if (dst_v->v_read == vdev_indirect_read) { remap_segment_t *o; o = rs_alloc(dst_v, dst_offset + inner_offset, inner_size, rs->rs_split_offset); if (o == NULL) { printf("vdev_indirect_remap: " "out of memory.\n"); zio->io_error = ENOMEM; break; } list_insert_head(&stack, o); } vdev_indirect_gather_splits(rs->rs_split_offset, dst_v, dst_offset + inner_offset, inner_size, arg); /* * vdev_indirect_gather_splits can have memory * allocation error, we can not recover from it. */ if (zio->io_error != 0) break; rs->rs_offset += inner_size; rs->rs_asize -= inner_size; rs->rs_split_offset += inner_size; } free(mapping); free(rs); if (zio->io_error != 0) break; } list_destroy(&stack); } static void vdev_indirect_map_free(zio_t *zio) { indirect_vsd_t *iv = zio->io_vsd; indirect_split_t *is; while ((is = list_head(&iv->iv_splits)) != NULL) { for (int c = 0; c < is->is_children; c++) { indirect_child_t *ic = &is->is_child[c]; free(ic->ic_data); } list_remove(&iv->iv_splits, is); free(is); } free(iv); } static int vdev_indirect_read(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset, size_t bytes) { zio_t zio; spa_t *spa = vdev->v_spa; indirect_vsd_t *iv; indirect_split_t *first; int rc = EIO; iv = calloc(1, sizeof (*iv)); if (iv == NULL) return (ENOMEM); list_create(&iv->iv_splits, sizeof (indirect_split_t), offsetof(indirect_split_t, is_node)); bzero(&zio, sizeof (zio)); zio.io_spa = spa; zio.io_bp = (blkptr_t *)bp; zio.io_data = buf; zio.io_size = bytes; zio.io_offset = offset; zio.io_vd = vdev; zio.io_vsd = iv; if (vdev->v_mapping == NULL) { vdev_indirect_config_t *vic; vic = &vdev->vdev_indirect_config; vdev->v_mapping = vdev_indirect_mapping_open(spa, &spa->spa_mos, vic->vic_mapping_object); } vdev_indirect_remap(vdev, offset, bytes, &zio); if (zio.io_error != 0) return (zio.io_error); first = list_head(&iv->iv_splits); if (first->is_size == zio.io_size) { /* * This is not a split block; we are pointing to the entire * data, which will checksum the same as the original data. * Pass the BP down so that the child i/o can verify the * checksum, and try a different location if available * (e.g. on a mirror). * * While this special case could be handled the same as the * general (split block) case, doing it this way ensures * that the vast majority of blocks on indirect vdevs * (which are not split) are handled identically to blocks * on non-indirect vdevs. This allows us to be less strict * about performance in the general (but rare) case. */ rc = first->is_vdev->v_read(first->is_vdev, zio.io_bp, zio.io_data, first->is_target_offset, bytes); } else { iv->iv_split_block = B_TRUE; /* * Read one copy of each split segment, from the * top-level vdev. Since we don't know the * checksum of each split individually, the child * zio can't ensure that we get the right data. * E.g. if it's a mirror, it will just read from a * random (healthy) leaf vdev. We have to verify * the checksum in vdev_indirect_io_done(). */ for (indirect_split_t *is = list_head(&iv->iv_splits); is != NULL; is = list_next(&iv->iv_splits, is)) { char *ptr = zio.io_data; rc = is->is_vdev->v_read(is->is_vdev, zio.io_bp, ptr + is->is_split_offset, is->is_target_offset, is->is_size); } if (zio_checksum_verify(spa, zio.io_bp, zio.io_data)) rc = ECKSUM; else rc = 0; } vdev_indirect_map_free(&zio); if (rc == 0) rc = zio.io_error; return (rc); } static int vdev_disk_read(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset, size_t bytes) { return (vdev_read_phys(vdev, bp, buf, offset + VDEV_LABEL_START_SIZE, bytes)); } static int vdev_missing_read(vdev_t *vdev __unused, const blkptr_t *bp __unused, void *buf __unused, off_t offset __unused, size_t bytes __unused) { return (ENOTSUP); } static int vdev_mirror_read(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset, size_t bytes) { vdev_t *kid; int rc; rc = EIO; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state != VDEV_STATE_HEALTHY) continue; rc = kid->v_read(kid, bp, buf, offset, bytes); if (!rc) return (0); } return (rc); } static int vdev_replacing_read(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset, size_t bytes) { vdev_t *kid; /* * Here we should have two kids: * First one which is the one we are replacing and we can trust * only this one to have valid data, but it might not be present. * Second one is that one we are replacing with. It is most likely * healthy, but we can't trust it has needed data, so we won't use it. */ kid = STAILQ_FIRST(&vdev->v_children); if (kid == NULL) return (EIO); if (kid->v_state != VDEV_STATE_HEALTHY) return (EIO); return (kid->v_read(kid, bp, buf, offset, bytes)); } static vdev_t * vdev_find(uint64_t guid) { vdev_t *vdev; STAILQ_FOREACH(vdev, &zfs_vdevs, v_alllink) if (vdev->v_guid == guid) return (vdev); return (0); } static vdev_t * vdev_create(uint64_t guid, vdev_read_t *vdev_read) { vdev_t *vdev; vdev_indirect_config_t *vic; vdev = calloc(1, sizeof (vdev_t)); if (vdev != NULL) { STAILQ_INIT(&vdev->v_children); vdev->v_guid = guid; vdev->v_read = vdev_read; /* * root vdev has no read function, we use this fact to * skip setting up data we do not need for root vdev. * We only point root vdev from spa. */ if (vdev_read != NULL) { vic = &vdev->vdev_indirect_config; vic->vic_prev_indirect_vdev = UINT64_MAX; STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink); } } return (vdev); } static void vdev_set_initial_state(vdev_t *vdev, const nvlist_t *nvlist) { uint64_t is_offline, is_faulted, is_degraded, is_removed, isnt_present; uint64_t is_log; is_offline = is_removed = is_faulted = is_degraded = isnt_present = 0; is_log = 0; (void) nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, NULL, &is_offline, NULL); (void) nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, NULL, &is_removed, NULL); (void) nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, NULL, &is_faulted, NULL); (void) nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, NULL, &is_degraded, NULL); (void) nvlist_find(nvlist, ZPOOL_CONFIG_NOT_PRESENT, DATA_TYPE_UINT64, NULL, &isnt_present, NULL); (void) nvlist_find(nvlist, ZPOOL_CONFIG_IS_LOG, DATA_TYPE_UINT64, NULL, &is_log, NULL); if (is_offline != 0) vdev->v_state = VDEV_STATE_OFFLINE; else if (is_removed != 0) vdev->v_state = VDEV_STATE_REMOVED; else if (is_faulted != 0) vdev->v_state = VDEV_STATE_FAULTED; else if (is_degraded != 0) vdev->v_state = VDEV_STATE_DEGRADED; else if (isnt_present != 0) vdev->v_state = VDEV_STATE_CANT_OPEN; vdev->v_islog = is_log != 0; } static int vdev_init(uint64_t guid, const nvlist_t *nvlist, vdev_t **vdevp) { uint64_t id, ashift, asize, nparity; const char *path; const char *type; int len, pathlen; char *name; vdev_t *vdev; if (nvlist_find(nvlist, ZPOOL_CONFIG_ID, DATA_TYPE_UINT64, NULL, &id, NULL) || nvlist_find(nvlist, ZPOOL_CONFIG_TYPE, DATA_TYPE_STRING, NULL, &type, &len)) { return (ENOENT); } if (memcmp(type, VDEV_TYPE_MIRROR, len) != 0 && memcmp(type, VDEV_TYPE_DISK, len) != 0 && #ifdef ZFS_TEST memcmp(type, VDEV_TYPE_FILE, len) != 0 && #endif memcmp(type, VDEV_TYPE_RAIDZ, len) != 0 && memcmp(type, VDEV_TYPE_INDIRECT, len) != 0 && memcmp(type, VDEV_TYPE_REPLACING, len) != 0 && memcmp(type, VDEV_TYPE_HOLE, len) != 0) { printf("ZFS: can only boot from disk, mirror, raidz1, " "raidz2 and raidz3 vdevs, got: %.*s\n", len, type); return (EIO); } if (memcmp(type, VDEV_TYPE_MIRROR, len) == 0) vdev = vdev_create(guid, vdev_mirror_read); else if (memcmp(type, VDEV_TYPE_RAIDZ, len) == 0) vdev = vdev_create(guid, vdev_raidz_read); else if (memcmp(type, VDEV_TYPE_REPLACING, len) == 0) vdev = vdev_create(guid, vdev_replacing_read); else if (memcmp(type, VDEV_TYPE_INDIRECT, len) == 0) { vdev_indirect_config_t *vic; vdev = vdev_create(guid, vdev_indirect_read); if (vdev != NULL) { vdev->v_state = VDEV_STATE_HEALTHY; vic = &vdev->vdev_indirect_config; nvlist_find(nvlist, ZPOOL_CONFIG_INDIRECT_OBJECT, DATA_TYPE_UINT64, NULL, &vic->vic_mapping_object, NULL); nvlist_find(nvlist, ZPOOL_CONFIG_INDIRECT_BIRTHS, DATA_TYPE_UINT64, NULL, &vic->vic_births_object, NULL); nvlist_find(nvlist, ZPOOL_CONFIG_PREV_INDIRECT_VDEV, DATA_TYPE_UINT64, NULL, &vic->vic_prev_indirect_vdev, NULL); } } else if (memcmp(type, VDEV_TYPE_HOLE, len) == 0) { vdev = vdev_create(guid, vdev_missing_read); } else { vdev = vdev_create(guid, vdev_disk_read); } if (vdev == NULL) return (ENOMEM); vdev_set_initial_state(vdev, nvlist); vdev->v_id = id; if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT, DATA_TYPE_UINT64, NULL, &ashift, NULL) == 0) vdev->v_ashift = ashift; if (nvlist_find(nvlist, ZPOOL_CONFIG_ASIZE, DATA_TYPE_UINT64, NULL, &asize, NULL) == 0) { vdev->v_psize = asize + VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE; } if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY, DATA_TYPE_UINT64, NULL, &nparity, NULL) == 0) vdev->v_nparity = nparity; if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH, DATA_TYPE_STRING, NULL, &path, &pathlen) == 0) { char prefix[] = "/dev/dsk/"; len = strlen(prefix); if (len < pathlen && memcmp(path, prefix, len) == 0) { path += len; pathlen -= len; } name = malloc(pathlen + 1); if (name != NULL) { bcopy(path, name, pathlen); name[pathlen] = '\0'; } vdev->v_name = name; vdev->v_phys_path = NULL; vdev->v_devid = NULL; if (nvlist_find(nvlist, ZPOOL_CONFIG_PHYS_PATH, DATA_TYPE_STRING, NULL, &path, &pathlen) == 0) { name = malloc(pathlen + 1); if (name != NULL) { bcopy(path, name, pathlen); name[pathlen] = '\0'; vdev->v_phys_path = name; } } if (nvlist_find(nvlist, ZPOOL_CONFIG_DEVID, DATA_TYPE_STRING, NULL, &path, &pathlen) == 0) { name = malloc(pathlen + 1); if (name != NULL) { bcopy(path, name, pathlen); name[pathlen] = '\0'; vdev->v_devid = name; } } } else { name = NULL; if (memcmp(type, VDEV_TYPE_RAIDZ, len) == 0) { if (vdev->v_nparity < 1 || vdev->v_nparity > 3) { printf("ZFS: invalid raidz parity: %d\n", vdev->v_nparity); return (EIO); } (void) asprintf(&name, "%.*s%d-%" PRIu64, len, type, vdev->v_nparity, id); } else { (void) asprintf(&name, "%.*s-%" PRIu64, len, type, id); } vdev->v_name = name; } *vdevp = vdev; return (0); } /* * Find slot for vdev. We return either NULL to signal to use * STAILQ_INSERT_HEAD, or we return link element to be used with * STAILQ_INSERT_AFTER. */ static vdev_t * vdev_find_previous(vdev_t *top_vdev, vdev_t *vdev) { vdev_t *v, *previous; if (STAILQ_EMPTY(&top_vdev->v_children)) return (NULL); previous = NULL; STAILQ_FOREACH(v, &top_vdev->v_children, v_childlink) { if (v->v_id > vdev->v_id) return (previous); if (v->v_id == vdev->v_id) return (v); if (v->v_id < vdev->v_id) previous = v; } return (previous); } static size_t vdev_child_count(vdev_t *vdev) { vdev_t *v; size_t count; count = 0; STAILQ_FOREACH(v, &vdev->v_children, v_childlink) { count++; } return (count); } /* * Insert vdev into top_vdev children list. List is ordered by v_id. */ static void vdev_insert(vdev_t *top_vdev, vdev_t *vdev) { vdev_t *previous; size_t count; /* * The top level vdev can appear in random order, depending how * the firmware is presenting the disk devices. * However, we will insert vdev to create list ordered by v_id, * so we can use either STAILQ_INSERT_HEAD or STAILQ_INSERT_AFTER * as STAILQ does not have insert before. */ previous = vdev_find_previous(top_vdev, vdev); if (previous == NULL) { STAILQ_INSERT_HEAD(&top_vdev->v_children, vdev, v_childlink); } else if (previous->v_id == vdev->v_id) { /* * This vdev was configured from label config, * do not insert duplicate. */ return; } else { STAILQ_INSERT_AFTER(&top_vdev->v_children, previous, vdev, v_childlink); } count = vdev_child_count(top_vdev); if (top_vdev->v_nchildren < count) top_vdev->v_nchildren = count; } static int vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist) { vdev_t *top_vdev, *vdev; nvlist_t **kids = NULL; int rc, nkids; /* Get top vdev. */ top_vdev = vdev_find(top_guid); if (top_vdev == NULL) { rc = vdev_init(top_guid, nvlist, &top_vdev); if (rc != 0) return (rc); top_vdev->v_spa = spa; top_vdev->v_top = top_vdev; vdev_insert(spa->spa_root_vdev, top_vdev); } /* Add children if there are any. */ rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, &nkids, &kids, NULL); if (rc == 0) { for (int i = 0; i < nkids; i++) { uint64_t guid; rc = nvlist_find(kids[i], ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, NULL, &guid, NULL); if (rc != 0) goto done; rc = vdev_init(guid, kids[i], &vdev); if (rc != 0) goto done; vdev->v_spa = spa; vdev->v_top = top_vdev; vdev_insert(top_vdev, vdev); } } else { /* * When there are no children, nvlist_find() does return * error, reset it because leaf devices have no children. */ rc = 0; } done: if (kids != NULL) { for (int i = 0; i < nkids; i++) nvlist_destroy(kids[i]); free(kids); } return (rc); } static int vdev_init_from_label(spa_t *spa, const nvlist_t *nvlist) { uint64_t pool_guid, top_guid; nvlist_t *vdevs; int rc; if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, NULL, &pool_guid, NULL) || nvlist_find(nvlist, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64, NULL, &top_guid, NULL) || nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, NULL, &vdevs, NULL)) { printf("ZFS: can't find vdev details\n"); return (ENOENT); } rc = vdev_from_nvlist(spa, top_guid, vdevs); nvlist_destroy(vdevs); return (rc); } static void vdev_set_state(vdev_t *vdev) { vdev_t *kid; int good_kids; int bad_kids; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { vdev_set_state(kid); } /* * A mirror or raidz is healthy if all its kids are healthy. A * mirror is degraded if any of its kids is healthy; a raidz * is degraded if at most nparity kids are offline. */ if (STAILQ_FIRST(&vdev->v_children)) { good_kids = 0; bad_kids = 0; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state == VDEV_STATE_HEALTHY) good_kids++; else bad_kids++; } if (bad_kids == 0) { vdev->v_state = VDEV_STATE_HEALTHY; } else { if (vdev->v_read == vdev_mirror_read) { if (good_kids) { vdev->v_state = VDEV_STATE_DEGRADED; } else { vdev->v_state = VDEV_STATE_OFFLINE; } } else if (vdev->v_read == vdev_raidz_read) { if (bad_kids > vdev->v_nparity) { vdev->v_state = VDEV_STATE_OFFLINE; } else { vdev->v_state = VDEV_STATE_DEGRADED; } } } } } static int vdev_update_from_nvlist(uint64_t top_guid, const nvlist_t *nvlist) { vdev_t *vdev; nvlist_t **kids = NULL; int rc, nkids; /* Update top vdev. */ vdev = vdev_find(top_guid); if (vdev != NULL) vdev_set_initial_state(vdev, nvlist); /* Update children if there are any. */ rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, &nkids, &kids, NULL); if (rc == 0) { for (int i = 0; i < nkids; i++) { uint64_t guid; rc = nvlist_find(kids[i], ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, NULL, &guid, NULL); if (rc != 0) break; vdev = vdev_find(guid); if (vdev != NULL) vdev_set_initial_state(vdev, kids[i]); } } else { rc = 0; } if (kids != NULL) { for (int i = 0; i < nkids; i++) nvlist_destroy(kids[i]); free(kids); } return (rc); } static int vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist) { uint64_t pool_guid, vdev_children; nvlist_t *vdevs = NULL, **kids = NULL; int rc, nkids; if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, NULL, &pool_guid, NULL) || nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_CHILDREN, DATA_TYPE_UINT64, NULL, &vdev_children, NULL) || nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, NULL, &vdevs, NULL)) { printf("ZFS: can't find vdev details\n"); return (ENOENT); } /* Wrong guid?! */ if (spa->spa_guid != pool_guid) { nvlist_destroy(vdevs); return (EINVAL); } spa->spa_root_vdev->v_nchildren = vdev_children; rc = nvlist_find(vdevs, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, &nkids, &kids, NULL); nvlist_destroy(vdevs); /* * MOS config has at least one child for root vdev. */ if (rc != 0) return (rc); for (int i = 0; i < nkids; i++) { uint64_t guid; vdev_t *vdev; rc = nvlist_find(kids[i], ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, NULL, &guid, NULL); if (rc != 0) break; vdev = vdev_find(guid); /* * Top level vdev is missing, create it. */ if (vdev == NULL) rc = vdev_from_nvlist(spa, guid, kids[i]); else rc = vdev_update_from_nvlist(guid, kids[i]); if (rc != 0) break; } if (kids != NULL) { for (int i = 0; i < nkids; i++) nvlist_destroy(kids[i]); free(kids); } /* * Re-evaluate top-level vdev state. */ vdev_set_state(spa->spa_root_vdev); return (rc); } static spa_t * spa_find_by_guid(uint64_t guid) { spa_t *spa; STAILQ_FOREACH(spa, &zfs_pools, spa_link) if (spa->spa_guid == guid) return (spa); return (NULL); } static spa_t * spa_find_by_name(const char *name) { spa_t *spa; STAILQ_FOREACH(spa, &zfs_pools, spa_link) if (strcmp(spa->spa_name, name) == 0) return (spa); return (NULL); } static spa_t * spa_find_by_dev(struct zfs_devdesc *dev) { if (dev->dd.d_dev->dv_type != DEVT_ZFS) return (NULL); if (dev->pool_guid == 0) return (STAILQ_FIRST(&zfs_pools)); return (spa_find_by_guid(dev->pool_guid)); } static spa_t * spa_create(uint64_t guid, const char *name) { spa_t *spa; if ((spa = calloc(1, sizeof (spa_t))) == NULL) return (NULL); if ((spa->spa_name = strdup(name)) == NULL) { free(spa); return (NULL); } spa->spa_guid = guid; spa->spa_root_vdev = vdev_create(guid, NULL); if (spa->spa_root_vdev == NULL) { free(spa->spa_name); free(spa); return (NULL); } spa->spa_root_vdev->v_name = strdup("root"); STAILQ_INSERT_TAIL(&zfs_pools, spa, spa_link); return (spa); } static const char * state_name(vdev_state_t state) { static const char *names[] = { "UNKNOWN", "CLOSED", "OFFLINE", "REMOVED", "CANT_OPEN", "FAULTED", "DEGRADED", "ONLINE" }; return (names[state]); } static int pager_printf(const char *fmt, ...) { char line[80]; va_list args; va_start(args, fmt); vsnprintf(line, sizeof (line), fmt, args); va_end(args); return (pager_output(line)); } #define STATUS_FORMAT " %s %s\n" static int print_state(int indent, const char *name, vdev_state_t state) { int i; char buf[512]; buf[0] = 0; for (i = 0; i < indent; i++) strcat(buf, " "); strcat(buf, name); return (pager_printf(STATUS_FORMAT, buf, state_name(state))); } static int vdev_status(vdev_t *vdev, int indent) { vdev_t *kid; int ret; if (vdev->v_islog) { (void) pager_output(" logs\n"); indent++; } ret = print_state(indent, vdev->v_name, vdev->v_state); if (ret != 0) return (ret); STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { ret = vdev_status(kid, indent + 1); if (ret != 0) return (ret); } return (ret); } static int spa_status(spa_t *spa) { static char bootfs[ZFS_MAXNAMELEN]; uint64_t rootid; vdev_list_t *vlist; vdev_t *vdev; int good_kids, bad_kids, degraded_kids, ret; vdev_state_t state; ret = pager_printf(" pool: %s\n", spa->spa_name); if (ret != 0) return (ret); if (zfs_get_root(spa, &rootid) == 0 && zfs_rlookup(spa, rootid, bootfs) == 0) { if (bootfs[0] == '\0') ret = pager_printf("bootfs: %s\n", spa->spa_name); else ret = pager_printf("bootfs: %s/%s\n", spa->spa_name, bootfs); if (ret != 0) return (ret); } ret = pager_printf("config:\n\n"); if (ret != 0) return (ret); ret = pager_printf(STATUS_FORMAT, "NAME", "STATE"); if (ret != 0) return (ret); good_kids = 0; degraded_kids = 0; bad_kids = 0; vlist = &spa->spa_root_vdev->v_children; STAILQ_FOREACH(vdev, vlist, v_childlink) { if (vdev->v_state == VDEV_STATE_HEALTHY) good_kids++; else if (vdev->v_state == VDEV_STATE_DEGRADED) degraded_kids++; else bad_kids++; } state = VDEV_STATE_CLOSED; if (good_kids > 0 && (degraded_kids + bad_kids) == 0) state = VDEV_STATE_HEALTHY; else if ((good_kids + degraded_kids) > 0) state = VDEV_STATE_DEGRADED; ret = print_state(0, spa->spa_name, state); if (ret != 0) return (ret); STAILQ_FOREACH(vdev, vlist, v_childlink) { ret = vdev_status(vdev, 1); if (ret != 0) return (ret); } return (ret); } int spa_all_status(void) { spa_t *spa; int first = 1, ret = 0; STAILQ_FOREACH(spa, &zfs_pools, spa_link) { if (!first) { ret = pager_printf("\n"); if (ret != 0) return (ret); } first = 0; ret = spa_status(spa); if (ret != 0) return (ret); } return (ret); } uint64_t vdev_label_offset(uint64_t psize, int l, uint64_t offset) { uint64_t label_offset; if (l < VDEV_LABELS / 2) label_offset = 0; else label_offset = psize - VDEV_LABELS * sizeof (vdev_label_t); return (offset + l * sizeof (vdev_label_t) + label_offset); } static int vdev_uberblock_compare(const uberblock_t *ub1, const uberblock_t *ub2) { unsigned int seq1 = 0; unsigned int seq2 = 0; int cmp = AVL_CMP(ub1->ub_txg, ub2->ub_txg); if (cmp != 0) return (cmp); cmp = AVL_CMP(ub1->ub_timestamp, ub2->ub_timestamp); if (cmp != 0) return (cmp); if (MMP_VALID(ub1) && MMP_SEQ_VALID(ub1)) seq1 = MMP_SEQ(ub1); if (MMP_VALID(ub2) && MMP_SEQ_VALID(ub2)) seq2 = MMP_SEQ(ub2); return (AVL_CMP(seq1, seq2)); } static int uberblock_verify(uberblock_t *ub) { if (ub->ub_magic == BSWAP_64((uint64_t)UBERBLOCK_MAGIC)) { byteswap_uint64_array(ub, sizeof (uberblock_t)); } if (ub->ub_magic != UBERBLOCK_MAGIC || !SPA_VERSION_IS_SUPPORTED(ub->ub_version)) return (EINVAL); return (0); } static int vdev_label_read(vdev_t *vd, int l, void *buf, uint64_t offset, size_t size) { blkptr_t bp; off_t off; off = vdev_label_offset(vd->v_psize, l, offset); BP_ZERO(&bp); BP_SET_LSIZE(&bp, size); BP_SET_PSIZE(&bp, size); BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL); BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF); DVA_SET_OFFSET(BP_IDENTITY(&bp), off); ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0); return (vdev_read_phys(vd, &bp, buf, off, size)); } /* * We do need to be sure we write to correct location. * Our vdev label does consist of 4 fields: * pad1 (8k), reserved. * bootenv (8k), checksummed, previously reserved, may contain garbage. * vdev_phys (112k), checksummed * uberblock ring (128k), checksummed. * * Since bootenv area may contain garbage, we can not reliably read it, as * we can get checksum errors. * Next best thing is vdev_phys - it is just after bootenv. It still may * be corrupted, but in such case we will miss this one write. */ static int vdev_label_write_validate(vdev_t *vd, int l, uint64_t offset) { uint64_t off, o_phys; void *buf; size_t size = VDEV_PHYS_SIZE; int rc; o_phys = offsetof(vdev_label_t, vl_vdev_phys); off = vdev_label_offset(vd->v_psize, l, o_phys); /* off should be 8K from bootenv */ if (vdev_label_offset(vd->v_psize, l, offset) + VDEV_PAD_SIZE != off) return (EINVAL); buf = malloc(size); if (buf == NULL) return (ENOMEM); /* Read vdev_phys */ rc = vdev_label_read(vd, l, buf, o_phys, size); free(buf); return (rc); } static int vdev_label_write(vdev_t *vd, int l, vdev_boot_envblock_t *be, uint64_t offset) { zio_checksum_info_t *ci; zio_cksum_t cksum; off_t off; size_t size = VDEV_PAD_SIZE; int rc; if (vd->v_phys_write == NULL) return (ENOTSUP); off = vdev_label_offset(vd->v_psize, l, offset); rc = vdev_label_write_validate(vd, l, offset); if (rc != 0) { return (rc); } ci = &zio_checksum_table[ZIO_CHECKSUM_LABEL]; be->vbe_zbt.zec_magic = ZEC_MAGIC; zio_checksum_label_verifier(&be->vbe_zbt.zec_cksum, off); ci->ci_func[0](be, size, NULL, &cksum); be->vbe_zbt.zec_cksum = cksum; return (vdev_write_phys(vd, be, off, size)); } static int vdev_write_bootenv_impl(vdev_t *vdev, vdev_boot_envblock_t *be) { vdev_t *kid; int rv = 0, err; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state != VDEV_STATE_HEALTHY) continue; err = vdev_write_bootenv_impl(kid, be); if (err != 0) rv = err; } /* * Non-leaf vdevs do not have v_phys_write. */ if (vdev->v_phys_write == NULL) return (rv); for (int l = 0; l < VDEV_LABELS; l++) { err = vdev_label_write(vdev, l, be, offsetof(vdev_label_t, vl_be)); if (err != 0) { printf("failed to write bootenv to %s label %d: %d\n", vdev->v_name ? vdev->v_name : "unknown", l, err); rv = err; } } return (rv); } int vdev_write_bootenv(vdev_t *vdev, nvlist_t *nvl) { vdev_boot_envblock_t *be; nvlist_t nv, *nvp; uint64_t version; int rv; if (nvl->nv_size > sizeof (be->vbe_bootenv)) return (E2BIG); version = VB_RAW; nvp = vdev_read_bootenv(vdev); if (nvp != NULL) { nvlist_find(nvp, BOOTENV_VERSION, DATA_TYPE_UINT64, NULL, &version, NULL); nvlist_destroy(nvp); } be = calloc(1, sizeof (*be)); if (be == NULL) return (ENOMEM); be->vbe_version = version; switch (version) { case VB_RAW: /* * If there is no envmap, we will just wipe bootenv. */ nvlist_find(nvl, GRUB_ENVMAP, DATA_TYPE_STRING, NULL, be->vbe_bootenv, NULL); rv = 0; break; case VB_NVLIST: nv.nv_header = nvl->nv_header; nv.nv_asize = nvl->nv_asize; nv.nv_size = nvl->nv_size; bcopy(&nv.nv_header, be->vbe_bootenv, sizeof (nv.nv_header)); nv.nv_data = (uint8_t *)be->vbe_bootenv + sizeof (nvs_header_t); bcopy(nvl->nv_data, nv.nv_data, nv.nv_size); rv = nvlist_export(&nv); break; default: rv = EINVAL; break; } if (rv == 0) { be->vbe_version = htobe64(be->vbe_version); rv = vdev_write_bootenv_impl(vdev, be); } free(be); return (rv); } /* * Read the bootenv area from pool label, return the nvlist from it. * We return from first successful read. */ nvlist_t * vdev_read_bootenv(vdev_t *vdev) { vdev_t *kid; nvlist_t *benv; vdev_boot_envblock_t *be; char *command; bool ok; int rv; STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state != VDEV_STATE_HEALTHY) continue; benv = vdev_read_bootenv(kid); if (benv != NULL) return (benv); } be = malloc(sizeof (*be)); if (be == NULL) return (NULL); rv = 0; for (int l = 0; l < VDEV_LABELS; l++) { rv = vdev_label_read(vdev, l, be, offsetof(vdev_label_t, vl_be), sizeof (*be)); if (rv == 0) break; } if (rv != 0) { free(be); return (NULL); } be->vbe_version = be64toh(be->vbe_version); switch (be->vbe_version) { case VB_RAW: /* * if we have textual data in vbe_bootenv, create nvlist * with key "envmap". */ benv = nvlist_create(NV_UNIQUE_NAME); if (benv != NULL) { if (*be->vbe_bootenv == '\0') { nvlist_add_uint64(benv, BOOTENV_VERSION, VB_NVLIST); break; } nvlist_add_uint64(benv, BOOTENV_VERSION, VB_RAW); be->vbe_bootenv[sizeof (be->vbe_bootenv) - 1] = '\0'; nvlist_add_string(benv, GRUB_ENVMAP, be->vbe_bootenv); } break; case VB_NVLIST: benv = nvlist_import(be->vbe_bootenv, sizeof (be->vbe_bootenv)); break; default: command = (char *)be; ok = false; /* Check for legacy zfsbootcfg command string */ for (int i = 0; command[i] != '\0'; i++) { if (iscntrl(command[i])) { ok = false; break; } else { ok = true; } } benv = nvlist_create(NV_UNIQUE_NAME); if (benv != NULL) { if (ok) nvlist_add_string(benv, FREEBSD_BOOTONCE, command); else nvlist_add_uint64(benv, BOOTENV_VERSION, VB_NVLIST); } break; } free(be); return (benv); } static uint64_t vdev_get_label_asize(nvlist_t *nvl) { nvlist_t *vdevs; uint64_t asize; const char *type; int len; asize = 0; /* Get vdev tree */ if (nvlist_find(nvl, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST, NULL, &vdevs, NULL) != 0) return (asize); /* * Get vdev type. We will calculate asize for raidz, mirror and disk. * For raidz, the asize is raw size of all children. */ if (nvlist_find(vdevs, ZPOOL_CONFIG_TYPE, DATA_TYPE_STRING, NULL, &type, &len) != 0) goto done; if (memcmp(type, VDEV_TYPE_MIRROR, len) != 0 && memcmp(type, VDEV_TYPE_DISK, len) != 0 && memcmp(type, VDEV_TYPE_RAIDZ, len) != 0) goto done; if (nvlist_find(vdevs, ZPOOL_CONFIG_ASIZE, DATA_TYPE_UINT64, NULL, &asize, NULL) != 0) goto done; if (memcmp(type, VDEV_TYPE_RAIDZ, len) == 0) { nvlist_t **kids; int nkids; if (nvlist_find(vdevs, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, &nkids, &kids, NULL) != 0) { asize = 0; goto done; } asize /= nkids; for (int i = 0; i < nkids; i++) nvlist_destroy(kids[i]); free(kids); } asize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE; done: nvlist_destroy(vdevs); return (asize); } static nvlist_t * vdev_label_read_config(vdev_t *vd, uint64_t txg) { vdev_phys_t *label; uint64_t best_txg = 0; uint64_t label_txg = 0; uint64_t asize; nvlist_t *nvl = NULL, *tmp; int error; label = malloc(sizeof (vdev_phys_t)); if (label == NULL) return (NULL); for (int l = 0; l < VDEV_LABELS; l++) { if (vdev_label_read(vd, l, label, offsetof(vdev_label_t, vl_vdev_phys), sizeof (vdev_phys_t))) continue; tmp = nvlist_import(label->vp_nvlist, sizeof (label->vp_nvlist)); if (tmp == NULL) continue; error = nvlist_find(tmp, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64, NULL, &label_txg, NULL); if (error != 0 || label_txg == 0) { nvlist_destroy(nvl); nvl = tmp; goto done; } if (label_txg <= txg && label_txg > best_txg) { best_txg = label_txg; nvlist_destroy(nvl); nvl = tmp; tmp = NULL; /* * Use asize from pool config. We need this * because we can get bad value from BIOS. */ asize = vdev_get_label_asize(nvl); if (asize != 0) { vd->v_psize = asize; } } nvlist_destroy(tmp); } if (best_txg == 0) { nvlist_destroy(nvl); nvl = NULL; } done: free(label); return (nvl); } static void vdev_uberblock_load(vdev_t *vd, uberblock_t *ub) { uberblock_t *buf; buf = malloc(VDEV_UBERBLOCK_SIZE(vd)); if (buf == NULL) return; for (int l = 0; l < VDEV_LABELS; l++) { for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) { if (vdev_label_read(vd, l, buf, VDEV_UBERBLOCK_OFFSET(vd, n), VDEV_UBERBLOCK_SIZE(vd))) continue; if (uberblock_verify(buf) != 0) continue; if (vdev_uberblock_compare(buf, ub) > 0) *ub = *buf; } } free(buf); } static int vdev_probe(vdev_phys_read_t *_read, vdev_phys_write_t *_write, void *priv, spa_t **spap) { vdev_t vtmp; spa_t *spa; vdev_t *vdev; nvlist_t *nvl; uint64_t val; uint64_t guid, vdev_children; uint64_t pool_txg, pool_guid; const char *pool_name; int rc, namelen; /* * Load the vdev label and figure out which * uberblock is most current. */ memset(&vtmp, 0, sizeof (vtmp)); vtmp.v_phys_read = _read; vtmp.v_phys_write = _write; vtmp.v_priv = priv; vtmp.v_psize = P2ALIGN(ldi_get_size(priv), (uint64_t)sizeof (vdev_label_t)); /* Test for minimum device size. */ if (vtmp.v_psize < SPA_MINDEVSIZE) return (EIO); nvl = vdev_label_read_config(&vtmp, UINT64_MAX); if (nvl == NULL) return (EIO); if (nvlist_find(nvl, ZPOOL_CONFIG_VERSION, DATA_TYPE_UINT64, NULL, &val, NULL) != 0) { nvlist_destroy(nvl); return (EIO); } if (!SPA_VERSION_IS_SUPPORTED(val)) { printf("ZFS: unsupported ZFS version %u (should be %u)\n", (unsigned)val, (unsigned)SPA_VERSION); nvlist_destroy(nvl); return (EIO); } /* Check ZFS features for read */ rc = nvlist_check_features_for_read(nvl); if (rc != 0) { nvlist_destroy(nvl); return (EIO); } if (nvlist_find(nvl, ZPOOL_CONFIG_POOL_STATE, DATA_TYPE_UINT64, NULL, &val, NULL) != 0) { nvlist_destroy(nvl); return (EIO); } if (val == POOL_STATE_DESTROYED) { /* We don't boot only from destroyed pools. */ nvlist_destroy(nvl); return (EIO); } if (nvlist_find(nvl, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64, NULL, &pool_txg, NULL) != 0 || nvlist_find(nvl, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, NULL, &pool_guid, NULL) != 0 || nvlist_find(nvl, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING, NULL, &pool_name, &namelen) != 0) { /* * Cache and spare devices end up here - just ignore * them. */ nvlist_destroy(nvl); return (EIO); } /* * Create the pool if this is the first time we've seen it. */ spa = spa_find_by_guid(pool_guid); if (spa == NULL) { char *name; nvlist_find(nvl, ZPOOL_CONFIG_VDEV_CHILDREN, DATA_TYPE_UINT64, NULL, &vdev_children, NULL); name = malloc(namelen + 1); if (name == NULL) { nvlist_destroy(nvl); return (ENOMEM); } bcopy(pool_name, name, namelen); name[namelen] = '\0'; spa = spa_create(pool_guid, name); free(name); if (spa == NULL) { nvlist_destroy(nvl); return (ENOMEM); } spa->spa_root_vdev->v_nchildren = vdev_children; } if (pool_txg > spa->spa_txg) spa->spa_txg = pool_txg; /* * Get the vdev tree and create our in-core copy of it. * If we already have a vdev with this guid, this must * be some kind of alias (overlapping slices, dangerously dedicated * disks etc). */ if (nvlist_find(nvl, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, NULL, &guid, NULL) != 0) { nvlist_destroy(nvl); return (EIO); } vdev = vdev_find(guid); /* Has this vdev already been inited? */ if (vdev && vdev->v_phys_read) { nvlist_destroy(nvl); return (EIO); } rc = vdev_init_from_label(spa, nvl); nvlist_destroy(nvl); if (rc != 0) return (rc); /* * We should already have created an incomplete vdev for this * vdev. Find it and initialise it with our read proc. */ vdev = vdev_find(guid); if (vdev != NULL) { vdev->v_phys_read = _read; vdev->v_phys_write = _write; vdev->v_priv = priv; vdev->v_psize = vtmp.v_psize; /* * If no other state is set, mark vdev healthy. */ if (vdev->v_state == VDEV_STATE_UNKNOWN) vdev->v_state = VDEV_STATE_HEALTHY; } else { printf("ZFS: inconsistent nvlist contents\n"); return (EIO); } if (vdev->v_islog) spa->spa_with_log = vdev->v_islog; /* Record boot vdev for spa. */ if (spa->spa_boot_vdev == NULL) spa->spa_boot_vdev = vdev; /* * Re-evaluate top-level vdev state. */ vdev_set_state(vdev->v_top); /* * Ok, we are happy with the pool so far. Lets find * the best uberblock and then we can actually access * the contents of the pool. */ vdev_uberblock_load(vdev, &spa->spa_uberblock); if (spap != NULL) *spap = spa; return (0); } static int ilog2(int n) { int v; for (v = 0; v < 32; v++) if (n == (1 << v)) return (v); return (-1); } static int zio_read_gang(const spa_t *spa, const blkptr_t *bp, void *buf) { blkptr_t gbh_bp; zio_gbh_phys_t zio_gb; char *pbuf; int i; /* Artificial BP for gang block header. */ gbh_bp = *bp; BP_SET_PSIZE(&gbh_bp, SPA_GANGBLOCKSIZE); BP_SET_LSIZE(&gbh_bp, SPA_GANGBLOCKSIZE); BP_SET_CHECKSUM(&gbh_bp, ZIO_CHECKSUM_GANG_HEADER); BP_SET_COMPRESS(&gbh_bp, ZIO_COMPRESS_OFF); for (i = 0; i < SPA_DVAS_PER_BP; i++) DVA_SET_GANG(&gbh_bp.blk_dva[i], 0); /* Read gang header block using the artificial BP. */ if (zio_read(spa, &gbh_bp, &zio_gb)) return (EIO); pbuf = buf; for (i = 0; i < SPA_GBH_NBLKPTRS; i++) { blkptr_t *gbp = &zio_gb.zg_blkptr[i]; if (BP_IS_HOLE(gbp)) continue; if (zio_read(spa, gbp, pbuf)) return (EIO); pbuf += BP_GET_PSIZE(gbp); } if (zio_checksum_verify(spa, bp, buf)) return (EIO); return (0); } static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf) { int cpfunc = BP_GET_COMPRESS(bp); uint64_t align, size; void *pbuf; int i, error; /* * Process data embedded in block pointer */ if (BP_IS_EMBEDDED(bp)) { ASSERT(BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA); size = BPE_GET_PSIZE(bp); ASSERT(size <= BPE_PAYLOAD_SIZE); if (cpfunc != ZIO_COMPRESS_OFF) pbuf = malloc(size); else pbuf = buf; if (pbuf == NULL) return (ENOMEM); decode_embedded_bp_compressed(bp, pbuf); error = 0; if (cpfunc != ZIO_COMPRESS_OFF) { error = zio_decompress_data(cpfunc, pbuf, size, buf, BP_GET_LSIZE(bp)); free(pbuf); } if (error != 0) printf("ZFS: i/o error - unable to decompress " "block pointer data, error %d\n", error); return (error); } error = EIO; for (i = 0; i < SPA_DVAS_PER_BP; i++) { const dva_t *dva = &bp->blk_dva[i]; vdev_t *vdev; vdev_list_t *vlist; uint64_t vdevid; off_t offset; if (!dva->dva_word[0] && !dva->dva_word[1]) continue; vdevid = DVA_GET_VDEV(dva); offset = DVA_GET_OFFSET(dva); vlist = &spa->spa_root_vdev->v_children; STAILQ_FOREACH(vdev, vlist, v_childlink) { if (vdev->v_id == vdevid) break; } if (!vdev || !vdev->v_read) continue; size = BP_GET_PSIZE(bp); if (vdev->v_read == vdev_raidz_read) { align = 1ULL << vdev->v_ashift; if (P2PHASE(size, align) != 0) size = P2ROUNDUP(size, align); } if (size != BP_GET_PSIZE(bp) || cpfunc != ZIO_COMPRESS_OFF) pbuf = malloc(size); else pbuf = buf; if (pbuf == NULL) { error = ENOMEM; break; } if (DVA_GET_GANG(dva)) error = zio_read_gang(spa, bp, pbuf); else error = vdev->v_read(vdev, bp, pbuf, offset, size); if (error == 0) { if (cpfunc != ZIO_COMPRESS_OFF) error = zio_decompress_data(cpfunc, pbuf, BP_GET_PSIZE(bp), buf, BP_GET_LSIZE(bp)); else if (size != BP_GET_PSIZE(bp)) bcopy(pbuf, buf, BP_GET_PSIZE(bp)); } if (buf != pbuf) free(pbuf); if (error == 0) break; } if (error != 0) printf("ZFS: i/o error - all block copies unavailable\n"); return (error); } static int dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf, size_t buflen) { int ibshift = dnode->dn_indblkshift - SPA_BLKPTRSHIFT; int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; int nlevels = dnode->dn_nlevels; int i, rc; if (bsize > SPA_MAXBLOCKSIZE) { printf("ZFS: I/O error - blocks larger than %llu are not " "supported\n", SPA_MAXBLOCKSIZE); return (EIO); } /* * Handle odd block sizes, mirrors dmu_read_impl(). Data can't exist * past the first block, so we'll clip the read to the portion of the * buffer within bsize and zero out the remainder. */ if (dnode->dn_maxblkid == 0) { size_t newbuflen; newbuflen = offset > bsize ? 0 : MIN(buflen, bsize - offset); bzero((char *)buf + newbuflen, buflen - newbuflen); buflen = newbuflen; } /* * Note: bsize may not be a power of two here so we need to do an * actual divide rather than a bitshift. */ while (buflen > 0) { uint64_t bn = offset / bsize; int boff = offset % bsize; int ibn; const blkptr_t *indbp; blkptr_t bp; if (bn > dnode->dn_maxblkid) { printf("warning: zfs bug: bn %llx > dn_maxblkid %llx\n", (unsigned long long)bn, (unsigned long long)dnode->dn_maxblkid); /* * zfs bug, will not return error * return (EIO); */ } if (dnode == dnode_cache_obj && bn == dnode_cache_bn) goto cached; indbp = dnode->dn_blkptr; for (i = 0; i < nlevels; i++) { /* * Copy the bp from the indirect array so that * we can re-use the scratch buffer for multi-level * objects. */ ibn = bn >> ((nlevels - i - 1) * ibshift); ibn &= ((1 << ibshift) - 1); bp = indbp[ibn]; if (BP_IS_HOLE(&bp)) { memset(dnode_cache_buf, 0, bsize); break; } rc = zio_read(spa, &bp, dnode_cache_buf); if (rc) return (rc); indbp = (const blkptr_t *) dnode_cache_buf; } dnode_cache_obj = dnode; dnode_cache_bn = bn; cached: /* * The buffer contains our data block. Copy what we * need from it and loop. */ i = bsize - boff; if (i > buflen) i = buflen; memcpy(buf, &dnode_cache_buf[boff], i); buf = ((char *)buf) + i; offset += i; buflen -= i; } return (0); } /* * Lookup a value in a microzap directory. */ static int mzap_lookup(const mzap_phys_t *mz, size_t size, const char *name, uint64_t *value) { const mzap_ent_phys_t *mze; int chunks, i; /* * Microzap objects use exactly one block. Read the whole * thing. */ chunks = size / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { mze = &mz->mz_chunk[i]; if (strcmp(mze->mze_name, name) == 0) { *value = mze->mze_value; return (0); } } return (ENOENT); } /* * Compare a name with a zap leaf entry. Return non-zero if the name * matches. */ static int fzap_name_equal(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, const char *name) { size_t namelen; const zap_leaf_chunk_t *nc; const char *p; namelen = zc->l_entry.le_name_numints; nc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_name_chunk); p = name; while (namelen > 0) { size_t len; len = namelen; if (len > ZAP_LEAF_ARRAY_BYTES) len = ZAP_LEAF_ARRAY_BYTES; if (memcmp(p, nc->l_array.la_array, len)) return (0); p += len; namelen -= len; nc = &ZAP_LEAF_CHUNK(zl, nc->l_array.la_next); } return (1); } /* * Extract a uint64_t value from a zap leaf entry. */ static uint64_t fzap_leaf_value(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc) { const zap_leaf_chunk_t *vc; int i; uint64_t value; const uint8_t *p; vc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_value_chunk); for (i = 0, value = 0, p = vc->l_array.la_array; i < 8; i++) { value = (value << 8) | p[i]; } return (value); } static void stv(int len, void *addr, uint64_t value) { switch (len) { case 1: *(uint8_t *)addr = value; return; case 2: *(uint16_t *)addr = value; return; case 4: *(uint32_t *)addr = value; return; case 8: *(uint64_t *)addr = value; return; } } /* * Extract a array from a zap leaf entry. */ static void fzap_leaf_array(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, uint64_t integer_size, uint64_t num_integers, void *buf) { uint64_t array_int_len = zc->l_entry.le_value_intlen; uint64_t value = 0; uint64_t *u64 = buf; char *p = buf; int len = MIN(zc->l_entry.le_value_numints, num_integers); int chunk = zc->l_entry.le_value_chunk; int byten = 0; if (integer_size == 8 && len == 1) { *u64 = fzap_leaf_value(zl, zc); return; } while (len > 0) { struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(zl, chunk).l_array; int i; ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(zl)); for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) { value = (value << 8) | la->la_array[i]; byten++; if (byten == array_int_len) { stv(integer_size, p, value); byten = 0; len--; if (len == 0) return; p += integer_size; } } chunk = la->la_next; } } static int fzap_check_size(uint64_t integer_size, uint64_t num_integers) { switch (integer_size) { case 1: case 2: case 4: case 8: break; default: return (EINVAL); } if (integer_size * num_integers > ZAP_MAXVALUELEN) return (E2BIG); return (0); } static void zap_leaf_free(zap_leaf_t *leaf) { free(leaf->l_phys); free(leaf); } static int zap_get_leaf_byblk(fat_zap_t *zap, uint64_t blk, zap_leaf_t **lp) { int bs = FZAP_BLOCK_SHIFT(zap); int err; *lp = malloc(sizeof (**lp)); if (*lp == NULL) return (ENOMEM); (*lp)->l_bs = bs; (*lp)->l_phys = malloc(1 << bs); if ((*lp)->l_phys == NULL) { free(*lp); return (ENOMEM); } err = dnode_read(zap->zap_spa, zap->zap_dnode, blk << bs, (*lp)->l_phys, 1 << bs); if (err != 0) { zap_leaf_free(*lp); } return (err); } static int zap_table_load(fat_zap_t *zap, zap_table_phys_t *tbl, uint64_t idx, uint64_t *valp) { int bs = FZAP_BLOCK_SHIFT(zap); uint64_t blk = idx >> (bs - 3); uint64_t off = idx & ((1 << (bs - 3)) - 1); uint64_t *buf; int rc; buf = malloc(1 << zap->zap_block_shift); if (buf == NULL) return (ENOMEM); rc = dnode_read(zap->zap_spa, zap->zap_dnode, (tbl->zt_blk + blk) << bs, buf, 1 << zap->zap_block_shift); if (rc == 0) *valp = buf[off]; free(buf); return (rc); } static int zap_idx_to_blk(fat_zap_t *zap, uint64_t idx, uint64_t *valp) { if (zap->zap_phys->zap_ptrtbl.zt_numblks == 0) { *valp = ZAP_EMBEDDED_PTRTBL_ENT(zap, idx); return (0); } else { return (zap_table_load(zap, &zap->zap_phys->zap_ptrtbl, idx, valp)); } } #define ZAP_HASH_IDX(hash, n) (((n) == 0) ? 0 : ((hash) >> (64 - (n)))) static int zap_deref_leaf(fat_zap_t *zap, uint64_t h, zap_leaf_t **lp) { uint64_t idx, blk; int err; idx = ZAP_HASH_IDX(h, zap->zap_phys->zap_ptrtbl.zt_shift); err = zap_idx_to_blk(zap, idx, &blk); if (err != 0) return (err); return (zap_get_leaf_byblk(zap, blk, lp)); } #define CHAIN_END 0xffff /* end of the chunk chain */ #define LEAF_HASH(l, h) \ ((ZAP_LEAF_HASH_NUMENTRIES(l)-1) & \ ((h) >> \ (64 - ZAP_LEAF_HASH_SHIFT(l) - (l)->l_phys->l_hdr.lh_prefix_len))) #define LEAF_HASH_ENTPTR(l, h) (&(l)->l_phys->l_hash[LEAF_HASH(l, h)]) static int zap_leaf_lookup(zap_leaf_t *zl, uint64_t hash, const char *name, uint64_t integer_size, uint64_t num_integers, void *value) { int rc; uint16_t *chunkp; struct zap_leaf_entry *le; /* * Make sure this chunk matches our hash. */ if (zl->l_phys->l_hdr.lh_prefix_len > 0 && zl->l_phys->l_hdr.lh_prefix != hash >> (64 - zl->l_phys->l_hdr.lh_prefix_len)) return (EIO); rc = ENOENT; for (chunkp = LEAF_HASH_ENTPTR(zl, hash); *chunkp != CHAIN_END; chunkp = &le->le_next) { zap_leaf_chunk_t *zc; uint16_t chunk = *chunkp; le = ZAP_LEAF_ENTRY(zl, chunk); if (le->le_hash != hash) continue; zc = &ZAP_LEAF_CHUNK(zl, chunk); if (fzap_name_equal(zl, zc, name)) { if (zc->l_entry.le_value_intlen > integer_size) { rc = EINVAL; } else { fzap_leaf_array(zl, zc, integer_size, num_integers, value); rc = 0; } break; } } return (rc); } /* * Lookup a value in a fatzap directory. */ static int fzap_lookup(const spa_t *spa, const dnode_phys_t *dnode, zap_phys_t *zh, const char *name, uint64_t integer_size, uint64_t num_integers, void *value) { int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; fat_zap_t z; zap_leaf_t *zl; uint64_t hash; int rc; if (zh->zap_magic != ZAP_MAGIC) return (EIO); if ((rc = fzap_check_size(integer_size, num_integers)) != 0) return (rc); z.zap_block_shift = ilog2(bsize); z.zap_phys = zh; z.zap_spa = spa; z.zap_dnode = dnode; hash = zap_hash(zh->zap_salt, name); rc = zap_deref_leaf(&z, hash, &zl); if (rc != 0) return (rc); rc = zap_leaf_lookup(zl, hash, name, integer_size, num_integers, value); zap_leaf_free(zl); return (rc); } /* * Lookup a name in a zap object and return its value as a uint64_t. */ static int zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t integer_size, uint64_t num_integers, void *value) { int rc; zap_phys_t *zap; size_t size = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; zap = malloc(size); if (zap == NULL) return (ENOMEM); rc = dnode_read(spa, dnode, 0, zap, size); if (rc) goto done; switch (zap->zap_block_type) { case ZBT_MICRO: rc = mzap_lookup((const mzap_phys_t *)zap, size, name, value); break; case ZBT_HEADER: rc = fzap_lookup(spa, dnode, zap, name, integer_size, num_integers, value); break; default: printf("ZFS: invalid zap_type=%" PRIx64 "\n", zap->zap_block_type); rc = EIO; } done: free(zap); return (rc); } /* * List a microzap directory. */ static int mzap_list(const mzap_phys_t *mz, size_t size, int (*callback)(const char *, uint64_t)) { const mzap_ent_phys_t *mze; int chunks, i, rc; /* * Microzap objects use exactly one block. Read the whole * thing. */ rc = 0; chunks = size / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { mze = &mz->mz_chunk[i]; if (mze->mze_name[0]) { rc = callback(mze->mze_name, mze->mze_value); if (rc != 0) break; } } return (rc); } /* * List a fatzap directory. */ static int fzap_list(const spa_t *spa, const dnode_phys_t *dnode, zap_phys_t *zh, int (*callback)(const char *, uint64_t)) { int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; fat_zap_t z; int i, j, rc; if (zh->zap_magic != ZAP_MAGIC) return (EIO); z.zap_block_shift = ilog2(bsize); z.zap_phys = zh; /* * This assumes that the leaf blocks start at block 1. The * documentation isn't exactly clear on this. */ zap_leaf_t zl; zl.l_bs = z.zap_block_shift; zl.l_phys = malloc(bsize); if (zl.l_phys == NULL) return (ENOMEM); for (i = 0; i < zh->zap_num_leafs; i++) { off_t off = ((off_t)(i + 1)) << zl.l_bs; char name[256], *p; uint64_t value; if (dnode_read(spa, dnode, off, zl.l_phys, bsize)) { free(zl.l_phys); return (EIO); } for (j = 0; j < ZAP_LEAF_NUMCHUNKS(&zl); j++) { zap_leaf_chunk_t *zc, *nc; int namelen; zc = &ZAP_LEAF_CHUNK(&zl, j); if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY) continue; namelen = zc->l_entry.le_name_numints; if (namelen > sizeof (name)) namelen = sizeof (name); /* * Paste the name back together. */ nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk); p = name; while (namelen > 0) { int len; len = namelen; if (len > ZAP_LEAF_ARRAY_BYTES) len = ZAP_LEAF_ARRAY_BYTES; memcpy(p, nc->l_array.la_array, len); p += len; namelen -= len; nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next); } /* * Assume the first eight bytes of the value are * a uint64_t. */ value = fzap_leaf_value(&zl, zc); /* printf("%s 0x%jx\n", name, (uintmax_t)value); */ rc = callback((const char *)name, value); if (rc != 0) { free(zl.l_phys); return (rc); } } } free(zl.l_phys); return (0); } static int zfs_printf(const char *name, uint64_t value __unused) { printf("%s\n", name); return (0); } /* * List a zap directory. */ static int zap_list(const spa_t *spa, const dnode_phys_t *dnode) { zap_phys_t *zap; size_t size = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; int rc; zap = malloc(size); if (zap == NULL) return (ENOMEM); rc = dnode_read(spa, dnode, 0, zap, size); if (rc == 0) { if (zap->zap_block_type == ZBT_MICRO) rc = mzap_list((const mzap_phys_t *)zap, size, zfs_printf); else rc = fzap_list(spa, dnode, zap, zfs_printf); } free(zap); return (rc); } static int objset_get_dnode(const spa_t *spa, const objset_phys_t *os, uint64_t objnum, dnode_phys_t *dnode) { off_t offset; offset = objnum * sizeof (dnode_phys_t); return (dnode_read(spa, &os->os_meta_dnode, offset, dnode, sizeof (dnode_phys_t))); } /* * Lookup a name in a microzap directory. */ static int mzap_rlookup(const mzap_phys_t *mz, size_t size, char *name, uint64_t value) { const mzap_ent_phys_t *mze; int chunks, i; /* * Microzap objects use exactly one block. Read the whole * thing. */ chunks = size / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { mze = &mz->mz_chunk[i]; if (value == mze->mze_value) { strcpy(name, mze->mze_name); return (0); } } return (ENOENT); } static void fzap_name_copy(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc, char *name) { size_t namelen; const zap_leaf_chunk_t *nc; char *p; namelen = zc->l_entry.le_name_numints; nc = &ZAP_LEAF_CHUNK(zl, zc->l_entry.le_name_chunk); p = name; while (namelen > 0) { size_t len; len = namelen; if (len > ZAP_LEAF_ARRAY_BYTES) len = ZAP_LEAF_ARRAY_BYTES; memcpy(p, nc->l_array.la_array, len); p += len; namelen -= len; nc = &ZAP_LEAF_CHUNK(zl, nc->l_array.la_next); } *p = '\0'; } static int fzap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, zap_phys_t *zh, char *name, uint64_t value) { int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; fat_zap_t z; uint64_t i; int j, rc; if (zh->zap_magic != ZAP_MAGIC) return (EIO); z.zap_block_shift = ilog2(bsize); z.zap_phys = zh; /* * This assumes that the leaf blocks start at block 1. The * documentation isn't exactly clear on this. */ zap_leaf_t zl; zl.l_bs = z.zap_block_shift; zl.l_phys = malloc(bsize); if (zl.l_phys == NULL) return (ENOMEM); for (i = 0; i < zh->zap_num_leafs; i++) { off_t off = ((off_t)(i + 1)) << zl.l_bs; rc = dnode_read(spa, dnode, off, zl.l_phys, bsize); if (rc != 0) goto done; for (j = 0; j < ZAP_LEAF_NUMCHUNKS(&zl); j++) { zap_leaf_chunk_t *zc; zc = &ZAP_LEAF_CHUNK(&zl, j); if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY) continue; if (zc->l_entry.le_value_intlen != 8 || zc->l_entry.le_value_numints != 1) continue; if (fzap_leaf_value(&zl, zc) == value) { fzap_name_copy(&zl, zc, name); goto done; } } } rc = ENOENT; done: free(zl.l_phys); return (rc); } static int zap_rlookup(const spa_t *spa, const dnode_phys_t *dnode, char *name, uint64_t value) { zap_phys_t *zap; size_t size = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT; int rc; zap = malloc(size); if (zap == NULL) return (ENOMEM); rc = dnode_read(spa, dnode, 0, zap, size); if (rc == 0) { if (zap->zap_block_type == ZBT_MICRO) rc = mzap_rlookup((const mzap_phys_t *)zap, size, name, value); else rc = fzap_rlookup(spa, dnode, zap, name, value); } free(zap); return (rc); } static int zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) { char name[256]; char component[256]; uint64_t dir_obj, parent_obj, child_dir_zapobj; dnode_phys_t child_dir_zap, dataset, dir, parent; dsl_dir_phys_t *dd; dsl_dataset_phys_t *ds; char *p; int len; p = &name[sizeof (name) - 1]; *p = '\0'; if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) { printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum); return (EIO); } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; dir_obj = ds->ds_dir_obj; for (;;) { if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir) != 0) return (EIO); dd = (dsl_dir_phys_t *)&dir.dn_bonus; /* Actual loop condition. */ parent_obj = dd->dd_parent_obj; if (parent_obj == 0) break; if (objset_get_dnode(spa, &spa->spa_mos, parent_obj, &parent) != 0) return (EIO); dd = (dsl_dir_phys_t *)&parent.dn_bonus; child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) return (EIO); if (zap_rlookup(spa, &child_dir_zap, component, dir_obj) != 0) return (EIO); len = strlen(component); p -= len; memcpy(p, component, len); --p; *p = '/'; /* Actual loop iteration. */ dir_obj = parent_obj; } if (*p != '\0') ++p; strcpy(result, p); return (0); } static int zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum) { char element[256]; uint64_t dir_obj, child_dir_zapobj; dnode_phys_t child_dir_zap, dir; dsl_dir_phys_t *dd; const char *p, *q; if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) return (EIO); if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, sizeof (dir_obj), 1, &dir_obj)) return (EIO); p = name; for (;;) { if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir)) return (EIO); dd = (dsl_dir_phys_t *)&dir.dn_bonus; while (*p == '/') p++; /* Actual loop condition #1. */ if (*p == '\0') break; q = strchr(p, '/'); if (q) { memcpy(element, p, q - p); element[q - p] = '\0'; p = q + 1; } else { strcpy(element, p); p += strlen(p); } child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) return (EIO); /* Actual loop condition #2. */ if (zap_lookup(spa, &child_dir_zap, element, sizeof (dir_obj), 1, &dir_obj) != 0) return (ENOENT); } *objnum = dd->dd_head_dataset_obj; return (0); } #pragma GCC diagnostic ignored "-Wstrict-aliasing" static int zfs_list_dataset(const spa_t *spa, uint64_t objnum) { uint64_t dir_obj, child_dir_zapobj; dnode_phys_t child_dir_zap, dir, dataset; dsl_dataset_phys_t *ds; dsl_dir_phys_t *dd; if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) { printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum); return (EIO); } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; dir_obj = ds->ds_dir_obj; if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir)) { printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj); return (EIO); } dd = (dsl_dir_phys_t *)&dir.dn_bonus; child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) { printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj); return (EIO); } return (zap_list(spa, &child_dir_zap) != 0); } int zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *, uint64_t)) { uint64_t dir_obj, child_dir_zapobj; dnode_phys_t child_dir_zap, dir, dataset; dsl_dataset_phys_t *ds; dsl_dir_phys_t *dd; zap_phys_t *zap; size_t size; int err; err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset); if (err != 0) { printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum); return (err); } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; dir_obj = ds->ds_dir_obj; err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir); if (err != 0) { printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj); return (err); } dd = (dsl_dir_phys_t *)&dir.dn_bonus; child_dir_zapobj = dd->dd_child_dir_zapobj; err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap); if (err != 0) { printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj); return (err); } size = child_dir_zap.dn_datablkszsec << SPA_MINBLOCKSHIFT; zap = malloc(size); if (zap != NULL) { err = dnode_read(spa, &child_dir_zap, 0, zap, size); if (err != 0) goto done; if (zap->zap_block_type == ZBT_MICRO) err = mzap_list((const mzap_phys_t *)zap, size, callback); else err = fzap_list(spa, &child_dir_zap, zap, callback); } else { err = ENOMEM; } done: free(zap); return (err); } /* * Find the object set given the object number of its dataset object * and return its details in *objset */ static int zfs_mount_dataset(const spa_t *spa, uint64_t objnum, objset_phys_t *objset) { dnode_phys_t dataset; dsl_dataset_phys_t *ds; if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) { printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum); return (EIO); } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; if (zio_read(spa, &ds->ds_bp, objset)) { printf("ZFS: can't read object set for dataset %ju\n", (uintmax_t)objnum); return (EIO); } return (0); } /* * Find the object set pointed to by the BOOTFS property or the root * dataset if there is none and return its details in *objset */ static int zfs_get_root(const spa_t *spa, uint64_t *objid) { dnode_phys_t dir, propdir; uint64_t props, bootfs, root; *objid = 0; /* * Start with the MOS directory object. */ if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) { printf("ZFS: can't read MOS object directory\n"); return (EIO); } /* * Lookup the pool_props and see if we can find a bootfs. */ if (zap_lookup(spa, &dir, DMU_POOL_PROPS, sizeof (props), 1, &props) == 0 && objset_get_dnode(spa, &spa->spa_mos, props, &propdir) == 0 && zap_lookup(spa, &propdir, "bootfs", sizeof (bootfs), 1, &bootfs) == 0 && bootfs != 0) { *objid = bootfs; return (0); } /* * Lookup the root dataset directory */ if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, sizeof (root), 1, &root) || objset_get_dnode(spa, &spa->spa_mos, root, &dir)) { printf("ZFS: can't find root dsl_dir\n"); return (EIO); } /* * Use the information from the dataset directory's bonus buffer * to find the dataset object and from that the object set itself. */ dsl_dir_phys_t *dd = (dsl_dir_phys_t *)&dir.dn_bonus; *objid = dd->dd_head_dataset_obj; return (0); } static int zfs_mount(const spa_t *spa, uint64_t rootobj, struct zfsmount *mnt) { mnt->spa = spa; /* * Find the root object set if not explicitly provided */ if (rootobj == 0 && zfs_get_root(spa, &rootobj)) { printf("ZFS: can't find root filesystem\n"); return (EIO); } if (zfs_mount_dataset(spa, rootobj, &mnt->objset)) { printf("ZFS: can't open root filesystem\n"); return (EIO); } mnt->rootobj = rootobj; return (0); } /* * callback function for feature name checks. */ static int check_feature(const char *name, uint64_t value) { int i; if (value == 0) return (0); if (name[0] == '\0') return (0); for (i = 0; features_for_read[i] != NULL; i++) { if (strcmp(name, features_for_read[i]) == 0) return (0); } printf("ZFS: unsupported feature: %s\n", name); return (EIO); } /* * Checks whether the MOS features that are active are supported. */ static int check_mos_features(const spa_t *spa) { dnode_phys_t dir; zap_phys_t *zap; uint64_t objnum; size_t size; int rc; if ((rc = objset_get_dnode(spa, &spa->spa_mos, DMU_OT_OBJECT_DIRECTORY, &dir)) != 0) return (rc); if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ, sizeof (objnum), 1, &objnum)) != 0) { /* * It is older pool without features. As we have already * tested the label, just return without raising the error. */ if (rc == ENOENT) rc = 0; return (rc); } if ((rc = objset_get_dnode(spa, &spa->spa_mos, objnum, &dir)) != 0) return (rc); if (dir.dn_type != DMU_OTN_ZAP_METADATA) return (EIO); size = dir.dn_datablkszsec << SPA_MINBLOCKSHIFT; zap = malloc(size); if (zap == NULL) return (ENOMEM); if (dnode_read(spa, &dir, 0, zap, size)) { free(zap); return (EIO); } if (zap->zap_block_type == ZBT_MICRO) rc = mzap_list((const mzap_phys_t *)zap, size, check_feature); else rc = fzap_list(spa, &dir, zap, check_feature); free(zap); return (rc); } static int load_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value) { dnode_phys_t dir; size_t size; int rc; char *nv; *value = NULL; if ((rc = objset_get_dnode(spa, &spa->spa_mos, obj, &dir)) != 0) return (rc); if (dir.dn_type != DMU_OT_PACKED_NVLIST && dir.dn_bonustype != DMU_OT_PACKED_NVLIST_SIZE) { return (EIO); } if (dir.dn_bonuslen != sizeof (uint64_t)) return (EIO); size = *(uint64_t *)DN_BONUS(&dir); nv = malloc(size); if (nv == NULL) return (ENOMEM); rc = dnode_read(spa, &dir, 0, nv, size); if (rc != 0) { free(nv); nv = NULL; return (rc); } *value = nvlist_import(nv, size); free(nv); return (rc); } static int zfs_spa_init(spa_t *spa) { dnode_phys_t dir; uint64_t config_object; nvlist_t *nvlist; int rc; if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) { printf("ZFS: can't read MOS of pool %s\n", spa->spa_name); return (EIO); } if (spa->spa_mos.os_type != DMU_OST_META) { printf("ZFS: corrupted MOS of pool %s\n", spa->spa_name); return (EIO); } if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) { printf("ZFS: failed to read pool %s directory object\n", spa->spa_name); return (EIO); } /* this is allowed to fail, older pools do not have salt */ rc = zap_lookup(spa, &dir, DMU_POOL_CHECKSUM_SALT, 1, sizeof (spa->spa_cksum_salt.zcs_bytes), spa->spa_cksum_salt.zcs_bytes); rc = check_mos_features(spa); if (rc != 0) { printf("ZFS: pool %s is not supported\n", spa->spa_name); return (rc); } rc = zap_lookup(spa, &dir, DMU_POOL_CONFIG, sizeof (config_object), 1, &config_object); if (rc != 0) { printf("ZFS: can not read MOS %s\n", DMU_POOL_CONFIG); return (EIO); } rc = load_nvlist(spa, config_object, &nvlist); if (rc != 0) return (rc); /* * Update vdevs from MOS config. Note, we do skip encoding bytes * here. See also vdev_label_read_config(). */ rc = vdev_init_from_nvlist(spa, nvlist); nvlist_destroy(nvlist); return (rc); } static int zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb) { if (dn->dn_bonustype != DMU_OT_SA) { znode_phys_t *zp = (znode_phys_t *)dn->dn_bonus; sb->st_mode = zp->zp_mode; sb->st_uid = zp->zp_uid; sb->st_gid = zp->zp_gid; sb->st_size = zp->zp_size; } else { sa_hdr_phys_t *sahdrp; int hdrsize; size_t size = 0; void *buf = NULL; if (dn->dn_bonuslen != 0) sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn); else { if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0) { blkptr_t *bp = DN_SPILL_BLKPTR(dn); int error; size = BP_GET_LSIZE(bp); buf = malloc(size); if (buf == NULL) error = ENOMEM; else error = zio_read(spa, bp, buf); if (error != 0) { free(buf); return (error); } sahdrp = buf; } else { return (EIO); } } hdrsize = SA_HDR_SIZE(sahdrp); sb->st_mode = *(uint64_t *)((char *)sahdrp + hdrsize + SA_MODE_OFFSET); sb->st_uid = *(uint64_t *)((char *)sahdrp + hdrsize + SA_UID_OFFSET); sb->st_gid = *(uint64_t *)((char *)sahdrp + hdrsize + SA_GID_OFFSET); sb->st_size = *(uint64_t *)((char *)sahdrp + hdrsize + SA_SIZE_OFFSET); free(buf); } return (0); } static int zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn, char *path, size_t psize) { int rc = 0; if (dn->dn_bonustype == DMU_OT_SA) { sa_hdr_phys_t *sahdrp = NULL; size_t size = 0; void *buf = NULL; int hdrsize; char *p; if (dn->dn_bonuslen != 0) { sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn); } else { blkptr_t *bp; if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) == 0) return (EIO); bp = DN_SPILL_BLKPTR(dn); size = BP_GET_LSIZE(bp); buf = malloc(size); if (buf == NULL) rc = ENOMEM; else rc = zio_read(spa, bp, buf); if (rc != 0) { free(buf); return (rc); } sahdrp = buf; } hdrsize = SA_HDR_SIZE(sahdrp); p = (char *)((uintptr_t)sahdrp + hdrsize + SA_SYMLINK_OFFSET); memcpy(path, p, psize); free(buf); return (0); } /* * Second test is purely to silence bogus compiler * warning about accessing past the end of dn_bonus. */ if (psize + sizeof (znode_phys_t) <= dn->dn_bonuslen && sizeof (znode_phys_t) <= sizeof (dn->dn_bonus)) { memcpy(path, &dn->dn_bonus[sizeof (znode_phys_t)], psize); } else { rc = dnode_read(spa, dn, 0, path, psize); } return (rc); } struct obj_list { uint64_t objnum; STAILQ_ENTRY(obj_list) entry; }; /* * Lookup a file and return its dnode. */ static int zfs_lookup(const struct zfsmount *mnt, const char *upath, dnode_phys_t *dnode) { int rc; uint64_t objnum; const spa_t *spa; dnode_phys_t dn; const char *p, *q; char element[256]; char path[1024]; int symlinks_followed = 0; struct stat sb; struct obj_list *entry, *tentry; STAILQ_HEAD(, obj_list) on_cache = STAILQ_HEAD_INITIALIZER(on_cache); spa = mnt->spa; if (mnt->objset.os_type != DMU_OST_ZFS) { printf("ZFS: unexpected object set type %ju\n", (uintmax_t)mnt->objset.os_type); return (EIO); } if ((entry = malloc(sizeof (struct obj_list))) == NULL) return (ENOMEM); /* * Get the root directory dnode. */ rc = objset_get_dnode(spa, &mnt->objset, MASTER_NODE_OBJ, &dn); if (rc) { free(entry); return (rc); } rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, sizeof (objnum), 1, &objnum); if (rc) { free(entry); return (rc); } entry->objnum = objnum; STAILQ_INSERT_HEAD(&on_cache, entry, entry); rc = objset_get_dnode(spa, &mnt->objset, objnum, &dn); if (rc != 0) goto done; p = upath; while (p && *p) { rc = objset_get_dnode(spa, &mnt->objset, objnum, &dn); if (rc != 0) goto done; while (*p == '/') p++; if (*p == '\0') break; q = p; while (*q != '\0' && *q != '/') q++; /* skip dot */ if (p + 1 == q && p[0] == '.') { p++; continue; } /* double dot */ if (p + 2 == q && p[0] == '.' && p[1] == '.') { p += 2; if (STAILQ_FIRST(&on_cache) == STAILQ_LAST(&on_cache, obj_list, entry)) { rc = ENOENT; goto done; } entry = STAILQ_FIRST(&on_cache); STAILQ_REMOVE_HEAD(&on_cache, entry); free(entry); objnum = (STAILQ_FIRST(&on_cache))->objnum; continue; } if (q - p + 1 > sizeof (element)) { rc = ENAMETOOLONG; goto done; } memcpy(element, p, q - p); element[q - p] = 0; p = q; if ((rc = zfs_dnode_stat(spa, &dn, &sb)) != 0) goto done; if (!S_ISDIR(sb.st_mode)) { rc = ENOTDIR; goto done; } rc = zap_lookup(spa, &dn, element, sizeof (objnum), 1, &objnum); if (rc) goto done; objnum = ZFS_DIRENT_OBJ(objnum); if ((entry = malloc(sizeof (struct obj_list))) == NULL) { rc = ENOMEM; goto done; } entry->objnum = objnum; STAILQ_INSERT_HEAD(&on_cache, entry, entry); rc = objset_get_dnode(spa, &mnt->objset, objnum, &dn); if (rc) goto done; /* * Check for symlink. */ rc = zfs_dnode_stat(spa, &dn, &sb); if (rc) goto done; if (S_ISLNK(sb.st_mode)) { if (symlinks_followed > 10) { rc = EMLINK; goto done; } symlinks_followed++; /* * Read the link value and copy the tail of our * current path onto the end. */ if (sb.st_size + strlen(p) + 1 > sizeof (path)) { rc = ENAMETOOLONG; goto done; } strcpy(&path[sb.st_size], p); rc = zfs_dnode_readlink(spa, &dn, path, sb.st_size); if (rc != 0) goto done; /* * Restart with the new path, starting either at * the root or at the parent depending whether or * not the link is relative. */ p = path; if (*p == '/') { while (STAILQ_FIRST(&on_cache) != STAILQ_LAST(&on_cache, obj_list, entry)) { entry = STAILQ_FIRST(&on_cache); STAILQ_REMOVE_HEAD(&on_cache, entry); free(entry); } } else { entry = STAILQ_FIRST(&on_cache); STAILQ_REMOVE_HEAD(&on_cache, entry); free(entry); } objnum = (STAILQ_FIRST(&on_cache))->objnum; } } *dnode = dn; done: STAILQ_FOREACH_SAFE(entry, &on_cache, entry, tentry) free(entry); return (rc); } /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 * $FreeBSD$ */ #ifndef _MACHINE_ASM_H_ #define _MACHINE_ASM_H_ #include #ifdef PIC #define PIC_PLT(x) x@PLT #define PIC_GOT(x) x@GOTPCREL(%rip) #else #define PIC_PLT(x) x #endif /* * CNAME and HIDENAME manage the relationship between symbol names in C * and the equivalent assembly language names. CNAME is given a name as * it would be used in a C program. It expands to the equivalent assembly * language name. HIDENAME is given an assembly-language name, and expands * to a possibly-modified form that will be invisible to C programs. */ #define CNAME(csym) csym #define HIDENAME(asmsym) .asmsym #define _START_ENTRY .text; .p2align 4,0x90 #define _ENTRY(x) _START_ENTRY; \ .globl CNAME(x); .type CNAME(x),@function; CNAME(x): #ifdef PROF #define ALTENTRY(x) _ENTRY(x); \ pushq %rbp; movq %rsp,%rbp; \ call PIC_PLT(HIDENAME(mcount)); \ popq %rbp; \ jmp 9f #define ENTRY(x) _ENTRY(x); \ pushq %rbp; movq %rsp,%rbp; \ call PIC_PLT(HIDENAME(mcount)); \ popq %rbp; \ 9: #else #define ALTENTRY(x) _ENTRY(x) #define ENTRY(x) _ENTRY(x) #endif #define END(x) .size x, . - x /* * WEAK_REFERENCE(): create a weak reference alias from sym. * The macro is not a general asm macro that takes arbitrary names, * but one that takes only C names. It does the non-null name * translation inside the macro. */ #define WEAK_REFERENCE(sym, alias) \ .weak CNAME(alias); \ .equ CNAME(alias),CNAME(sym) #define RCSID(x) .text; .asciz x #undef __FBSDID #if !defined(lint) && !defined(STRIP_FBSDID) #define __FBSDID(s) .ident s #else #define __FBSDID(s) /* nothing */ #endif /* not lint and not STRIP_FBSDID */ #endif /* !_MACHINE_ASM_H_ */ /*- * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ #ifndef _MACHINE_ASMACROS_H_ #define _MACHINE_ASMACROS_H_ #include /* XXX too much duplication in various asm*.h's. */ /* * CNAME is used to manage the relationship between symbol names in C * and the equivalent assembly language names. CNAME is given a name as * it would be used in a C program. It expands to the equivalent assembly * language name. */ #define CNAME(csym) csym #define ALIGN_DATA .p2align 3 /* 8 byte alignment, zero filled */ #ifdef GPROF #define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ #else #define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ #endif #define SUPERALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ #define GEN_ENTRY(name) ALIGN_TEXT; .globl CNAME(name); \ .type CNAME(name),@function; CNAME(name): #define NON_GPROF_ENTRY(name) GEN_ENTRY(name) #define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */ #define END(name) .size name, . - name #ifdef GPROF /* * __mcount is like [.]mcount except that doesn't require its caller to set * up a frame pointer. It must be called before pushing anything onto the * stack. gcc should eventually generate code to call __mcount in most * cases. This would make -pg in combination with -fomit-frame-pointer * useful. gcc has a configuration variable PROFILE_BEFORE_PROLOGUE to * allow profiling before setting up the frame pointer, but this is * inadequate for good handling of special cases, e.g., -fpic works best * with profiling after the prologue. * * [.]mexitcount is a new function to support non-statistical profiling if an * accurate clock is available. For C sources, calls to it are generated * by the FreeBSD extension `-mprofiler-epilogue' to gcc. It is best to * call [.]mexitcount at the end of a function like the MEXITCOUNT macro does, * but gcc currently generates calls to it at the start of the epilogue to * avoid problems with -fpic. * * [.]mcount and __mcount may clobber the call-used registers and %ef. * [.]mexitcount may clobber %ecx and %ef. * * Cross-jumping makes non-statistical profiling timing more complicated. * It is handled in many cases by calling [.]mexitcount before jumping. It * is handled for conditional jumps using CROSSJUMP() and CROSSJUMP_LABEL(). * It is handled for some fault-handling jumps by not sharing the exit * routine. * * ALTENTRY() must be before a corresponding ENTRY() so that it can jump to * the main entry point. Note that alt entries are counted twice. They * have to be counted as ordinary entries for gprof to get the call times * right for the ordinary entries. * * High local labels are used in macros to avoid clashes with local labels * in functions. * * Ordinary `ret' is used instead of a macro `RET' because there are a lot * of `ret's. 0xc3 is the opcode for `ret' (`#define ret ... ret' can't * be used because this file is sometimes preprocessed in traditional mode). * `ret' clobbers eflags but this doesn't matter. */ #define ALTENTRY(name) GEN_ENTRY(name) ; MCOUNT ; MEXITCOUNT ; jmp 9f #define CROSSJUMP(jtrue, label, jfalse) \ jfalse 8f; MEXITCOUNT; jmp __CONCAT(to,label); 8: #define CROSSJUMPTARGET(label) \ ALIGN_TEXT; __CONCAT(to,label): ; MCOUNT; jmp label #define ENTRY(name) GEN_ENTRY(name) ; 9: ; MCOUNT #define FAKE_MCOUNT(caller) pushq caller ; call __mcount ; popq %rcx #define MCOUNT call __mcount #define MCOUNT_LABEL(name) GEN_ENTRY(name) ; nop ; ALIGN_TEXT #ifdef GUPROF #define MEXITCOUNT call .mexitcount #define ret MEXITCOUNT ; NON_GPROF_RET #else #define MEXITCOUNT #endif #else /* !GPROF */ /* * ALTENTRY() has to align because it is before a corresponding ENTRY(). * ENTRY() has to align to because there may be no ALTENTRY() before it. * If there is a previous ALTENTRY() then the alignment code for ENTRY() * is empty. */ #define ALTENTRY(name) GEN_ENTRY(name) #define CROSSJUMP(jtrue, label, jfalse) jtrue label #define CROSSJUMPTARGET(label) #define ENTRY(name) GEN_ENTRY(name) #define FAKE_MCOUNT(caller) #define MCOUNT #define MCOUNT_LABEL(name) #define MEXITCOUNT #endif /* GPROF */ /* * Convenience for adding frame pointers to hand-coded ASM. Useful for * DTrace, HWPMC, and KDB. */ #define PUSH_FRAME_POINTER \ pushq %rbp ; \ movq %rsp, %rbp ; #define POP_FRAME_POINTER \ popq %rbp #ifdef LOCORE /* * Convenience macro for declaring interrupt entry points. */ #define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \ .type __CONCAT(X,name),@function; __CONCAT(X,name): /* * Macros to create and destroy a trap frame. */ #define PUSH_FRAME \ subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \ testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \ jz 1f ; /* Yes, dont swapgs again */ \ swapgs ; \ 1: movq %rdi,TF_RDI(%rsp) ; \ movq %rsi,TF_RSI(%rsp) ; \ movq %rdx,TF_RDX(%rsp) ; \ movq %rcx,TF_RCX(%rsp) ; \ movq %r8,TF_R8(%rsp) ; \ movq %r9,TF_R9(%rsp) ; \ movq %rax,TF_RAX(%rsp) ; \ movq %rbx,TF_RBX(%rsp) ; \ movq %rbp,TF_RBP(%rsp) ; \ movq %r10,TF_R10(%rsp) ; \ movq %r11,TF_R11(%rsp) ; \ movq %r12,TF_R12(%rsp) ; \ movq %r13,TF_R13(%rsp) ; \ movq %r14,TF_R14(%rsp) ; \ movq %r15,TF_R15(%rsp) ; \ movw %fs,TF_FS(%rsp) ; \ movw %gs,TF_GS(%rsp) ; \ movw %es,TF_ES(%rsp) ; \ movw %ds,TF_DS(%rsp) ; \ movl $TF_HASSEGS,TF_FLAGS(%rsp) ; \ cld #define POP_FRAME \ movq TF_RDI(%rsp),%rdi ; \ movq TF_RSI(%rsp),%rsi ; \ movq TF_RDX(%rsp),%rdx ; \ movq TF_RCX(%rsp),%rcx ; \ movq TF_R8(%rsp),%r8 ; \ movq TF_R9(%rsp),%r9 ; \ movq TF_RAX(%rsp),%rax ; \ movq TF_RBX(%rsp),%rbx ; \ movq TF_RBP(%rsp),%rbp ; \ movq TF_R10(%rsp),%r10 ; \ movq TF_R11(%rsp),%r11 ; \ movq TF_R12(%rsp),%r12 ; \ movq TF_R13(%rsp),%r13 ; \ movq TF_R14(%rsp),%r14 ; \ movq TF_R15(%rsp),%r15 ; \ testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \ jz 1f ; /* keep kernel GS.base */ \ cli ; \ swapgs ; \ 1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */ /* * Access per-CPU data. */ #define PCPU(member) %gs:PC_ ## member #define PCPU_ADDR(member, reg) \ movq %gs:PC_PRVSPACE, reg ; \ addq $PC_ ## member, reg #endif /* LOCORE */ #ifdef __STDC__ #define ELFNOTE(name, type, desctype, descdata...) \ .pushsection .note.name ; \ .align 4 ; \ .long 2f - 1f /* namesz */ ; \ .long 4f - 3f /* descsz */ ; \ .long type ; \ 1:.asciz #name ; \ 2:.align 4 ; \ 3:desctype descdata ; \ 4:.align 4 ; \ .popsection #else /* !__STDC__, i.e. -traditional */ #define ELFNOTE(name, type, desctype, descdata) \ .pushsection .note.name ; \ .align 4 ; \ .long 2f - 1f /* namesz */ ; \ .long 4f - 3f /* descsz */ ; \ .long type ; \ 1:.asciz "name" ; \ 2:.align 4 ; \ 3:desctype descdata ; \ 4:.align 4 ; \ .popsection #endif /* __STDC__ */ #endif /* !_MACHINE_ASMACROS_H_ */ /*- * Copyright (c) 2003 Peter Wemm. * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ /* * Functions to provide access to special i386 instructions. * This in included in sys/systm.h, and that file should be * used in preference to this. */ #ifndef _MACHINE_CPUFUNC_H_ #define _MACHINE_CPUFUNC_H_ #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif struct region_descriptor; #define readb(va) (*(volatile uint8_t *) (va)) #define readw(va) (*(volatile uint16_t *) (va)) #define readl(va) (*(volatile uint32_t *) (va)) #define readq(va) (*(volatile uint64_t *) (va)) #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) #define writew(va, d) (*(volatile uint16_t *) (va) = (d)) #define writel(va, d) (*(volatile uint32_t *) (va) = (d)) #define writeq(va, d) (*(volatile uint64_t *) (va) = (d)) #if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) static __inline void breakpoint(void) { __asm __volatile("int $3"); } static __inline u_int bsfl(u_int mask) { u_int result; __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline u_long bsfq(u_long mask) { u_long result; __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline u_int bsrl(u_int mask) { u_int result; __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline u_long bsrq(u_long mask) { u_long result; __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline void clflush(u_long addr) { __asm __volatile("clflush %0" : : "m" (*(char *)addr)); } static __inline void clflushopt(u_long addr) { __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); } static __inline void clts(void) { __asm __volatile("clts"); } static __inline void disable_intr(void) { __asm __volatile("cli" : : : "memory"); } static __inline void do_cpuid(u_int ax, u_int *p) { __asm __volatile("cpuid" : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) : "0" (ax)); } static __inline void cpuid_count(u_int ax, u_int cx, u_int *p) { __asm __volatile("cpuid" : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) : "0" (ax), "c" (cx)); } static __inline void enable_intr(void) { __asm __volatile("sti"); } #ifdef _KERNEL #define HAVE_INLINE_FFS #define ffs(x) __builtin_ffs(x) #define HAVE_INLINE_FFSL static __inline int ffsl(long mask) { return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); } #define HAVE_INLINE_FFSLL static __inline int ffsll(long long mask) { return (ffsl((long)mask)); } #define HAVE_INLINE_FLS static __inline int fls(int mask) { return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); } #define HAVE_INLINE_FLSL static __inline int flsl(long mask) { return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); } #define HAVE_INLINE_FLSLL static __inline int flsll(long long mask) { return (flsl((long)mask)); } #endif /* _KERNEL */ static __inline void halt(void) { __asm __volatile("hlt"); } static __inline u_char inb(u_int port) { u_char data; __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline u_int inl(u_int port) { u_int data; __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline void insb(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insb" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void insw(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insw" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void insl(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insl" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void invd(void) { __asm __volatile("invd"); } static __inline u_short inw(u_int port) { u_short data; __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline void outb(u_int port, u_char data) { __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); } static __inline void outl(u_int port, u_int data) { __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); } static __inline void outsb(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsb" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outsw(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsw" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outsl(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsl" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outw(u_int port, u_short data) { __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); } static __inline u_long popcntq(u_long mask) { u_long result; __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline void lfence(void) { __asm __volatile("lfence" : : : "memory"); } static __inline void mfence(void) { __asm __volatile("mfence" : : : "memory"); } static __inline void sfence(void) { __asm __volatile("sfence" : : : "memory"); } static __inline void ia32_pause(void) { __asm __volatile("pause"); } static __inline u_long read_rflags(void) { u_long rf; __asm __volatile("pushfq; popq %0" : "=r" (rf)); return (rf); } static __inline uint64_t rdmsr(u_int msr) { uint32_t low, high; __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); return (low | ((uint64_t)high << 32)); } static __inline uint32_t rdmsr32(u_int msr) { uint32_t low; __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx"); return (low); } static __inline uint64_t rdpmc(u_int pmc) { uint32_t low, high; __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc)); return (low | ((uint64_t)high << 32)); } static __inline uint64_t rdtsc(void) { uint32_t low, high; __asm __volatile("rdtsc" : "=a" (low), "=d" (high)); return (low | ((uint64_t)high << 32)); } static __inline uint32_t rdtsc32(void) { uint32_t rv; __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); return (rv); } static __inline void wbinvd(void) { __asm __volatile("wbinvd"); } static __inline void write_rflags(u_long rf) { __asm __volatile("pushq %0; popfq" : : "r" (rf)); } static __inline void wrmsr(u_int msr, uint64_t newval) { uint32_t low, high; low = newval; high = newval >> 32; __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr)); } static __inline void load_cr0(u_long data) { __asm __volatile("movq %0,%%cr0" : : "r" (data)); } static __inline u_long rcr0(void) { u_long data; __asm __volatile("movq %%cr0,%0" : "=r" (data)); return (data); } static __inline u_long rcr2(void) { u_long data; __asm __volatile("movq %%cr2,%0" : "=r" (data)); return (data); } static __inline void load_cr3(u_long data) { __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory"); } static __inline u_long rcr3(void) { u_long data; __asm __volatile("movq %%cr3,%0" : "=r" (data)); return (data); } static __inline void load_cr4(u_long data) { __asm __volatile("movq %0,%%cr4" : : "r" (data)); } static __inline u_long rcr4(void) { u_long data; __asm __volatile("movq %%cr4,%0" : "=r" (data)); return (data); } static __inline u_long rxcr(u_int reg) { u_int low, high; __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); return (low | ((uint64_t)high << 32)); } static __inline void load_xcr(u_int reg, u_long val) { u_int low, high; low = val; high = val >> 32; __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); } /* * Global TLB flush (except for thise for pages marked PG_G) */ static __inline void invltlb(void) { load_cr3(rcr3()); } #ifndef CR4_PGE #define CR4_PGE 0x00000080 /* Page global enable */ #endif /* * Perform the guaranteed invalidation of all TLB entries. This * includes the global entries, and entries in all PCIDs, not only the * current context. The function works both on non-PCID CPUs and CPUs * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 * Operations that Invalidate TLBs and Paging-Structure Caches. */ static __inline void invltlb_glob(void) { uint64_t cr4; cr4 = rcr4(); load_cr4(cr4 & ~CR4_PGE); /* * Although preemption at this point could be detrimental to * performance, it would not lead to an error. PG_G is simply * ignored if CR4.PGE is clear. Moreover, in case this block * is re-entered, the load_cr4() either above or below will * modify CR4.PGE flushing the TLB. */ load_cr4(cr4 | CR4_PGE); } /* * TLB flush for an individual page (even if it has PG_G). * Only works on 486+ CPUs (i386 does not have PG_G). */ static __inline void invlpg(u_long addr) { __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); } #define INVPCID_ADDR 0 #define INVPCID_CTX 1 #define INVPCID_CTXGLOB 2 #define INVPCID_ALLCTX 3 struct invpcid_descr { uint64_t pcid:12 __packed; uint64_t pad:52 __packed; uint64_t addr; } __packed; static __inline void invpcid(struct invpcid_descr *d, int type) { __asm __volatile("invpcid (%0),%1" : : "r" (d), "r" ((u_long)type) : "memory"); } static __inline u_short rfs(void) { u_short sel; __asm __volatile("movw %%fs,%0" : "=rm" (sel)); return (sel); } static __inline u_short rgs(void) { u_short sel; __asm __volatile("movw %%gs,%0" : "=rm" (sel)); return (sel); } static __inline u_short rss(void) { u_short sel; __asm __volatile("movw %%ss,%0" : "=rm" (sel)); return (sel); } static __inline void load_ds(u_short sel) { __asm __volatile("movw %0,%%ds" : : "rm" (sel)); } static __inline void load_es(u_short sel) { __asm __volatile("movw %0,%%es" : : "rm" (sel)); } static __inline void cpu_monitor(const void *addr, u_long extensions, u_int hints) { __asm __volatile("monitor" : : "a" (addr), "c" (extensions), "d" (hints)); } static __inline void cpu_mwait(u_long extensions, u_int hints) { __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); } #ifdef _KERNEL /* This is defined in but is too painful to get to */ #ifndef MSR_FSBASE #define MSR_FSBASE 0xc0000100 #endif static __inline void load_fs(u_short sel) { /* Preserve the fsbase value across the selector load */ __asm __volatile("rdmsr; movw %0,%%fs; wrmsr" : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx"); } #ifndef MSR_GSBASE #define MSR_GSBASE 0xc0000101 #endif static __inline void load_gs(u_short sel) { /* * Preserve the gsbase value across the selector load. * Note that we have to disable interrupts because the gsbase * being trashed happens to be the kernel gsbase at the time. */ __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq" : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx"); } #else /* Usable by userland */ static __inline void load_fs(u_short sel) { __asm __volatile("movw %0,%%fs" : : "rm" (sel)); } static __inline void load_gs(u_short sel) { __asm __volatile("movw %0,%%gs" : : "rm" (sel)); } #endif static __inline void bare_lgdt(struct region_descriptor *addr) { __asm __volatile("lgdt (%0)" : : "r" (addr)); } static __inline void sgdt(struct region_descriptor *addr) { char *loc; loc = (char *)addr; __asm __volatile("sgdt %0" : "=m" (*loc) : : "memory"); } static __inline void lidt(struct region_descriptor *addr) { __asm __volatile("lidt (%0)" : : "r" (addr)); } static __inline void sidt(struct region_descriptor *addr) { char *loc; loc = (char *)addr; __asm __volatile("sidt %0" : "=m" (*loc) : : "memory"); } static __inline void lldt(u_short sel) { __asm __volatile("lldt %0" : : "r" (sel)); } static __inline void ltr(u_short sel) { __asm __volatile("ltr %0" : : "r" (sel)); } static __inline uint32_t read_tr(void) { u_short sel; __asm __volatile("str %0" : "=r" (sel)); return (sel); } static __inline uint64_t rdr0(void) { uint64_t data; __asm __volatile("movq %%dr0,%0" : "=r" (data)); return (data); } static __inline void load_dr0(uint64_t dr0) { __asm __volatile("movq %0,%%dr0" : : "r" (dr0)); } static __inline uint64_t rdr1(void) { uint64_t data; __asm __volatile("movq %%dr1,%0" : "=r" (data)); return (data); } static __inline void load_dr1(uint64_t dr1) { __asm __volatile("movq %0,%%dr1" : : "r" (dr1)); } static __inline uint64_t rdr2(void) { uint64_t data; __asm __volatile("movq %%dr2,%0" : "=r" (data)); return (data); } static __inline void load_dr2(uint64_t dr2) { __asm __volatile("movq %0,%%dr2" : : "r" (dr2)); } static __inline uint64_t rdr3(void) { uint64_t data; __asm __volatile("movq %%dr3,%0" : "=r" (data)); return (data); } static __inline void load_dr3(uint64_t dr3) { __asm __volatile("movq %0,%%dr3" : : "r" (dr3)); } static __inline uint64_t rdr6(void) { uint64_t data; __asm __volatile("movq %%dr6,%0" : "=r" (data)); return (data); } static __inline void load_dr6(uint64_t dr6) { __asm __volatile("movq %0,%%dr6" : : "r" (dr6)); } static __inline uint64_t rdr7(void) { uint64_t data; __asm __volatile("movq %%dr7,%0" : "=r" (data)); return (data); } static __inline void load_dr7(uint64_t dr7) { __asm __volatile("movq %0,%%dr7" : : "r" (dr7)); } static __inline register_t intr_disable(void) { register_t rflags; rflags = read_rflags(); disable_intr(); return (rflags); } static __inline void intr_restore(register_t rflags) { write_rflags(rflags); } #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ int breakpoint(void); u_int bsfl(u_int mask); u_int bsrl(u_int mask); void clflush(u_long addr); void clts(void); void cpuid_count(u_int ax, u_int cx, u_int *p); void disable_intr(void); void do_cpuid(u_int ax, u_int *p); void enable_intr(void); void halt(void); void ia32_pause(void); u_char inb(u_int port); u_int inl(u_int port); void insb(u_int port, void *addr, size_t count); void insl(u_int port, void *addr, size_t count); void insw(u_int port, void *addr, size_t count); register_t intr_disable(void); void intr_restore(register_t rf); void invd(void); void invlpg(u_int addr); void invltlb(void); u_short inw(u_int port); void lidt(struct region_descriptor *addr); void lldt(u_short sel); void load_cr0(u_long cr0); void load_cr3(u_long cr3); void load_cr4(u_long cr4); void load_dr0(uint64_t dr0); void load_dr1(uint64_t dr1); void load_dr2(uint64_t dr2); void load_dr3(uint64_t dr3); void load_dr6(uint64_t dr6); void load_dr7(uint64_t dr7); void load_fs(u_short sel); void load_gs(u_short sel); void ltr(u_short sel); void outb(u_int port, u_char data); void outl(u_int port, u_int data); void outsb(u_int port, const void *addr, size_t count); void outsl(u_int port, const void *addr, size_t count); void outsw(u_int port, const void *addr, size_t count); void outw(u_int port, u_short data); u_long rcr0(void); u_long rcr2(void); u_long rcr3(void); u_long rcr4(void); uint64_t rdmsr(u_int msr); uint32_t rdmsr32(u_int msr); uint64_t rdpmc(u_int pmc); uint64_t rdr0(void); uint64_t rdr1(void); uint64_t rdr2(void); uint64_t rdr3(void); uint64_t rdr6(void); uint64_t rdr7(void); uint64_t rdtsc(void); u_long read_rflags(void); u_int rfs(void); u_int rgs(void); void wbinvd(void); void write_rflags(u_int rf); void wrmsr(u_int msr, uint64_t newval); #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ void reset_dbregs(void); #ifdef _KERNEL int rdmsr_safe(u_int msr, uint64_t *val); int wrmsr_safe(u_int msr, uint64_t newval); #endif #endif /* !_MACHINE_CPUFUNC_H_ */ /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)exec.h 8.1 (Berkeley) 6/11/93 * $FreeBSD$ */ #ifndef _MACHINE_EXEC_H_ #define _MACHINE_EXEC_H_ #define __LDPGSZ 4096 #endif /* !_MACHINE_EXEC_H_ */ /*- * This file is in the public domain. */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * Copyright (c) 2002 David E. O'Brien. All rights reserved. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department and Ralph Campbell. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)param.h 8.1 (Berkeley) 6/10/93 * $FreeBSD$ */ #ifndef _AMD64_INCLUDE_PARAM_H_ #define _AMD64_INCLUDE_PARAM_H_ #include /* * Machine dependent constants for AMD64. */ #define __HAVE_ACPI #define __PCI_REROUTE_INTERRUPT #ifndef MACHINE #define MACHINE "amd64" #endif #ifndef MACHINE_ARCH #define MACHINE_ARCH "amd64" #endif #ifndef MACHINE_ARCH32 #define MACHINE_ARCH32 "i386" #endif #if defined(SMP) || defined(KLD_MODULE) #ifndef MAXCPU #define MAXCPU 256 #endif #else #define MAXCPU 1 #endif #ifndef MAXMEMDOM #define MAXMEMDOM 1 #endif #define ALIGNBYTES _ALIGNBYTES #define ALIGN(p) _ALIGN(p) /* * ALIGNED_POINTER is a boolean macro that checks whether an address * is valid to fetch data elements of type t from on this architecture. * This does not reflect the optimal alignment, just the possibility * (within reasonable limits). */ #define ALIGNED_POINTER(p, t) 1 /* * CACHE_LINE_SIZE is the compile-time maximum cache line size for an * architecture. It should be used with appropriate caution. */ #define CACHE_LINE_SHIFT 7 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) /* Size of the level 1 page table units */ #define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t))) #define NPTEPGSHIFT 9 /* LOG2(NPTEPG) */ #define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ #define PAGE_SIZE (1<> PAGE_SHIFT) #define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) #define amd64_btop(x) ((unsigned long)(x) >> PAGE_SHIFT) #define amd64_ptob(x) ((unsigned long)(x) << PAGE_SHIFT) #define pgtok(x) ((unsigned long)(x) * (PAGE_SIZE / 1024)) #define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ || ((va) >= VM_MIN_KERNEL_ADDRESS && (va) < VM_MAX_KERNEL_ADDRESS)) #endif /* !_AMD64_INCLUDE_PARAM_H_ */ /*- * Copyright (c) 1997 Michael Smith * Copyright (c) 1998 Jonathan Lemon * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _MACHINE_PC_BIOS_H_ #define _MACHINE_PC_BIOS_H_ /* * Int 15:E820 'SMAP' structure */ #define SMAP_SIG 0x534D4150 /* 'SMAP' */ #define SMAP_TYPE_MEMORY 1 #define SMAP_TYPE_RESERVED 2 #define SMAP_TYPE_ACPI_RECLAIM 3 #define SMAP_TYPE_ACPI_NVS 4 #define SMAP_TYPE_ACPI_ERROR 5 #define SMAP_XATTR_ENABLED 0x00000001 #define SMAP_XATTR_NON_VOLATILE 0x00000002 #define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE) struct bios_smap { u_int64_t base; u_int64_t length; u_int32_t type; } __packed; /* Structure extended to include extended attribute field in ACPI 3.0. */ struct bios_smap_xattr { u_int64_t base; u_int64_t length; u_int32_t type; u_int32_t xattr; } __packed; /* * System Management BIOS */ #define SMBIOS_START 0xf0000 #define SMBIOS_STEP 0x10 #define SMBIOS_OFF 0 #define SMBIOS_LEN 4 #define SMBIOS_SIG "_SM_" struct smbios_eps { uint8_t anchor_string[4]; /* '_SM_' */ uint8_t checksum; uint8_t length; uint8_t major_version; uint8_t minor_version; uint16_t maximum_structure_size; uint8_t entry_point_revision; uint8_t formatted_area[5]; uint8_t intermediate_anchor_string[5]; /* '_DMI_' */ uint8_t intermediate_checksum; uint16_t structure_table_length; uint32_t structure_table_address; uint16_t number_structures; uint8_t BCD_revision; }; struct smbios_structure_header { uint8_t type; uint8_t length; uint16_t handle; }; #ifdef _KERNEL #define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE) #define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE) struct bios_oem_signature { char * anchor; /* search anchor string in BIOS memory */ size_t offset; /* offset from anchor (may be negative) */ size_t totlen; /* total length of BIOS string to copy */ } __packed; struct bios_oem_range { u_int from; /* shouldn't be below 0xe0000 */ u_int to; /* shouldn't be above 0xfffff */ } __packed; struct bios_oem { struct bios_oem_range range; struct bios_oem_signature signature[]; } __packed; int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen); uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen, int sigofs); void bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize, vm_paddr_t *physmap, int *physmap_idx); #endif #endif /* _MACHINE_PC_BIOS_H_ */ /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * Copyright (c) 1989, 1990 William F. Jolitz * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 */ #ifndef _MACHINE_SEGMENTS_H_ #define _MACHINE_SEGMENTS_H_ /* * AMD64 Segmentation Data Structures and definitions */ #include /* * System segment descriptors (128 bit wide) */ struct system_segment_descriptor { u_int64_t sd_lolimit:16; /* segment extent (lsb) */ u_int64_t sd_lobase:24; /* segment base address (lsb) */ u_int64_t sd_type:5; /* segment type */ u_int64_t sd_dpl:2; /* segment descriptor priority level */ u_int64_t sd_p:1; /* segment descriptor present */ u_int64_t sd_hilimit:4; /* segment extent (msb) */ u_int64_t sd_xx0:3; /* unused */ u_int64_t sd_gran:1; /* limit granularity (byte/page units)*/ u_int64_t sd_hibase:40 __packed;/* segment base address (msb) */ u_int64_t sd_xx1:8; u_int64_t sd_mbz:5; /* MUST be zero */ u_int64_t sd_xx2:19; } __packed; /* * Software definitions are in this convenient format, * which are translated into inconvenient segment descriptors * when needed to be used by the 386 hardware */ struct soft_segment_descriptor { unsigned long ssd_base; /* segment base address */ unsigned long ssd_limit; /* segment extent */ unsigned long ssd_type:5; /* segment type */ unsigned long ssd_dpl:2; /* segment descriptor priority level */ unsigned long ssd_p:1; /* segment descriptor present */ unsigned long ssd_long:1; /* long mode (for %cs) */ unsigned long ssd_def32:1; /* default 32 vs 16 bit size */ unsigned long ssd_gran:1; /* limit granularity (byte/page units)*/ } __packed; /* * region descriptors, used to load gdt/idt tables before segments yet exist. */ struct region_descriptor { uint64_t rd_limit:16; /* segment extent */ uint64_t rd_base:64 __packed; /* base address */ } __packed; #ifdef _KERNEL extern struct user_segment_descriptor gdt[]; extern struct soft_segment_descriptor gdt_segs[]; extern struct gate_descriptor *idt; extern struct region_descriptor r_gdt, r_idt; void lgdt(struct region_descriptor *rdp); void sdtossd(struct user_segment_descriptor *sdp, struct soft_segment_descriptor *ssdp); void ssdtosd(struct soft_segment_descriptor *ssdp, struct user_segment_descriptor *sdp); void ssdtosyssd(struct soft_segment_descriptor *ssdp, struct system_segment_descriptor *sdp); void update_gdt_gsbase(struct thread *td, uint32_t base); void update_gdt_fsbase(struct thread *td, uint32_t base); #endif /* _KERNEL */ #endif /* !_MACHINE_SEGMENTS_H_ */ /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * This file is in the public domain. */ /* $FreeBSD$ */ #include /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)tss.h 5.4 (Berkeley) 1/18/91 */ #ifndef _MACHINE_TSS_H_ #define _MACHINE_TSS_H_ 1 /* * amd64 Context Data Type * * The alignment is pretty messed up here due to reuse of the original 32 bit * fields. It might be worth trying to set the tss on a +4 byte offset to * make the 64 bit fields aligned in practice. */ struct amd64tss { u_int32_t tss_rsvd0; u_int64_t tss_rsp0 __packed; /* kernel stack pointer ring 0 */ u_int64_t tss_rsp1 __packed; /* kernel stack pointer ring 1 */ u_int64_t tss_rsp2 __packed; /* kernel stack pointer ring 2 */ u_int32_t tss_rsvd1; u_int32_t tss_rsvd2; u_int64_t tss_ist1 __packed; /* Interrupt stack table 1 */ u_int64_t tss_ist2 __packed; /* Interrupt stack table 2 */ u_int64_t tss_ist3 __packed; /* Interrupt stack table 3 */ u_int64_t tss_ist4 __packed; /* Interrupt stack table 4 */ u_int64_t tss_ist5 __packed; /* Interrupt stack table 5 */ u_int64_t tss_ist6 __packed; /* Interrupt stack table 6 */ u_int64_t tss_ist7 __packed; /* Interrupt stack table 7 */ u_int32_t tss_rsvd3; u_int32_t tss_rsvd4; u_int16_t tss_rsvd5; u_int16_t tss_iobase; /* io bitmap offset */ }; #ifdef _KERNEL extern struct amd64tss common_tss[]; #endif #endif /* _MACHINE_TSS_H_ */ $FreeBSD$ This directory contains various files derived from CDDL sources that are used by the ZFS bootstrap: fletcher.c checksum support sha256.c checksum support lz4.c compression support lzjb.c compression support blkptr.c ZFS embedded-data block pointers support zfssubr.c checksum, compression and raidz support zfsimpl.h mostly describing the physical layout The files fletcher.c, lzjb.c, lz4.c, sha256.c and blkptr.c are largely identical to the ZFS base code (with write support removed) and could be shared but that might complicate future imports from Illumos. /* * CDDL HEADER START * * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. * * CDDL HEADER END */ /* * Copyright (c) 2013 by Delphix. All rights reserved. */ /* * Embedded-data Block Pointers * * Normally, block pointers point (via their DVAs) to a block which holds data. * If the data that we need to store is very small, this is an inefficient * use of space, because a block must be at minimum 1 sector (typically 512 * bytes or 4KB). Additionally, reading these small blocks tends to generate * more random reads. * * Embedded-data Block Pointers allow small pieces of data (the "payload", * up to 112 bytes) to be stored in the block pointer itself, instead of * being pointed to. The "Pointer" part of this name is a bit of a * misnomer, as nothing is pointed to. * * BP_EMBEDDED_TYPE_DATA block pointers allow highly-compressible data to * be embedded in the block pointer. The logic for this is handled in * the SPA, by the zio pipeline. Therefore most code outside the zio * pipeline doesn't need special-cases to handle these block pointers. * * See spa.h for details on the exact layout of embedded block pointers. */ /* * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be * more than BPE_PAYLOAD_SIZE bytes). */ void decode_embedded_bp_compressed(const blkptr_t *bp, void *buf) { int psize; uint8_t *buf8 = buf; uint64_t w = 0; const uint64_t *bp64 = (const uint64_t *)bp; ASSERT(BP_IS_EMBEDDED(bp)); psize = BPE_GET_PSIZE(bp); /* * Decode the words of the block pointer into the byte array. * Low bits of first word are the first byte (little endian). */ for (int i = 0; i < psize; i++) { if (i % sizeof (w) == 0) { /* beginning of a word */ ASSERT3P(bp64, <, bp + 1); w = *bp64; bp64++; if (!BPE_IS_PAYLOADWORD(bp, bp64)) bp64++; } buf8[i] = BF64_GET(w, (i % sizeof (w)) * NBBY, NBBY); } } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://opensource.org/licenses/CDDL-1.0. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2013 Saso Kiselkov. All rights reserved. * Use is subject to license terms. */ #include #define EDONR_MODE 512 #define EDONR_BLOCK_SIZE EdonR512_BLOCK_SIZE /* * Native zio_checksum interface for the Edon-R hash function. */ /*ARGSUSED*/ static void zio_checksum_edonr_native(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { uint8_t digest[EDONR_MODE / 8]; EdonRState ctx; ASSERT(ctx_template != NULL); bcopy(ctx_template, &ctx, sizeof (ctx)); EdonRUpdate(&ctx, buf, size * 8); EdonRFinal(&ctx, digest); bcopy(digest, zcp->zc_word, sizeof (zcp->zc_word)); } /* * Byteswapped zio_checksum interface for the Edon-R hash function. */ static void zio_checksum_edonr_byteswap(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { zio_cksum_t tmp; zio_checksum_edonr_native(buf, size, ctx_template, &tmp); zcp->zc_word[0] = BSWAP_64(zcp->zc_word[0]); zcp->zc_word[1] = BSWAP_64(zcp->zc_word[1]); zcp->zc_word[2] = BSWAP_64(zcp->zc_word[2]); zcp->zc_word[3] = BSWAP_64(zcp->zc_word[3]); } static void * zio_checksum_edonr_tmpl_init(const zio_cksum_salt_t *salt) { EdonRState *ctx; uint8_t salt_block[EDONR_BLOCK_SIZE]; /* * Edon-R needs all but the last hash invocation to be on full-size * blocks, but the salt is too small. Rather than simply padding it * with zeros, we expand the salt into a new salt block of proper * size by double-hashing it (the new salt block will be composed of * H(salt) || H(H(salt))). */ EdonRHash(EDONR_MODE, salt->zcs_bytes, sizeof (salt->zcs_bytes) * 8, salt_block); EdonRHash(EDONR_MODE, salt_block, EDONR_MODE, salt_block + EDONR_MODE / 8); /* * Feed the new salt block into the hash function - this will serve * as our MAC key. */ ctx = malloc(sizeof (*ctx)); bzero(ctx, sizeof (*ctx)); EdonRInit(ctx, EDONR_MODE); EdonRUpdate(ctx, salt_block, sizeof (salt_block) * 8); return (ctx); } static void zio_checksum_edonr_tmpl_free(void *ctx_template) { EdonRState *ctx = ctx_template; bzero(ctx, sizeof (*ctx)); free(ctx); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ static void fletcher_2_native(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { const uint64_t *ip = buf; const uint64_t *ipend = ip + (size / sizeof (uint64_t)); uint64_t a0, b0, a1, b1; for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) { a0 += ip[0]; a1 += ip[1]; b0 += a0; b1 += a1; } ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1); } static void fletcher_2_byteswap(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { const uint64_t *ip = buf; const uint64_t *ipend = ip + (size / sizeof (uint64_t)); uint64_t a0, b0, a1, b1; for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) { a0 += BSWAP_64(ip[0]); a1 += BSWAP_64(ip[1]); b0 += a0; b1 += a1; } ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1); } static void fletcher_4_native(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { const uint32_t *ip = buf; const uint32_t *ipend = ip + (size / sizeof (uint32_t)); uint64_t a, b, c, d; for (a = b = c = d = 0; ip < ipend; ip++) { a += ip[0]; b += a; c += b; d += c; } ZIO_SET_CHECKSUM(zcp, a, b, c, d); } static void fletcher_4_byteswap(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { const uint32_t *ip = buf; const uint32_t *ipend = ip + (size / sizeof (uint32_t)); uint64_t a, b, c, d; for (a = b = c = d = 0; ip < ipend; ip++) { a += BSWAP_32(ip[0]); b += a; c += b; d += c; } ZIO_SET_CHECKSUM(zcp, a, b, c, d); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * We keep our own copy of this algorithm for 2 main reasons: * 1. If we didn't, anyone modifying common/os/compress.c would * directly break our on disk format * 2. Our version of lzjb does not have a number of checks that the * common/os version needs and uses * In particular, we are adding the "feature" that compress() can * take a destination buffer size and return -1 if the data will not * compress to d_len or less. */ #define MATCH_BITS 6 #define MATCH_MIN 3 #define MATCH_MAX ((1 << MATCH_BITS) + (MATCH_MIN - 1)) #define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) #define LEMPEL_SIZE 256 /*ARGSUSED*/ static int lzjb_decompress(void *s_start, void *d_start, size_t s_len __unused, size_t d_len, int n __unused) { unsigned char *src = s_start; unsigned char *dst = d_start; unsigned char *d_end = (unsigned char *)d_start + d_len; unsigned char *cpy, copymap = 0; int copymask = 1 << (NBBY - 1); while (dst < d_end) { if ((copymask <<= 1) == (1 << NBBY)) { copymask = 1; copymap = *src++; } if (copymap & copymask) { int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; src += 2; if ((cpy = dst - offset) < (unsigned char *)d_start) return (-1); while (--mlen >= 0 && dst < d_end) *dst++ = *cpy++; } else { *dst++ = *src++; } } return (0); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright 2013 Saso Kiselkov. All rights reserved. * Copyright 2015 Toomas Soome */ /* * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at: * http://csrc.nist.gov/cryptval * * This is a very compact implementation of SHA-256 and SHA-512/256. * It is designed to be simple and portable, not to be fast. */ /* * The literal definitions according to FIPS180-4 would be: * * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) * * We use logical equivalents which require one less op. */ #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) #define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n)))) /* SHA-224/256 operations */ #define BIGSIGMA0_256(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define BIGSIGMA1_256(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define SIGMA0_256(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3)) #define SIGMA1_256(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10)) /* SHA-384/512 operations */ #define BIGSIGMA0_512(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39)) #define BIGSIGMA1_512(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41)) #define SIGMA0_512(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7)) #define SIGMA1_512(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6)) /* SHA-256 round constants */ static const uint32_t SHA256_K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; /* SHA-512 round constants */ static const uint64_t SHA512_K[80] = { 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL, 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL, 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL, 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL, 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL, 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL, 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL, 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL, 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL, 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL, 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL, 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL, 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL, 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL, 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL, 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL, 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL, 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL, 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL, 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL, 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL }; static void SHA256Transform(uint32_t *H, const uint8_t *cp) { uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; /* copy chunk into the first 16 words of the message schedule */ for (t = 0; t < 16; t++, cp += sizeof (uint32_t)) W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; /* extend the first 16 words into the remaining 48 words */ for (t = 16; t < 64; t++) W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] + SIGMA0_256(W[t - 15]) + W[t - 16]; /* init working variables to the current hash value */ a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; /* iterate the compression function for all rounds of the hash */ for (t = 0; t < 64; t++) { T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; T2 = BIGSIGMA0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } /* add the compressed chunk to the current hash value */ H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; } static void SHA512Transform(uint64_t *H, const uint8_t *cp) { uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80]; /* copy chunk into the first 16 words of the message schedule */ for (t = 0; t < 16; t++, cp += sizeof (uint64_t)) W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) | ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) | ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) | ((uint64_t)cp[6] << 8) | (uint64_t)cp[7]; /* extend the first 16 words into the remaining 64 words */ for (t = 16; t < 80; t++) W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] + SIGMA0_512(W[t - 15]) + W[t - 16]; /* init working variables to the current hash value */ a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; /* iterate the compression function for all rounds of the hash */ for (t = 0; t < 80; t++) { T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t]; T2 = BIGSIGMA0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } /* add the compressed chunk to the current hash value */ H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; } /* * Implements the SHA-224 and SHA-256 hash algos - to select between them * pass the appropriate initial values of 'H' and truncate the last 32 bits * in case of SHA-224. */ static void SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp) { uint8_t pad[128]; unsigned padsize = size & 63; unsigned i, k; /* process all blocks up to the last one */ for (i = 0; i < size - padsize; i += 64) SHA256Transform(H, (uint8_t *)buf + i); /* process the last block and padding */ for (k = 0; k < padsize; k++) pad[k] = ((uint8_t *)buf)[k+i]; for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) pad[padsize] = 0; for (i = 0; i < 8; i++) pad[padsize++] = (size << 3) >> (56 - 8 * i); for (i = 0; i < padsize; i += 64) SHA256Transform(H, pad + i); ZIO_SET_CHECKSUM(zcp, (uint64_t)H[0] << 32 | H[1], (uint64_t)H[2] << 32 | H[3], (uint64_t)H[4] << 32 | H[5], (uint64_t)H[6] << 32 | H[7]); } /* * encode 64bit data in big-endian format. */ static void Encode64(uint8_t *output, uint64_t *input, size_t len) { size_t i, j; for (i = 0, j = 0; j < len; i++, j += 8) { output[j] = (input[i] >> 56) & 0xff; output[j + 1] = (input[i] >> 48) & 0xff; output[j + 2] = (input[i] >> 40) & 0xff; output[j + 3] = (input[i] >> 32) & 0xff; output[j + 4] = (input[i] >> 24) & 0xff; output[j + 5] = (input[i] >> 16) & 0xff; output[j + 6] = (input[i] >> 8) & 0xff; output[j + 7] = input[i] & 0xff; } } /* * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select * between them pass the appropriate initial values for 'H'. The output * of this function is truncated to the first 256 bits that fit into 'zcp'. */ static void SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp) { uint64_t c64[2]; uint8_t pad[256]; unsigned padsize = size & 127; unsigned i, k; /* process all blocks up to the last one */ for (i = 0; i < size - padsize; i += 128) SHA512Transform(H, (uint8_t *)buf + i); /* process the last block and padding */ for (k = 0; k < padsize; k++) pad[k] = ((uint8_t *)buf)[k+i]; if (padsize < 112) { for (pad[padsize++] = 0x80; padsize < 112; padsize++) pad[padsize] = 0; } else { for (pad[padsize++] = 0x80; padsize < 240; padsize++) pad[padsize] = 0; } c64[0] = 0; c64[1] = size << 3; Encode64(pad+padsize, c64, sizeof (c64)); padsize += sizeof (c64); for (i = 0; i < padsize; i += 128) SHA512Transform(H, pad + i); /* truncate the output to the first 256 bits which fit into 'zcp' */ Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4); } static void zio_checksum_SHA256(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { /* SHA-256 as per FIPS 180-4. */ uint32_t H[] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; SHA256(H, buf, size, zcp); } static void zio_checksum_SHA512_native(const void *buf, uint64_t size, const void *ctx_template __unused, zio_cksum_t *zcp) { /* SHA-512/256 as per FIPS 180-4. */ uint64_t H[] = { 0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL, 0x2393B86B6F53B151ULL, 0x963877195940EABDULL, 0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL, 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL }; SHA512(H, buf, size, zcp); } static void zio_checksum_SHA512_byteswap(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { zio_cksum_t tmp; zio_checksum_SHA512_native(buf, size, ctx_template, &tmp); zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]); zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]); zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]); zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://opensource.org/licenses/CDDL-1.0. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2013 Saso Kiselkov. All rights reserved. */ #include /* * Computes a native 256-bit skein MAC checksum. Please note that this * function requires the presence of a ctx_template that should be allocated * using zio_checksum_skein_tmpl_init. */ /*ARGSUSED*/ static void zio_checksum_skein_native(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { Skein_512_Ctxt_t ctx; ASSERT(ctx_template != NULL); bcopy(ctx_template, &ctx, sizeof (ctx)); (void) Skein_512_Update(&ctx, buf, size); (void) Skein_512_Final(&ctx, (uint8_t *)zcp); bzero(&ctx, sizeof (ctx)); } /* * Byteswapped version of zio_checksum_skein_native. This just invokes * the native checksum function and byteswaps the resulting checksum (since * skein is internally endian-insensitive). */ static void zio_checksum_skein_byteswap(const void *buf, uint64_t size, const void *ctx_template, zio_cksum_t *zcp) { zio_cksum_t tmp; zio_checksum_skein_native(buf, size, ctx_template, &tmp); zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]); zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]); zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]); zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]); } /* * Allocates a skein MAC template suitable for using in skein MAC checksum * computations and returns a pointer to it. */ static void * zio_checksum_skein_tmpl_init(const zio_cksum_salt_t *salt) { Skein_512_Ctxt_t *ctx; ctx = malloc(sizeof (*ctx)); bzero(ctx, sizeof (*ctx)); (void) Skein_512_InitExt(ctx, sizeof (zio_cksum_t) * 8, 0, salt->zcs_bytes, sizeof (salt->zcs_bytes)); return (ctx); } /* * Frees a skein context template previously allocated using * zio_checksum_skein_tmpl_init. */ static void zio_checksum_skein_tmpl_free(void *ctx_template) { Skein_512_Ctxt_t *ctx = ctx_template; bzero(ctx, sizeof (*ctx)); free(ctx); } /* * Copyright (c) 2002 McAfee, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Marshall * Kirk McKusick and McAfee Research,, the Security Research Division of * McAfee, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as * part of the DARPA CHATS research program * * 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. * * 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. */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright 2013 by Saso Kiselkov. All rights reserved. */ /* * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _ZFSIMPL_H_ #define _ZFSIMPL_H_ #include #include #include #define MAXNAMELEN 256 #define _NOTE(s) /* * AVL comparator helpers */ #define AVL_ISIGN(a) (((a) > 0) - ((a) < 0)) #define AVL_CMP(a, b) (((a) > (b)) - ((a) < (b))) #define AVL_PCMP(a, b) \ (((uintptr_t)(a) > (uintptr_t)(b)) - ((uintptr_t)(a) < (uintptr_t)(b))) /* CRC64 table */ #define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ /* * Macros for various sorts of alignment and rounding when the alignment * is known to be a power of 2. */ #define P2ALIGN(x, align) ((x) & -(align)) #define P2PHASE(x, align) ((x) & ((align) - 1)) #define P2NPHASE(x, align) (-(x) & ((align) - 1)) #define P2ROUNDUP(x, align) (-(-(x) & -(align))) #define P2END(x, align) (-(~(x) & -(align))) #define P2PHASEUP(x, align, phase) ((phase) - (((phase) - (x)) & -(align))) #define P2BOUNDARY(off, len, align) \ (((off) ^ ((off) + (len) - 1)) > (align) - 1) /* * General-purpose 32-bit and 64-bit bitfield encodings. */ #define BF32_DECODE(x, low, len) P2PHASE((x) >> (low), 1U << (len)) #define BF64_DECODE(x, low, len) P2PHASE((x) >> (low), 1ULL << (len)) #define BF32_ENCODE(x, low, len) (P2PHASE((x), 1U << (len)) << (low)) #define BF64_ENCODE(x, low, len) (P2PHASE((x), 1ULL << (len)) << (low)) #define BF32_GET(x, low, len) BF32_DECODE(x, low, len) #define BF64_GET(x, low, len) BF64_DECODE(x, low, len) #define BF32_SET(x, low, len, val) \ ((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len)) #define BF64_SET(x, low, len, val) \ ((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len)) #define BF32_GET_SB(x, low, len, shift, bias) \ ((BF32_GET(x, low, len) + (bias)) << (shift)) #define BF64_GET_SB(x, low, len, shift, bias) \ ((BF64_GET(x, low, len) + (bias)) << (shift)) #define BF32_SET_SB(x, low, len, shift, bias, val) \ BF32_SET(x, low, len, ((val) >> (shift)) - (bias)) #define BF64_SET_SB(x, low, len, shift, bias, val) \ BF64_SET(x, low, len, ((val) >> (shift)) - (bias)) /* * Macros to reverse byte order */ #define BSWAP_8(x) ((x) & 0xff) #define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) #define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) #define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32)) #define SPA_MINBLOCKSHIFT 9 #define SPA_OLDMAXBLOCKSHIFT 17 #define SPA_MAXBLOCKSHIFT 24 #define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) #define SPA_OLDMAXBLOCKSIZE (1ULL << SPA_OLDMAXBLOCKSHIFT) #define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) /* * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. * The ASIZE encoding should be at least 64 times larger (6 more bits) * to support up to 4-way RAID-Z mirror mode with worst-case gang block * overhead, three DVAs per bp, plus one more bit in case we do anything * else that expands the ASIZE. */ #define SPA_LSIZEBITS 16 /* LSIZE up to 32M (2^16 * 512) */ #define SPA_PSIZEBITS 16 /* PSIZE up to 32M (2^16 * 512) */ #define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */ /* * All SPA data is represented by 128-bit data virtual addresses (DVAs). * The members of the dva_t should be considered opaque outside the SPA. */ typedef struct dva { uint64_t dva_word[2]; } dva_t; /* * Each block has a 256-bit checksum -- strong enough for cryptographic hashes. */ typedef struct zio_cksum { uint64_t zc_word[4]; } zio_cksum_t; /* * Some checksums/hashes need a 256-bit initialization salt. This salt is kept * secret and is suitable for use in MAC algorithms as the key. */ typedef struct zio_cksum_salt { uint8_t zcs_bytes[32]; } zio_cksum_salt_t; /* * Each block is described by its DVAs, time of birth, checksum, etc. * The word-by-word, bit-by-bit layout of the blkptr is as follows: * * 64 56 48 40 32 24 16 8 0 * +-------+-------+-------+-------+-------+-------+-------+-------+ * 0 | vdev1 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 1 |G| offset1 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 2 | vdev2 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 3 |G| offset2 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 4 | vdev3 | GRID | ASIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 5 |G| offset3 | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 7 | padding | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 8 | padding | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 9 | physical birth txg | * +-------+-------+-------+-------+-------+-------+-------+-------+ * a | logical birth txg | * +-------+-------+-------+-------+-------+-------+-------+-------+ * b | fill count | * +-------+-------+-------+-------+-------+-------+-------+-------+ * c | checksum[0] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * d | checksum[1] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * e | checksum[2] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * f | checksum[3] | * +-------+-------+-------+-------+-------+-------+-------+-------+ * * Legend: * * vdev virtual device ID * offset offset into virtual device * LSIZE logical size * PSIZE physical size (after compression) * ASIZE allocated size (including RAID-Z parity and gang block headers) * GRID RAID-Z layout information (reserved for future use) * cksum checksum function * comp compression function * G gang block indicator * B byteorder (endianness) * D dedup * X encryption (on version 30, which is not supported) * E blkptr_t contains embedded data (see below) * lvl level of indirection * type DMU object type * phys birth txg of block allocation; zero if same as logical birth txg * log. birth transaction group in which the block was logically born * fill count number of non-zero blocks under this bp * checksum[4] 256-bit checksum of the data this bp describes */ /* * "Embedded" blkptr_t's don't actually point to a block, instead they * have a data payload embedded in the blkptr_t itself. See the comment * in blkptr.c for more details. * * The blkptr_t is laid out as follows: * * 64 56 48 40 32 24 16 8 0 * +-------+-------+-------+-------+-------+-------+-------+-------+ * 0 | payload | * 1 | payload | * 2 | payload | * 3 | payload | * 4 | payload | * 5 | payload | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 6 |BDX|lvl| type | etype |E| comp| PSIZE| LSIZE | * +-------+-------+-------+-------+-------+-------+-------+-------+ * 7 | payload | * 8 | payload | * 9 | payload | * +-------+-------+-------+-------+-------+-------+-------+-------+ * a | logical birth txg | * +-------+-------+-------+-------+-------+-------+-------+-------+ * b | payload | * c | payload | * d | payload | * e | payload | * f | payload | * +-------+-------+-------+-------+-------+-------+-------+-------+ * * Legend: * * payload contains the embedded data * B (byteorder) byteorder (endianness) * D (dedup) padding (set to zero) * X encryption (set to zero; see above) * E (embedded) set to one * lvl indirection level * type DMU object type * etype how to interpret embedded data (BP_EMBEDDED_TYPE_*) * comp compression function of payload * PSIZE size of payload after compression, in bytes * LSIZE logical size of payload, in bytes * note that 25 bits is enough to store the largest * "normal" BP's LSIZE (2^16 * 2^9) in bytes * log. birth transaction group in which the block was logically born * * Note that LSIZE and PSIZE are stored in bytes, whereas for non-embedded * bp's they are stored in units of SPA_MINBLOCKSHIFT. * Generally, the generic BP_GET_*() macros can be used on embedded BP's. * The B, D, X, lvl, type, and comp fields are stored the same as with normal * BP's so the BP_SET_* macros can be used with them. etype, PSIZE, LSIZE must * be set with the BPE_SET_* macros. BP_SET_EMBEDDED() should be called before * other macros, as they assert that they are only used on BP's of the correct * "embedded-ness". */ #define BPE_GET_ETYPE(bp) \ (ASSERT(BP_IS_EMBEDDED(bp)), \ BF64_GET((bp)->blk_prop, 40, 8)) #define BPE_SET_ETYPE(bp, t) do { \ ASSERT(BP_IS_EMBEDDED(bp)); \ BF64_SET((bp)->blk_prop, 40, 8, t); \ _NOTE(CONSTCOND) } while (0) #define BPE_GET_LSIZE(bp) \ (ASSERT(BP_IS_EMBEDDED(bp)), \ BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1)) #define BPE_SET_LSIZE(bp, x) do { \ ASSERT(BP_IS_EMBEDDED(bp)); \ BF64_SET_SB((bp)->blk_prop, 0, 25, 0, 1, x); \ _NOTE(CONSTCOND) } while (0) #define BPE_GET_PSIZE(bp) \ (ASSERT(BP_IS_EMBEDDED(bp)), \ BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1)) #define BPE_SET_PSIZE(bp, x) do { \ ASSERT(BP_IS_EMBEDDED(bp)); \ BF64_SET_SB((bp)->blk_prop, 25, 7, 0, 1, x); \ _NOTE(CONSTCOND) } while (0) typedef enum bp_embedded_type { BP_EMBEDDED_TYPE_DATA, BP_EMBEDDED_TYPE_RESERVED, /* Reserved for an unintegrated feature. */ NUM_BP_EMBEDDED_TYPES = BP_EMBEDDED_TYPE_RESERVED } bp_embedded_type_t; #define BPE_NUM_WORDS 14 #define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t)) #define BPE_IS_PAYLOADWORD(bp, wp) \ ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth) #define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */ #define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */ typedef struct blkptr { dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */ uint64_t blk_prop; /* size, compression, type, etc */ uint64_t blk_pad[2]; /* Extra space for the future */ uint64_t blk_phys_birth; /* txg when block was allocated */ uint64_t blk_birth; /* transaction group at birth */ uint64_t blk_fill; /* fill count */ zio_cksum_t blk_cksum; /* 256-bit checksum */ } blkptr_t; /* * Macros to get and set fields in a bp or DVA. */ #define DVA_GET_ASIZE(dva) \ BF64_GET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0) #define DVA_SET_ASIZE(dva, x) \ BF64_SET_SB((dva)->dva_word[0], 0, SPA_ASIZEBITS, \ SPA_MINBLOCKSHIFT, 0, x) #define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8) #define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x) #define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32) #define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x) #define DVA_GET_OFFSET(dva) \ BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0) #define DVA_SET_OFFSET(dva, x) \ BF64_SET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0, x) #define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1) #define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x) #define BP_GET_LSIZE(bp) \ (BP_IS_EMBEDDED(bp) ? \ (BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA ? BPE_GET_LSIZE(bp) : 0): \ BF64_GET_SB((bp)->blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1)) #define BP_SET_LSIZE(bp, x) do { \ ASSERT(!BP_IS_EMBEDDED(bp)); \ BF64_SET_SB((bp)->blk_prop, \ 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x); \ _NOTE(CONSTCOND) } while (0) #define BP_GET_PSIZE(bp) \ BF64_GET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1) #define BP_SET_PSIZE(bp, x) \ BF64_SET_SB((bp)->blk_prop, 16, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x) #define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7) #define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x) #define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8) #define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x) #define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8) #define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x) #define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5) #define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x) #define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1) #define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1) #define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x) #define BP_GET_BYTEORDER(bp) BF64_GET((bp)->blk_prop, 63, 1) #define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x) #define BP_PHYSICAL_BIRTH(bp) \ ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth) #define BP_GET_ASIZE(bp) \ (DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ DVA_GET_ASIZE(&(bp)->blk_dva[2])) #define BP_GET_UCSIZE(bp) \ ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \ BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp)); #define BP_GET_NDVAS(bp) \ (!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \ !!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ !!DVA_GET_ASIZE(&(bp)->blk_dva[2])) #define DVA_EQUAL(dva1, dva2) \ ((dva1)->dva_word[1] == (dva2)->dva_word[1] && \ (dva1)->dva_word[0] == (dva2)->dva_word[0]) #define ZIO_CHECKSUM_EQUAL(zc1, zc2) \ (0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \ ((zc1).zc_word[1] - (zc2).zc_word[1]) | \ ((zc1).zc_word[2] - (zc2).zc_word[2]) | \ ((zc1).zc_word[3] - (zc2).zc_word[3]))) #define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0) #define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \ { \ (zcp)->zc_word[0] = w0; \ (zcp)->zc_word[1] = w1; \ (zcp)->zc_word[2] = w2; \ (zcp)->zc_word[3] = w3; \ } #define BP_IDENTITY(bp) (&(bp)->blk_dva[0]) #define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp)) #define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] == 0ULL && \ (dva)->dva_word[1] == 0ULL) #define BP_IS_HOLE(bp) DVA_IS_EMPTY(BP_IDENTITY(bp)) #define BP_IS_OLDER(bp, txg) (!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg)) #define BP_ZERO(bp) \ { \ (bp)->blk_dva[0].dva_word[0] = 0; \ (bp)->blk_dva[0].dva_word[1] = 0; \ (bp)->blk_dva[1].dva_word[0] = 0; \ (bp)->blk_dva[1].dva_word[1] = 0; \ (bp)->blk_dva[2].dva_word[0] = 0; \ (bp)->blk_dva[2].dva_word[1] = 0; \ (bp)->blk_prop = 0; \ (bp)->blk_pad[0] = 0; \ (bp)->blk_pad[1] = 0; \ (bp)->blk_phys_birth = 0; \ (bp)->blk_birth = 0; \ (bp)->blk_fill = 0; \ ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \ } #if BYTE_ORDER == _BIG_ENDIAN #define ZFS_HOST_BYTEORDER (0ULL) #else #define ZFS_HOST_BYTEORDER (1ULL) #endif #define BP_SHOULD_BYTESWAP(bp) (BP_GET_BYTEORDER(bp) != ZFS_HOST_BYTEORDER) #define BPE_NUM_WORDS 14 #define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t)) #define BPE_IS_PAYLOADWORD(bp, wp) \ ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth) /* * Embedded checksum */ #define ZEC_MAGIC 0x210da7ab10c7a11ULL typedef struct zio_eck { uint64_t zec_magic; /* for validation, endianness */ zio_cksum_t zec_cksum; /* 256-bit checksum */ } zio_eck_t; /* * Gang block headers are self-checksumming and contain an array * of block pointers. */ #define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE #define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ sizeof (zio_eck_t)) / sizeof (blkptr_t)) #define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ sizeof (zio_eck_t) - \ (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ sizeof (uint64_t)) typedef struct zio_gbh { blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; uint64_t zg_filler[SPA_GBH_FILLER]; zio_eck_t zg_tail; } zio_gbh_phys_t; #define VDEV_RAIDZ_MAXPARITY 3 #define VDEV_PAD_SIZE (8 << 10) /* 2 padding areas (vl_pad1 and vl_be) to skip */ #define VDEV_SKIP_SIZE VDEV_PAD_SIZE * 2 #define VDEV_PHYS_SIZE (112 << 10) #define VDEV_UBERBLOCK_RING (128 << 10) /* * MMP blocks occupy the last MMP_BLOCKS_PER_LABEL slots in the uberblock * ring when MMP is enabled. */ #define MMP_BLOCKS_PER_LABEL 1 /* The largest uberblock we support is 8k. */ #define MAX_UBERBLOCK_SHIFT (13) #define VDEV_UBERBLOCK_SHIFT(vd) \ MIN(MAX((vd)->v_top->v_ashift, UBERBLOCK_SHIFT), MAX_UBERBLOCK_SHIFT) #define VDEV_UBERBLOCK_COUNT(vd) \ (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(vd)) #define VDEV_UBERBLOCK_OFFSET(vd, n) \ offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(vd)]) #define VDEV_UBERBLOCK_SIZE(vd) (1ULL << VDEV_UBERBLOCK_SHIFT(vd)) typedef struct vdev_phys { char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)]; zio_eck_t vp_zbt; } vdev_phys_t; typedef enum vbe_vers { /* The bootenv file is stored as ascii text in the envblock */ VB_RAW = 0, /* * The bootenv file is converted to an nvlist and then packed into the * envblock. */ VB_NVLIST = 1 } vbe_vers_t; typedef struct vdev_boot_envblock { uint64_t vbe_version; char vbe_bootenv[VDEV_PAD_SIZE - sizeof (uint64_t) - sizeof (zio_eck_t)]; zio_eck_t vbe_zbt; } vdev_boot_envblock_t; CTASSERT(sizeof (vdev_boot_envblock_t) == VDEV_PAD_SIZE); typedef struct vdev_label { char vl_pad1[VDEV_PAD_SIZE]; /* 8K */ vdev_boot_envblock_t vl_be; /* 8K */ vdev_phys_t vl_vdev_phys; /* 112K */ char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */ } vdev_label_t; /* 256K total */ /* * vdev_dirty() flags */ #define VDD_METASLAB 0x01 #define VDD_DTL 0x02 /* * Size and offset of embedded boot loader region on each label. * The total size of the first two labels plus the boot area is 4MB. */ #define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t)) #define VDEV_BOOT_SIZE (7ULL << 19) /* 3.5M */ /* * Size of label regions at the start and end of each leaf device. */ #define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE) #define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t)) #define VDEV_LABELS 4 enum zio_checksum { ZIO_CHECKSUM_INHERIT = 0, ZIO_CHECKSUM_ON, ZIO_CHECKSUM_OFF, ZIO_CHECKSUM_LABEL, ZIO_CHECKSUM_GANG_HEADER, ZIO_CHECKSUM_ZILOG, ZIO_CHECKSUM_FLETCHER_2, ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_ZILOG2, ZIO_CHECKSUM_NOPARITY, ZIO_CHECKSUM_SHA512, ZIO_CHECKSUM_SKEIN, ZIO_CHECKSUM_EDONR, ZIO_CHECKSUM_FUNCTIONS }; #define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_4 #define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON enum zio_compress { ZIO_COMPRESS_INHERIT = 0, ZIO_COMPRESS_ON, ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, ZIO_COMPRESS_GZIP_1, ZIO_COMPRESS_GZIP_2, ZIO_COMPRESS_GZIP_3, ZIO_COMPRESS_GZIP_4, ZIO_COMPRESS_GZIP_5, ZIO_COMPRESS_GZIP_6, ZIO_COMPRESS_GZIP_7, ZIO_COMPRESS_GZIP_8, ZIO_COMPRESS_GZIP_9, ZIO_COMPRESS_ZLE, ZIO_COMPRESS_LZ4, ZIO_COMPRESS_FUNCTIONS }; #define ZIO_COMPRESS_ON_VALUE ZIO_COMPRESS_LZJB #define ZIO_COMPRESS_DEFAULT ZIO_COMPRESS_OFF /* nvlist pack encoding */ #define NV_ENCODE_NATIVE 0 #define NV_ENCODE_XDR 1 typedef enum { DATA_TYPE_UNKNOWN = 0, DATA_TYPE_BOOLEAN, DATA_TYPE_BYTE, DATA_TYPE_INT16, DATA_TYPE_UINT16, DATA_TYPE_INT32, DATA_TYPE_UINT32, DATA_TYPE_INT64, DATA_TYPE_UINT64, DATA_TYPE_STRING, DATA_TYPE_BYTE_ARRAY, DATA_TYPE_INT16_ARRAY, DATA_TYPE_UINT16_ARRAY, DATA_TYPE_INT32_ARRAY, DATA_TYPE_UINT32_ARRAY, DATA_TYPE_INT64_ARRAY, DATA_TYPE_UINT64_ARRAY, DATA_TYPE_STRING_ARRAY, DATA_TYPE_HRTIME, DATA_TYPE_NVLIST, DATA_TYPE_NVLIST_ARRAY, DATA_TYPE_BOOLEAN_VALUE, DATA_TYPE_INT8, DATA_TYPE_UINT8, DATA_TYPE_BOOLEAN_ARRAY, DATA_TYPE_INT8_ARRAY, DATA_TYPE_UINT8_ARRAY } data_type_t; /* * On-disk version number. */ #define SPA_VERSION_1 1ULL #define SPA_VERSION_2 2ULL #define SPA_VERSION_3 3ULL #define SPA_VERSION_4 4ULL #define SPA_VERSION_5 5ULL #define SPA_VERSION_6 6ULL #define SPA_VERSION_7 7ULL #define SPA_VERSION_8 8ULL #define SPA_VERSION_9 9ULL #define SPA_VERSION_10 10ULL #define SPA_VERSION_11 11ULL #define SPA_VERSION_12 12ULL #define SPA_VERSION_13 13ULL #define SPA_VERSION_14 14ULL #define SPA_VERSION_15 15ULL #define SPA_VERSION_16 16ULL #define SPA_VERSION_17 17ULL #define SPA_VERSION_18 18ULL #define SPA_VERSION_19 19ULL #define SPA_VERSION_20 20ULL #define SPA_VERSION_21 21ULL #define SPA_VERSION_22 22ULL #define SPA_VERSION_23 23ULL #define SPA_VERSION_24 24ULL #define SPA_VERSION_25 25ULL #define SPA_VERSION_26 26ULL #define SPA_VERSION_27 27ULL #define SPA_VERSION_28 28ULL #define SPA_VERSION_5000 5000ULL /* * When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk * format change. Go to usr/src/grub/grub-0.97/stage2/{zfs-include/, fsys_zfs*}, * and do the appropriate changes. Also bump the version number in * usr/src/grub/capability. */ #define SPA_VERSION SPA_VERSION_5000 #define SPA_VERSION_STRING "5000" /* * Symbolic names for the changes that caused a SPA_VERSION switch. * Used in the code when checking for presence or absence of a feature. * Feel free to define multiple symbolic names for each version if there * were multiple changes to on-disk structures during that version. * * NOTE: When checking the current SPA_VERSION in your code, be sure * to use spa_version() since it reports the version of the * last synced uberblock. Checking the in-flight version can * be dangerous in some cases. */ #define SPA_VERSION_INITIAL SPA_VERSION_1 #define SPA_VERSION_DITTO_BLOCKS SPA_VERSION_2 #define SPA_VERSION_SPARES SPA_VERSION_3 #define SPA_VERSION_RAID6 SPA_VERSION_3 #define SPA_VERSION_BPLIST_ACCOUNT SPA_VERSION_3 #define SPA_VERSION_RAIDZ_DEFLATE SPA_VERSION_3 #define SPA_VERSION_DNODE_BYTES SPA_VERSION_3 #define SPA_VERSION_ZPOOL_HISTORY SPA_VERSION_4 #define SPA_VERSION_GZIP_COMPRESSION SPA_VERSION_5 #define SPA_VERSION_BOOTFS SPA_VERSION_6 #define SPA_VERSION_SLOGS SPA_VERSION_7 #define SPA_VERSION_DELEGATED_PERMS SPA_VERSION_8 #define SPA_VERSION_FUID SPA_VERSION_9 #define SPA_VERSION_REFRESERVATION SPA_VERSION_9 #define SPA_VERSION_REFQUOTA SPA_VERSION_9 #define SPA_VERSION_UNIQUE_ACCURATE SPA_VERSION_9 #define SPA_VERSION_L2CACHE SPA_VERSION_10 #define SPA_VERSION_NEXT_CLONES SPA_VERSION_11 #define SPA_VERSION_ORIGIN SPA_VERSION_11 #define SPA_VERSION_DSL_SCRUB SPA_VERSION_11 #define SPA_VERSION_SNAP_PROPS SPA_VERSION_12 #define SPA_VERSION_USED_BREAKDOWN SPA_VERSION_13 #define SPA_VERSION_PASSTHROUGH_X SPA_VERSION_14 #define SPA_VERSION_USERSPACE SPA_VERSION_15 #define SPA_VERSION_STMF_PROP SPA_VERSION_16 #define SPA_VERSION_RAIDZ3 SPA_VERSION_17 #define SPA_VERSION_USERREFS SPA_VERSION_18 #define SPA_VERSION_HOLES SPA_VERSION_19 #define SPA_VERSION_ZLE_COMPRESSION SPA_VERSION_20 #define SPA_VERSION_DEDUP SPA_VERSION_21 #define SPA_VERSION_RECVD_PROPS SPA_VERSION_22 #define SPA_VERSION_SLIM_ZIL SPA_VERSION_23 #define SPA_VERSION_SA SPA_VERSION_24 #define SPA_VERSION_SCAN SPA_VERSION_25 #define SPA_VERSION_DIR_CLONES SPA_VERSION_26 #define SPA_VERSION_DEADLISTS SPA_VERSION_26 #define SPA_VERSION_FAST_SNAP SPA_VERSION_27 #define SPA_VERSION_MULTI_REPLACE SPA_VERSION_28 #define SPA_VERSION_BEFORE_FEATURES SPA_VERSION_28 #define SPA_VERSION_FEATURES SPA_VERSION_5000 #define SPA_VERSION_IS_SUPPORTED(v) \ (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \ ((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION)) /* * The following are configuration names used in the nvlist describing a pool's * configuration. */ #define ZPOOL_CONFIG_VERSION "version" #define ZPOOL_CONFIG_POOL_NAME "name" #define ZPOOL_CONFIG_POOL_STATE "state" #define ZPOOL_CONFIG_POOL_TXG "txg" #define ZPOOL_CONFIG_POOL_GUID "pool_guid" #define ZPOOL_CONFIG_CREATE_TXG "create_txg" #define ZPOOL_CONFIG_TOP_GUID "top_guid" #define ZPOOL_CONFIG_VDEV_TREE "vdev_tree" #define ZPOOL_CONFIG_TYPE "type" #define ZPOOL_CONFIG_CHILDREN "children" #define ZPOOL_CONFIG_ID "id" #define ZPOOL_CONFIG_GUID "guid" #define ZPOOL_CONFIG_INDIRECT_OBJECT "com.delphix:indirect_object" #define ZPOOL_CONFIG_INDIRECT_BIRTHS "com.delphix:indirect_births" #define ZPOOL_CONFIG_PREV_INDIRECT_VDEV "com.delphix:prev_indirect_vdev" #define ZPOOL_CONFIG_PATH "path" #define ZPOOL_CONFIG_DEVID "devid" #define ZPOOL_CONFIG_PHYS_PATH "phys_path" #define ZPOOL_CONFIG_METASLAB_ARRAY "metaslab_array" #define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift" #define ZPOOL_CONFIG_ASHIFT "ashift" #define ZPOOL_CONFIG_ASIZE "asize" #define ZPOOL_CONFIG_DTL "DTL" #define ZPOOL_CONFIG_STATS "stats" #define ZPOOL_CONFIG_WHOLE_DISK "whole_disk" #define ZPOOL_CONFIG_ERRCOUNT "error_count" #define ZPOOL_CONFIG_NOT_PRESENT "not_present" #define ZPOOL_CONFIG_SPARES "spares" #define ZPOOL_CONFIG_IS_SPARE "is_spare" #define ZPOOL_CONFIG_NPARITY "nparity" #define ZPOOL_CONFIG_HOSTID "hostid" #define ZPOOL_CONFIG_HOSTNAME "hostname" #define ZPOOL_CONFIG_IS_LOG "is_log" #define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */ #define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read" #define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children" /* * The persistent vdev state is stored as separate values rather than a single * 'vdev_state' entry. This is because a device can be in multiple states, such * as offline and degraded. */ #define ZPOOL_CONFIG_OFFLINE "offline" #define ZPOOL_CONFIG_FAULTED "faulted" #define ZPOOL_CONFIG_DEGRADED "degraded" #define ZPOOL_CONFIG_REMOVED "removed" #define ZPOOL_CONFIG_FRU "fru" #define ZPOOL_CONFIG_AUX_STATE "aux_state" #define VDEV_TYPE_ROOT "root" #define VDEV_TYPE_MIRROR "mirror" #define VDEV_TYPE_REPLACING "replacing" #define VDEV_TYPE_RAIDZ "raidz" #define VDEV_TYPE_DISK "disk" #define VDEV_TYPE_FILE "file" #define VDEV_TYPE_MISSING "missing" #define VDEV_TYPE_HOLE "hole" #define VDEV_TYPE_SPARE "spare" #define VDEV_TYPE_LOG "log" #define VDEV_TYPE_L2CACHE "l2cache" #define VDEV_TYPE_INDIRECT "indirect" /* * This is needed in userland to report the minimum necessary device size. */ #define SPA_MINDEVSIZE (64ULL << 20) /* * The location of the pool configuration repository, shared between kernel and * userland. */ #define ZPOOL_CACHE "/boot/zfs/zpool.cache" /* * vdev states are ordered from least to most healthy. * A vdev that's CANT_OPEN or below is considered unusable. */ typedef enum vdev_state { VDEV_STATE_UNKNOWN = 0, /* Uninitialized vdev */ VDEV_STATE_CLOSED, /* Not currently open */ VDEV_STATE_OFFLINE, /* Not allowed to open */ VDEV_STATE_REMOVED, /* Explicitly removed from system */ VDEV_STATE_CANT_OPEN, /* Tried to open, but failed */ VDEV_STATE_FAULTED, /* External request to fault device */ VDEV_STATE_DEGRADED, /* Replicated vdev with unhealthy kids */ VDEV_STATE_HEALTHY /* Presumed good */ } vdev_state_t; /* * vdev aux states. When a vdev is in the CANT_OPEN state, the aux field * of the vdev stats structure uses these constants to distinguish why. */ typedef enum vdev_aux { VDEV_AUX_NONE, /* no error */ VDEV_AUX_OPEN_FAILED, /* ldi_open_*() or vn_open() failed */ VDEV_AUX_CORRUPT_DATA, /* bad label or disk contents */ VDEV_AUX_NO_REPLICAS, /* insufficient number of replicas */ VDEV_AUX_BAD_GUID_SUM, /* vdev guid sum doesn't match */ VDEV_AUX_TOO_SMALL, /* vdev size is too small */ VDEV_AUX_BAD_LABEL, /* the label is OK but invalid */ VDEV_AUX_VERSION_NEWER, /* on-disk version is too new */ VDEV_AUX_VERSION_OLDER, /* on-disk version is too old */ VDEV_AUX_SPARED /* hot spare used in another pool */ } vdev_aux_t; /* * pool state. The following states are written to disk as part of the normal * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE. The remaining states are * software abstractions used at various levels to communicate pool state. */ typedef enum pool_state { POOL_STATE_ACTIVE = 0, /* In active use */ POOL_STATE_EXPORTED, /* Explicitly exported */ POOL_STATE_DESTROYED, /* Explicitly destroyed */ POOL_STATE_SPARE, /* Reserved for hot spare use */ POOL_STATE_UNINITIALIZED, /* Internal spa_t state */ POOL_STATE_UNAVAIL, /* Internal libzfs state */ POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */ } pool_state_t; /* * The uberblock version is incremented whenever an incompatible on-disk * format change is made to the SPA, DMU, or ZAP. * * Note: the first two fields should never be moved. When a storage pool * is opened, the uberblock must be read off the disk before the version * can be checked. If the ub_version field is moved, we may not detect * version mismatch. If the ub_magic field is moved, applications that * expect the magic number in the first word won't work. */ #define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ #define UBERBLOCK_SHIFT 10 /* up to 1K */ #define MMP_MAGIC 0xa11cea11 /* all-see-all */ #define MMP_INTERVAL_VALID_BIT 0x01 #define MMP_SEQ_VALID_BIT 0x02 #define MMP_FAIL_INT_VALID_BIT 0x04 #define MMP_VALID(ubp) (ubp->ub_magic == UBERBLOCK_MAGIC && \ ubp->ub_mmp_magic == MMP_MAGIC) #define MMP_INTERVAL_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \ MMP_INTERVAL_VALID_BIT)) #define MMP_SEQ_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \ MMP_SEQ_VALID_BIT)) #define MMP_FAIL_INT_VALID(ubp) (MMP_VALID(ubp) && (ubp->ub_mmp_config & \ MMP_FAIL_INT_VALID_BIT)) #define MMP_INTERVAL(ubp) ((ubp->ub_mmp_config & 0x00000000FFFFFF00) \ >> 8) #define MMP_SEQ(ubp) ((ubp->ub_mmp_config & 0x0000FFFF00000000) \ >> 32) #define MMP_FAIL_INT(ubp) ((ubp->ub_mmp_config & 0xFFFF000000000000) \ >> 48) typedef struct uberblock { uint64_t ub_magic; /* UBERBLOCK_MAGIC */ uint64_t ub_version; /* SPA_VERSION */ uint64_t ub_txg; /* txg of last sync */ uint64_t ub_guid_sum; /* sum of all vdev guids */ uint64_t ub_timestamp; /* UTC time of last sync */ blkptr_t ub_rootbp; /* MOS objset_phys_t */ /* highest SPA_VERSION supported by software that wrote this txg */ uint64_t ub_software_version; /* Maybe missing in uberblocks we read, but always written */ uint64_t ub_mmp_magic; /* * If ub_mmp_delay == 0 and ub_mmp_magic is valid, MMP is off. * Otherwise, nanosec since last MMP write. */ uint64_t ub_mmp_delay; /* BEGIN CSTYLED */ /* * The ub_mmp_config contains the multihost write interval, multihost * fail intervals, sequence number for sub-second granularity, and * valid bit mask. This layout is as follows: * * 64 56 48 40 32 24 16 8 0 * +-------+-------+-------+-------+-------+-------+-------+-------+ * 0 | Fail Intervals| Seq | Write Interval (ms) | VALID | * +-------+-------+-------+-------+-------+-------+-------+-------+ * * This allows a write_interval of (2^24/1000)s, over 4.5 hours * * VALID Bits: * - 0x01 - Write Interval (ms) * - 0x02 - Sequence number exists * - 0x04 - Fail Intervals * - 0xf8 - Reserved */ /* END CSTYLED */ uint64_t ub_mmp_config; /* * ub_checkpoint_txg indicates two things about the current uberblock: * * 1] If it is not zero then this uberblock is a checkpoint. If it is * zero, then this uberblock is not a checkpoint. * * 2] On checkpointed uberblocks, the value of ub_checkpoint_txg is * the ub_txg that the uberblock had at the time we moved it to * the MOS config. * * The field is set when we checkpoint the uberblock and continues to * hold that value even after we've rewound (unlike the ub_txg that * is reset to a higher value). * * Besides checks used to determine whether we are reopening the * pool from a checkpointed uberblock [see spa_ld_select_uberblock()], * the value of the field is used to determine which ZIL blocks have * been allocated according to the ms_sm when we are rewinding to a * checkpoint. Specifically, if blk_birth > ub_checkpoint_txg, then * the ZIL block is not allocated [see uses of spa_min_claim_txg()]. */ uint64_t ub_checkpoint_txg; } uberblock_t; /* * Flags. */ #define DNODE_MUST_BE_ALLOCATED 1 #define DNODE_MUST_BE_FREE 2 /* * Fixed constants. */ #define DNODE_SHIFT 9 /* 512 bytes */ #define DN_MIN_INDBLKSHIFT 12 /* 4k */ #define DN_MAX_INDBLKSHIFT 17 /* 128k */ #define DNODE_BLOCK_SHIFT 14 /* 16k */ #define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */ #define DN_MAX_OBJECT_SHIFT 48 /* 256 trillion (zfs_fid_t limit) */ #define DN_MAX_OFFSET_SHIFT 64 /* 2^64 bytes in a dnode */ /* * Derived constants. */ #define DNODE_MIN_SIZE (1 << DNODE_SHIFT) #define DNODE_MAX_SIZE (1 << DNODE_BLOCK_SHIFT) #define DNODE_BLOCK_SIZE (1 << DNODE_BLOCK_SHIFT) #define DNODE_MIN_SLOTS (DNODE_MIN_SIZE >> DNODE_SHIFT) #define DNODE_MAX_SLOTS (DNODE_MAX_SIZE >> DNODE_SHIFT) #define DN_BONUS_SIZE(dnsize) ((dnsize) - DNODE_CORE_SIZE - \ (1 << SPA_BLKPTRSHIFT)) #define DN_SLOTS_TO_BONUSLEN(slots) DN_BONUS_SIZE((slots) << DNODE_SHIFT) #define DN_OLD_MAX_BONUSLEN (DN_BONUS_SIZE(DNODE_MIN_SIZE)) #define DN_MAX_NBLKPTR ((DNODE_MIN_SIZE - DNODE_CORE_SIZE) >> \ SPA_BLKPTRSHIFT) #define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT) #define DN_ZERO_BONUSLEN (DN_BONUS_SIZE(DNODE_MAX_SIZE) + 1) #define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) #define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) #define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) /* The +2 here is a cheesy way to round up */ #define DN_MAX_LEVELS (2 + ((DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT) / \ (DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT))) #define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) #define DN_USED_BYTES(dnp) (((dnp)->dn_flags & DNODE_FLAG_USED_BYTES) ? \ (dnp)->dn_used : (dnp)->dn_used << SPA_MINBLOCKSHIFT) #define EPB(blkshift, typeshift) (1 << (blkshift - typeshift)) /* Is dn_used in bytes? if not, it's in multiples of SPA_MINBLOCKSIZE */ #define DNODE_FLAG_USED_BYTES (1<<0) #define DNODE_FLAG_USERUSED_ACCOUNTED (1<<1) /* Does dnode have a SA spill blkptr in bonus? */ #define DNODE_FLAG_SPILL_BLKPTR (1<<2) typedef struct dnode_phys { uint8_t dn_type; /* dmu_object_type_t */ uint8_t dn_indblkshift; /* ln2(indirect block size) */ uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */ uint8_t dn_nblkptr; /* length of dn_blkptr */ uint8_t dn_bonustype; /* type of data in bonus buffer */ uint8_t dn_checksum; /* ZIO_CHECKSUM type */ uint8_t dn_compress; /* ZIO_COMPRESS type */ uint8_t dn_flags; /* DNODE_FLAG_* */ uint16_t dn_datablkszsec; /* data block size in 512b sectors */ uint16_t dn_bonuslen; /* length of dn_bonus */ uint8_t dn_extra_slots; /* # of subsequent slots consumed */ uint8_t dn_pad2[3]; /* accounting is protected by dn_dirty_mtx */ uint64_t dn_maxblkid; /* largest allocated block ID */ uint64_t dn_used; /* bytes (or sectors) of disk space */ uint64_t dn_pad3[4]; /* BEGIN CSTYLED */ /* * The tail region is 448 bytes for a 512 byte dnode, and * correspondingly larger for larger dnode sizes. The spill * block pointer, when present, is always at the end of the tail * region. There are three ways this space may be used, using * a 512 byte dnode for this diagram: * * 0 64 128 192 256 320 384 448 (offset) * +---------------+---------------+---------------+-------+ * | dn_blkptr[0] | dn_blkptr[1] | dn_blkptr[2] | / | * +---------------+---------------+---------------+-------+ * | dn_blkptr[0] | dn_bonus[0..319] | * +---------------+-----------------------+---------------+ * | dn_blkptr[0] | dn_bonus[0..191] | dn_spill | * +---------------+-----------------------+---------------+ */ /* END CSTYLED */ union { blkptr_t dn_blkptr[1+DN_OLD_MAX_BONUSLEN/sizeof (blkptr_t)]; struct { blkptr_t __dn_ignore1; uint8_t dn_bonus[DN_OLD_MAX_BONUSLEN]; }; struct { blkptr_t __dn_ignore2; uint8_t __dn_ignore3[DN_OLD_MAX_BONUSLEN - sizeof (blkptr_t)]; blkptr_t dn_spill; }; }; } dnode_phys_t; #define DN_SPILL_BLKPTR(dnp) (blkptr_t *)((char *)(dnp) + \ (((dnp)->dn_extra_slots + 1) << DNODE_SHIFT) - (1 << SPA_BLKPTRSHIFT)) typedef enum dmu_object_byteswap { DMU_BSWAP_UINT8, DMU_BSWAP_UINT16, DMU_BSWAP_UINT32, DMU_BSWAP_UINT64, DMU_BSWAP_ZAP, DMU_BSWAP_DNODE, DMU_BSWAP_OBJSET, DMU_BSWAP_ZNODE, DMU_BSWAP_OLDACL, DMU_BSWAP_ACL, /* * Allocating a new byteswap type number makes the on-disk format * incompatible with any other format that uses the same number. * * Data can usually be structured to work with one of the * DMU_BSWAP_UINT* or DMU_BSWAP_ZAP types. */ DMU_BSWAP_NUMFUNCS } dmu_object_byteswap_t; #define DMU_OT_NEWTYPE 0x80 #define DMU_OT_METADATA 0x40 #define DMU_OT_BYTESWAP_MASK 0x3f /* * Defines a uint8_t object type. Object types specify if the data * in the object is metadata (boolean) and how to byteswap the data * (dmu_object_byteswap_t). */ #define DMU_OT(byteswap, metadata) \ (DMU_OT_NEWTYPE | \ ((metadata) ? DMU_OT_METADATA : 0) | \ ((byteswap) & DMU_OT_BYTESWAP_MASK)) typedef enum dmu_object_type { DMU_OT_NONE, /* general: */ DMU_OT_OBJECT_DIRECTORY, /* ZAP */ DMU_OT_OBJECT_ARRAY, /* UINT64 */ DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ DMU_OT_BPLIST, /* UINT64 */ DMU_OT_BPLIST_HDR, /* UINT64 */ /* spa: */ DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ DMU_OT_SPACE_MAP, /* UINT64 */ /* zil: */ DMU_OT_INTENT_LOG, /* UINT64 */ /* dmu: */ DMU_OT_DNODE, /* DNODE */ DMU_OT_OBJSET, /* OBJSET */ /* dsl: */ DMU_OT_DSL_DIR, /* UINT64 */ DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */ DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */ DMU_OT_DSL_PROPS, /* ZAP */ DMU_OT_DSL_DATASET, /* UINT64 */ /* zpl: */ DMU_OT_ZNODE, /* ZNODE */ DMU_OT_OLDACL, /* Old ACL */ DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ DMU_OT_MASTER_NODE, /* ZAP */ DMU_OT_UNLINKED_SET, /* ZAP */ /* zvol: */ DMU_OT_ZVOL, /* UINT8 */ DMU_OT_ZVOL_PROP, /* ZAP */ /* other; for testing only! */ DMU_OT_PLAIN_OTHER, /* UINT8 */ DMU_OT_UINT64_OTHER, /* UINT64 */ DMU_OT_ZAP_OTHER, /* ZAP */ /* new object types: */ DMU_OT_ERROR_LOG, /* ZAP */ DMU_OT_SPA_HISTORY, /* UINT8 */ DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */ DMU_OT_POOL_PROPS, /* ZAP */ DMU_OT_DSL_PERMS, /* ZAP */ DMU_OT_ACL, /* ACL */ DMU_OT_SYSACL, /* SYSACL */ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ DMU_OT_NEXT_CLONES, /* ZAP */ DMU_OT_SCAN_QUEUE, /* ZAP */ DMU_OT_USERGROUP_USED, /* ZAP */ DMU_OT_USERGROUP_QUOTA, /* ZAP */ DMU_OT_USERREFS, /* ZAP */ DMU_OT_DDT_ZAP, /* ZAP */ DMU_OT_DDT_STATS, /* ZAP */ DMU_OT_SA, /* System attr */ DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ DMU_OT_SCAN_XLATE, /* ZAP */ DMU_OT_DEDUP, /* fake dedup BP from ddt_bp_create() */ DMU_OT_NUMTYPES, /* * Names for valid types declared with DMU_OT(). */ DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE), DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE), DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE), DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE), DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE), DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE), DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE), DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE), DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE), DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE) } dmu_object_type_t; typedef enum dmu_objset_type { DMU_OST_NONE, DMU_OST_META, DMU_OST_ZFS, DMU_OST_ZVOL, DMU_OST_OTHER, /* For testing only! */ DMU_OST_ANY, /* Be careful! */ DMU_OST_NUMTYPES } dmu_objset_type_t; #define ZAP_MAXVALUELEN (1024 * 8) /* * header for all bonus and spill buffers. * The header has a fixed portion with a variable number * of "lengths" depending on the number of variable sized * attribues which are determined by the "layout number" */ #define SA_MAGIC 0x2F505A /* ZFS SA */ typedef struct sa_hdr_phys { uint32_t sa_magic; uint16_t sa_layout_info; /* Encoded with hdrsize and layout number */ uint16_t sa_lengths[1]; /* optional sizes for variable length attrs */ /* ... Data follows the lengths. */ } sa_hdr_phys_t; /* * sa_hdr_phys -> sa_layout_info * * 16 10 0 * +--------+-------+ * | hdrsz |layout | * +--------+-------+ * * Bits 0-10 are the layout number * Bits 11-16 are the size of the header. * The hdrsize is the number * 8 * * For example. * hdrsz of 1 ==> 8 byte header * 2 ==> 16 byte header * */ #define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10) #define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) #define SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \ { \ BF32_SET_SB(x, 10, 6, 3, 0, size); \ BF32_SET(x, 0, 10, num); \ } #define SA_MODE_OFFSET 0 #define SA_SIZE_OFFSET 8 #define SA_GEN_OFFSET 16 #define SA_UID_OFFSET 24 #define SA_GID_OFFSET 32 #define SA_PARENT_OFFSET 40 #define SA_SYMLINK_OFFSET 160 #define ZIO_OBJSET_MAC_LEN 32 /* * Intent log header - this on disk structure holds fields to manage * the log. All fields are 64 bit to easily handle cross architectures. */ typedef struct zil_header { uint64_t zh_claim_txg; /* txg in which log blocks were claimed */ uint64_t zh_replay_seq; /* highest replayed sequence number */ blkptr_t zh_log; /* log chain */ uint64_t zh_claim_seq; /* highest claimed sequence number */ uint64_t zh_pad[5]; } zil_header_t; #define OBJSET_PHYS_SIZE_V2 2048 #define OBJSET_PHYS_SIZE_V3 4096 #define OBJSET_PHYS_PAD0_SIZE \ (OBJSET_PHYS_SIZE_V2 - sizeof (dnode_phys_t) * 3 - \ sizeof (zil_header_t) - sizeof (uint64_t) * 2 - \ 2 * ZIO_OBJSET_MAC_LEN) #define OBJSET_PHYS_PAD1_SIZE \ (OBJSET_PHYS_SIZE_V3 - OBJSET_PHYS_SIZE_V2 - sizeof (dnode_phys_t)) typedef struct objset_phys { dnode_phys_t os_meta_dnode; zil_header_t os_zil_header; uint64_t os_type; uint64_t os_flags; uint8_t os_portable_mac[ZIO_OBJSET_MAC_LEN]; uint8_t os_local_mac[ZIO_OBJSET_MAC_LEN]; char os_pad0[OBJSET_PHYS_PAD0_SIZE]; dnode_phys_t os_userused_dnode; dnode_phys_t os_groupused_dnode; dnode_phys_t os_projectused_dnode; char os_pad1[OBJSET_PHYS_PAD1_SIZE]; } objset_phys_t; typedef struct dsl_dir_phys { uint64_t dd_creation_time; /* not actually used */ uint64_t dd_head_dataset_obj; uint64_t dd_parent_obj; uint64_t dd_clone_parent_obj; uint64_t dd_child_dir_zapobj; /* * how much space our children are accounting for; for leaf * datasets, == physical space used by fs + snaps */ uint64_t dd_used_bytes; uint64_t dd_compressed_bytes; uint64_t dd_uncompressed_bytes; /* Administrative quota setting */ uint64_t dd_quota; /* Administrative reservation setting */ uint64_t dd_reserved; uint64_t dd_props_zapobj; uint64_t dd_pad[21]; /* pad out to 256 bytes for good measure */ } dsl_dir_phys_t; typedef struct dsl_dataset_phys { uint64_t ds_dir_obj; uint64_t ds_prev_snap_obj; uint64_t ds_prev_snap_txg; uint64_t ds_next_snap_obj; uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */ uint64_t ds_num_children; /* clone/snap children; ==0 for head */ uint64_t ds_creation_time; /* seconds since 1970 */ uint64_t ds_creation_txg; uint64_t ds_deadlist_obj; uint64_t ds_used_bytes; uint64_t ds_compressed_bytes; uint64_t ds_uncompressed_bytes; uint64_t ds_unique_bytes; /* only relevant to snapshots */ /* * The ds_fsid_guid is a 56-bit ID that can change to avoid * collisions. The ds_guid is a 64-bit ID that will never * change, so there is a small probability that it will collide. */ uint64_t ds_fsid_guid; uint64_t ds_guid; uint64_t ds_flags; blkptr_t ds_bp; uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */ } dsl_dataset_phys_t; /* * The names of zap entries in the DIRECTORY_OBJECT of the MOS. */ #define DMU_POOL_DIRECTORY_OBJECT 1 #define DMU_POOL_CONFIG "config" #define DMU_POOL_FEATURES_FOR_READ "features_for_read" #define DMU_POOL_ROOT_DATASET "root_dataset" #define DMU_POOL_SYNC_BPLIST "sync_bplist" #define DMU_POOL_ERRLOG_SCRUB "errlog_scrub" #define DMU_POOL_ERRLOG_LAST "errlog_last" #define DMU_POOL_SPARES "spares" #define DMU_POOL_DEFLATE "deflate" #define DMU_POOL_HISTORY "history" #define DMU_POOL_PROPS "pool_props" #define DMU_POOL_CHECKSUM_SALT "org.illumos:checksum_salt" #define DMU_POOL_REMOVING "com.delphix:removing" #define DMU_POOL_OBSOLETE_BPOBJ "com.delphix:obsolete_bpobj" #define DMU_POOL_CONDENSING_INDIRECT "com.delphix:condensing_indirect" #define ZAP_MAGIC 0x2F52AB2ABULL #define FZAP_BLOCK_SHIFT(zap) ((zap)->zap_block_shift) #define ZAP_MAXCD (uint32_t)(-1) #define ZAP_HASHBITS 28 #define MZAP_ENT_LEN 64 #define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2) #define MZAP_MAX_BLKSZ SPA_OLD_MAXBLOCKSIZE typedef struct mzap_ent_phys { uint64_t mze_value; uint32_t mze_cd; uint16_t mze_pad; /* in case we want to chain them someday */ char mze_name[MZAP_NAME_LEN]; } mzap_ent_phys_t; typedef struct mzap_phys { uint64_t mz_block_type; /* ZBT_MICRO */ uint64_t mz_salt; uint64_t mz_normflags; uint64_t mz_pad[5]; mzap_ent_phys_t mz_chunk[1]; /* actually variable size depending on block size */ } mzap_phys_t; /* * The (fat) zap is stored in one object. It is an array of * 1<= 6] [zap_leaf_t] [ptrtbl] ... * */ #define ZBT_LEAF ((1ULL << 63) + 0) #define ZBT_HEADER ((1ULL << 63) + 1) #define ZBT_MICRO ((1ULL << 63) + 3) /* any other values are ptrtbl blocks */ /* * the embedded pointer table takes up half a block: * block size / entry size (2^3) / 2 */ #define ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1) /* * The embedded pointer table starts half-way through the block. Since * the pointer table itself is half the block, it starts at (64-bit) * word number (1<zap_phys) \ [(idx) + (1<l_bs) - hash entry size (2) * number of hash * entries - header space (2*chunksize) */ #define ZAP_LEAF_NUMCHUNKS(l) \ (((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \ ZAP_LEAF_CHUNKSIZE - 2) /* * The amount of space within the chunk available for the array is: * chunk size - space for type (1) - space for next pointer (2) */ #define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) #define ZAP_LEAF_ARRAY_NCHUNKS(bytes) \ (((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES) /* * Low water mark: when there are only this many chunks free, start * growing the ptrtbl. Ideally, this should be larger than a * "reasonably-sized" entry. 20 chunks is more than enough for the * largest directory entry (MAXNAMELEN (256) byte name, 8-byte value), * while still being only around 3% for 16k blocks. */ #define ZAP_LEAF_LOW_WATER (20) /* * The leaf hash table has block size / 2^5 (32) number of entries, * which should be more than enough for the maximum number of entries, * which is less than block size / CHUNKSIZE (24) / minimum number of * chunks per entry (3). */ #define ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5) #define ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l)) /* * The chunks start immediately after the hash table. The end of the * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a * chunk_t. */ #define ZAP_LEAF_CHUNK(l, idx) \ ((zap_leaf_chunk_t *) \ ((l)->l_phys->l_hash + ZAP_LEAF_HASH_NUMENTRIES(l)))[idx] #define ZAP_LEAF_ENTRY(l, idx) (&ZAP_LEAF_CHUNK(l, idx).l_entry) typedef enum zap_chunk_type { ZAP_CHUNK_FREE = 253, ZAP_CHUNK_ENTRY = 252, ZAP_CHUNK_ARRAY = 251, ZAP_CHUNK_TYPE_MAX = 250 } zap_chunk_type_t; /* * TAKE NOTE: * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified. */ typedef struct zap_leaf_phys { struct zap_leaf_header { uint64_t lh_block_type; /* ZBT_LEAF */ uint64_t lh_pad1; uint64_t lh_prefix; /* hash prefix of this leaf */ uint32_t lh_magic; /* ZAP_LEAF_MAGIC */ uint16_t lh_nfree; /* number free chunks */ uint16_t lh_nentries; /* number of entries */ uint16_t lh_prefix_len; /* num bits used to id this */ /* above is accessable to zap, below is zap_leaf private */ uint16_t lh_freelist; /* chunk head of free list */ uint8_t lh_pad2[12]; } l_hdr; /* 2 24-byte chunks */ /* * The header is followed by a hash table with * ZAP_LEAF_HASH_NUMENTRIES(zap) entries. The hash table is * followed by an array of ZAP_LEAF_NUMCHUNKS(zap) * zap_leaf_chunk structures. These structures are accessed * with the ZAP_LEAF_CHUNK() macro. */ uint16_t l_hash[1]; } zap_leaf_phys_t; typedef union zap_leaf_chunk { struct zap_leaf_entry { uint8_t le_type; /* always ZAP_CHUNK_ENTRY */ uint8_t le_value_intlen; /* size of ints */ uint16_t le_next; /* next entry in hash chain */ uint16_t le_name_chunk; /* first chunk of the name */ uint16_t le_name_numints; /* bytes in name, incl null */ uint16_t le_value_chunk; /* first chunk of the value */ uint16_t le_value_numints; /* value length in ints */ uint32_t le_cd; /* collision differentiator */ uint64_t le_hash; /* hash value of the name */ } l_entry; struct zap_leaf_array { uint8_t la_type; /* always ZAP_CHUNK_ARRAY */ uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; uint16_t la_next; /* next blk or CHAIN_END */ } l_array; struct zap_leaf_free { uint8_t lf_type; /* always ZAP_CHUNK_FREE */ uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES]; uint16_t lf_next; /* next in free list, or CHAIN_END */ } l_free; } zap_leaf_chunk_t; typedef struct zap_leaf { int l_bs; /* block size shift */ zap_leaf_phys_t *l_phys; } zap_leaf_t; /* * Define special zfs pflags */ #define ZFS_XATTR 0x1 /* is an extended attribute */ #define ZFS_INHERIT_ACE 0x2 /* ace has inheritable ACEs */ #define ZFS_ACL_TRIVIAL 0x4 /* files ACL is trivial */ #define MASTER_NODE_OBJ 1 /* * special attributes for master node. */ #define ZFS_FSID "FSID" #define ZFS_UNLINKED_SET "DELETE_QUEUE" #define ZFS_ROOT_OBJ "ROOT" #define ZPL_VERSION_OBJ "VERSION" #define ZFS_PROP_BLOCKPERPAGE "BLOCKPERPAGE" #define ZFS_PROP_NOGROWBLOCKS "NOGROWBLOCKS" #define ZFS_FLAG_BLOCKPERPAGE 0x1 #define ZFS_FLAG_NOGROWBLOCKS 0x2 /* * ZPL version - rev'd whenever an incompatible on-disk format change * occurs. Independent of SPA/DMU/ZAP versioning. */ #define ZPL_VERSION 1ULL /* * The directory entry has the type (currently unused on Solaris) in the * top 4 bits, and the object number in the low 48 bits. The "middle" * 12 bits are unused. */ #define ZFS_DIRENT_TYPE(de) BF64_GET(de, 60, 4) #define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48) #define ZFS_DIRENT_MAKE(type, obj) (((uint64_t)type << 60) | obj) typedef struct ace { uid_t a_who; /* uid or gid */ uint32_t a_access_mask; /* read,write,... */ uint16_t a_flags; /* see below */ uint16_t a_type; /* allow or deny */ } ace_t; #define ACE_SLOT_CNT 6 typedef struct zfs_znode_acl { uint64_t z_acl_extern_obj; /* ext acl pieces */ uint32_t z_acl_count; /* Number of ACEs */ uint16_t z_acl_version; /* acl version */ uint16_t z_acl_pad; /* pad */ ace_t z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */ } zfs_znode_acl_t; /* * This is the persistent portion of the znode. It is stored * in the "bonus buffer" of the file. Short symbolic links * are also stored in the bonus buffer. */ typedef struct znode_phys { uint64_t zp_atime[2]; /* 0 - last file access time */ uint64_t zp_mtime[2]; /* 16 - last file modification time */ uint64_t zp_ctime[2]; /* 32 - last file change time */ uint64_t zp_crtime[2]; /* 48 - creation time */ uint64_t zp_gen; /* 64 - generation (txg of creation) */ uint64_t zp_mode; /* 72 - file mode bits */ uint64_t zp_size; /* 80 - size of file */ uint64_t zp_parent; /* 88 - directory parent (`..') */ uint64_t zp_links; /* 96 - number of links to file */ uint64_t zp_xattr; /* 104 - DMU object for xattrs */ uint64_t zp_rdev; /* 112 - dev_t for VBLK & VCHR files */ uint64_t zp_flags; /* 120 - persistent flags */ uint64_t zp_uid; /* 128 - file owner */ uint64_t zp_gid; /* 136 - owning group */ uint64_t zp_pad[4]; /* 144 - future */ zfs_znode_acl_t zp_acl; /* 176 - 263 ACL */ /* * Data may pad out any remaining bytes in the znode buffer, eg: * * |<---------------------- dnode_phys (512) ------------------------>| * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->| * |<---- znode (264) ---->|<---- data (56) ---->| * * At present, we only use this space to store symbolic links. */ } znode_phys_t; /* * In-core vdev representation. */ struct vdev; struct spa; typedef int vdev_phys_read_t(struct vdev *, void *, off_t, void *, size_t); typedef int vdev_phys_write_t(struct vdev *, off_t, void *, size_t); typedef int vdev_read_t(struct vdev *, const blkptr_t *, void *, off_t, size_t); typedef STAILQ_HEAD(vdev_list, vdev) vdev_list_t; typedef struct vdev_indirect_mapping_entry_phys { /* * Decode with DVA_MAPPING_* macros. * Contains: * the source offset (low 63 bits) * the one-bit "mark", used for garbage collection (by zdb) */ uint64_t vimep_src; /* * Note: the DVA's asize is 24 bits, and can thus store ranges * up to 8GB. */ dva_t vimep_dst; } vdev_indirect_mapping_entry_phys_t; #define DVA_MAPPING_GET_SRC_OFFSET(vimep) \ BF64_GET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0) #define DVA_MAPPING_SET_SRC_OFFSET(vimep, x) \ BF64_SET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0, x) typedef struct vdev_indirect_mapping_entry { vdev_indirect_mapping_entry_phys_t vime_mapping; uint32_t vime_obsolete_count; list_node_t vime_node; } vdev_indirect_mapping_entry_t; /* * This is stored in the bonus buffer of the mapping object, see comment of * vdev_indirect_config for more details. */ typedef struct vdev_indirect_mapping_phys { uint64_t vimp_max_offset; uint64_t vimp_bytes_mapped; uint64_t vimp_num_entries; /* number of v_i_m_entry_phys_t's */ /* * For each entry in the mapping object, this object contains an * entry representing the number of bytes of that mapping entry * that were no longer in use by the pool at the time this indirect * vdev was last condensed. */ uint64_t vimp_counts_object; } vdev_indirect_mapping_phys_t; #define VDEV_INDIRECT_MAPPING_SIZE_V0 (3 * sizeof (uint64_t)) typedef struct vdev_indirect_mapping { uint64_t vim_object; boolean_t vim_havecounts; /* vim_entries segment offset currently in memory. */ uint64_t vim_entry_offset; /* vim_entries segment size. */ size_t vim_num_entries; /* Needed by dnode_read() */ const void *vim_spa; dnode_phys_t *vim_dn; /* * An ordered array of mapping entries, sorted by source offset. * Note that vim_entries is needed during a removal (and contains * mappings that have been synced to disk so far) to handle frees * from the removing device. */ vdev_indirect_mapping_entry_phys_t *vim_entries; objset_phys_t *vim_objset; vdev_indirect_mapping_phys_t *vim_phys; } vdev_indirect_mapping_t; /* * On-disk indirect vdev state. * * An indirect vdev is described exclusively in the MOS config of a pool. * The config for an indirect vdev includes several fields, which are * accessed in memory by a vdev_indirect_config_t. */ typedef struct vdev_indirect_config { /* * Object (in MOS) which contains the indirect mapping. This object * contains an array of vdev_indirect_mapping_entry_phys_t ordered by * vimep_src. The bonus buffer for this object is a * vdev_indirect_mapping_phys_t. This object is allocated when a vdev * removal is initiated. * * Note that this object can be empty if none of the data on the vdev * has been copied yet. */ uint64_t vic_mapping_object; /* * Object (in MOS) which contains the birth times for the mapping * entries. This object contains an array of * vdev_indirect_birth_entry_phys_t sorted by vibe_offset. The bonus * buffer for this object is a vdev_indirect_birth_phys_t. This object * is allocated when a vdev removal is initiated. * * Note that this object can be empty if none of the vdev has yet been * copied. */ uint64_t vic_births_object; /* * This is the vdev ID which was removed previous to this vdev, or * UINT64_MAX if there are no previously removed vdevs. */ uint64_t vic_prev_indirect_vdev; } vdev_indirect_config_t; typedef struct vdev { STAILQ_ENTRY(vdev) v_childlink; /* link in parent's child list */ STAILQ_ENTRY(vdev) v_alllink; /* link in global vdev list */ vdev_list_t v_children; /* children of this vdev */ const char *v_name; /* vdev name */ const char *v_phys_path; /* vdev bootpath */ const char *v_devid; /* vdev devid */ uint64_t v_guid; /* vdev guid */ uint64_t v_id; /* index in parent */ uint64_t v_psize; /* physical device capacity */ int v_ashift; /* offset to block shift */ int v_nparity; /* # parity for raidz */ struct vdev *v_top; /* parent vdev */ size_t v_nchildren; /* # children */ vdev_state_t v_state; /* current state */ vdev_phys_read_t *v_phys_read; /* read from raw leaf vdev */ vdev_phys_write_t *v_phys_write; /* write to raw leaf vdev */ vdev_read_t *v_read; /* read from vdev */ void *v_priv; /* data for read/write function */ boolean_t v_islog; struct spa *v_spa; /* link to spa */ /* * Values stored in the config for an indirect or removing vdev. */ vdev_indirect_config_t vdev_indirect_config; vdev_indirect_mapping_t *v_mapping; } vdev_t; /* * In-core pool representation. */ typedef STAILQ_HEAD(spa_list, spa) spa_list_t; typedef struct spa { STAILQ_ENTRY(spa) spa_link; /* link in global pool list */ char *spa_name; /* pool name */ uint64_t spa_guid; /* pool guid */ uint64_t spa_txg; /* most recent transaction */ struct uberblock spa_uberblock; /* best uberblock so far */ vdev_t *spa_root_vdev; /* toplevel vdev container */ objset_phys_t spa_mos; /* MOS for this pool */ zio_cksum_salt_t spa_cksum_salt; /* secret salt for cksum */ void *spa_cksum_tmpls[ZIO_CHECKSUM_FUNCTIONS]; vdev_t *spa_boot_vdev; /* boot device for kernel */ boolean_t spa_with_log; /* this pool has log */ void *spa_bootenv; /* bootenv from pool label */ } spa_t; /* IO related arguments. */ typedef struct zio { spa_t *io_spa; blkptr_t *io_bp; void *io_data; uint64_t io_size; uint64_t io_offset; /* Stuff for the vdev stack */ vdev_t *io_vd; void *io_vsd; int io_error; } zio_t; extern void decode_embedded_bp_compressed(const blkptr_t *, void *); #endif /* _ZFSIMPL_H_ */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include static uint64_t zfs_crc64_table[256]; #define ECKSUM 666 #define ASSERT3S(x, y, z) ((void)0) #define ASSERT3U(x, y, z) ((void)0) #define ASSERT3P(x, y, z) ((void)0) #define ASSERT0(x) ((void)0) #define ASSERT(x) ((void)0) static void zfs_init_crc(void) { int i, j; uint64_t *ct; /* * Calculate the crc64 table (used for the zap hash * function). */ if (zfs_crc64_table[128] != ZFS_CRC64_POLY) { memset(zfs_crc64_table, 0, sizeof (zfs_crc64_table)); for (i = 0; i < 256; i++) { ct = zfs_crc64_table + i; for (*ct = i, j = 8; j > 0; j--) *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY); } } } static void zio_checksum_off(const void *buf __unused, uint64_t size __unused, const void *ctx_template __unused, zio_cksum_t *zcp) { ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0); } /* * Signature for checksum functions. */ typedef void zio_checksum_t(const void *data, uint64_t size, const void *ctx_template, zio_cksum_t *zcp); typedef void *zio_checksum_tmpl_init_t(const zio_cksum_salt_t *salt); typedef void zio_checksum_tmpl_free_t(void *ctx_template); typedef enum zio_checksum_flags { /* Strong enough for metadata? */ ZCHECKSUM_FLAG_METADATA = (1 << 1), /* ZIO embedded checksum */ ZCHECKSUM_FLAG_EMBEDDED = (1 << 2), /* Strong enough for dedup (without verification)? */ ZCHECKSUM_FLAG_DEDUP = (1 << 3), /* Uses salt value */ ZCHECKSUM_FLAG_SALTED = (1 << 4), /* Strong enough for nopwrite? */ ZCHECKSUM_FLAG_NOPWRITE = (1 << 5) } zio_checksum_flags_t; /* * Information about each checksum function. */ typedef struct zio_checksum_info { /* checksum function for each byteorder */ zio_checksum_t *ci_func[2]; zio_checksum_tmpl_init_t *ci_tmpl_init; zio_checksum_tmpl_free_t *ci_tmpl_free; zio_checksum_flags_t ci_flags; const char *ci_name; /* descriptive name */ } zio_checksum_info_t; #include "blkptr.c" #include "fletcher.c" #include "sha256.c" #include "skein_zfs.c" #include "edonr_zfs.c" static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { {{NULL, NULL}, NULL, NULL, 0, "inherit"}, {{NULL, NULL}, NULL, NULL, 0, "on"}, {{zio_checksum_off, zio_checksum_off}, NULL, NULL, 0, "off"}, {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "label"}, {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "gang_header"}, {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL, ZCHECKSUM_FLAG_EMBEDDED, "zilog"}, {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL, 0, "fletcher2"}, {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL, ZCHECKSUM_FLAG_METADATA, "fletcher4"}, {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP | ZCHECKSUM_FLAG_NOPWRITE, "SHA256"}, {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL, ZCHECKSUM_FLAG_EMBEDDED, "zillog2"}, {{zio_checksum_off, zio_checksum_off}, NULL, NULL, 0, "noparity"}, {{zio_checksum_SHA512_native, zio_checksum_SHA512_byteswap}, NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP | ZCHECKSUM_FLAG_NOPWRITE, "SHA512"}, /* no skein and edonr for now */ {{zio_checksum_skein_native, zio_checksum_skein_byteswap}, zio_checksum_skein_tmpl_init, zio_checksum_skein_tmpl_free, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP | ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "skein"}, {{zio_checksum_edonr_native, zio_checksum_edonr_byteswap}, zio_checksum_edonr_tmpl_init, zio_checksum_edonr_tmpl_free, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"}, }; /* * Common signature for all zio compress/decompress functions. */ typedef size_t zio_compress_func_t(void *src, void *dst, size_t s_len, size_t d_len, int); typedef int zio_decompress_func_t(void *src, void *dst, size_t s_len, size_t d_len, int); extern int gzip_decompress(void *src, void *dst, size_t s_len, size_t d_len, int); /* * Information about each compression function. */ typedef struct zio_compress_info { zio_compress_func_t *ci_compress; /* compression function */ zio_decompress_func_t *ci_decompress; /* decompression function */ int ci_level; /* level parameter */ const char *ci_name; /* algorithm name */ } zio_compress_info_t; #include "lzjb.c" #include "zle.c" /* * Compression vectors. */ static zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = { {NULL, NULL, 0, "inherit"}, {NULL, NULL, 0, "on"}, {NULL, NULL, 0, "uncompressed"}, {NULL, lzjb_decompress, 0, "lzjb"}, {NULL, NULL, 0, "empty"}, {NULL, gzip_decompress, 1, "gzip-1"}, {NULL, gzip_decompress, 2, "gzip-2"}, {NULL, gzip_decompress, 3, "gzip-3"}, {NULL, gzip_decompress, 4, "gzip-4"}, {NULL, gzip_decompress, 5, "gzip-5"}, {NULL, gzip_decompress, 6, "gzip-6"}, {NULL, gzip_decompress, 7, "gzip-7"}, {NULL, gzip_decompress, 8, "gzip-8"}, {NULL, gzip_decompress, 9, "gzip-9"}, {NULL, zle_decompress, 64, "zle"}, {NULL, lz4_decompress, 0, "lz4"}, }; static void byteswap_uint64_array(void *vbuf, size_t size) { uint64_t *buf = vbuf; size_t count = size >> 3; int i; ASSERT((size & 7) == 0); for (i = 0; i < count; i++) buf[i] = BSWAP_64(buf[i]); } /* * Set the external verifier for a gang block based on , * a tuple which is guaranteed to be unique for the life of the pool. */ static void zio_checksum_gang_verifier(zio_cksum_t *zcp, const blkptr_t *bp) { const dva_t *dva = BP_IDENTITY(bp); uint64_t txg = BP_PHYSICAL_BIRTH(bp); ASSERT(BP_IS_GANG(bp)); ZIO_SET_CHECKSUM(zcp, DVA_GET_VDEV(dva), DVA_GET_OFFSET(dva), txg, 0); } /* * Set the external verifier for a label block based on its offset. * The vdev is implicit, and the txg is unknowable at pool open time -- * hence the logic in vdev_uberblock_load() to find the most recent copy. */ static void zio_checksum_label_verifier(zio_cksum_t *zcp, uint64_t offset) { ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0); } /* * Calls the template init function of a checksum which supports context * templates and installs the template into the spa_t. */ static void zio_checksum_template_init(enum zio_checksum checksum, spa_t *spa) { zio_checksum_info_t *ci = &zio_checksum_table[checksum]; if (ci->ci_tmpl_init == NULL) return; if (spa->spa_cksum_tmpls[checksum] != NULL) return; if (spa->spa_cksum_tmpls[checksum] == NULL) { spa->spa_cksum_tmpls[checksum] = ci->ci_tmpl_init(&spa->spa_cksum_salt); } } /* * Called by a spa_t that's about to be deallocated. This steps through * all of the checksum context templates and deallocates any that were * initialized using the algorithm-specific template init function. */ void zio_checksum_templates_free(spa_t *spa) { for (enum zio_checksum checksum = 0; checksum < ZIO_CHECKSUM_FUNCTIONS; checksum++) { if (spa->spa_cksum_tmpls[checksum] != NULL) { zio_checksum_info_t *ci = &zio_checksum_table[checksum]; ci->ci_tmpl_free(spa->spa_cksum_tmpls[checksum]); spa->spa_cksum_tmpls[checksum] = NULL; } } } static int zio_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data) { uint64_t size; unsigned int checksum; zio_checksum_info_t *ci; void *ctx = NULL; zio_cksum_t actual_cksum, expected_cksum, verifier; int byteswap; checksum = BP_GET_CHECKSUM(bp); size = BP_GET_PSIZE(bp); if (checksum >= ZIO_CHECKSUM_FUNCTIONS) return (EINVAL); ci = &zio_checksum_table[checksum]; if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL) return (EINVAL); if (spa != NULL) { zio_checksum_template_init(checksum, (spa_t *)spa); ctx = spa->spa_cksum_tmpls[checksum]; } if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) { zio_eck_t *eck; ASSERT(checksum == ZIO_CHECKSUM_GANG_HEADER || checksum == ZIO_CHECKSUM_LABEL); eck = (zio_eck_t *)((char *)data + size) - 1; if (checksum == ZIO_CHECKSUM_GANG_HEADER) zio_checksum_gang_verifier(&verifier, bp); else if (checksum == ZIO_CHECKSUM_LABEL) zio_checksum_label_verifier(&verifier, DVA_GET_OFFSET(BP_IDENTITY(bp))); else verifier = bp->blk_cksum; byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC)); if (byteswap) byteswap_uint64_array(&verifier, sizeof (zio_cksum_t)); expected_cksum = eck->zec_cksum; eck->zec_cksum = verifier; ci->ci_func[byteswap](data, size, ctx, &actual_cksum); eck->zec_cksum = expected_cksum; if (byteswap) byteswap_uint64_array(&expected_cksum, sizeof (zio_cksum_t)); } else { byteswap = BP_SHOULD_BYTESWAP(bp); expected_cksum = bp->blk_cksum; ci->ci_func[byteswap](data, size, ctx, &actual_cksum); } if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) { /* printf("ZFS: read checksum %s failed\n", ci->ci_name); */ return (EIO); } return (0); } static int zio_decompress_data(int cpfunc, void *src, uint64_t srcsize, void *dest, uint64_t destsize) { zio_compress_info_t *ci; if (cpfunc >= ZIO_COMPRESS_FUNCTIONS) { printf("ZFS: unsupported compression algorithm %u\n", cpfunc); return (EIO); } ci = &zio_compress_table[cpfunc]; if (!ci->ci_decompress) { printf("ZFS: unsupported compression algorithm %s\n", ci->ci_name); return (EIO); } return (ci->ci_decompress(src, dest, srcsize, destsize, ci->ci_level)); } static uint64_t zap_hash(uint64_t salt, const char *name) { const uint8_t *cp; uint8_t c; uint64_t crc = salt; ASSERT(crc != 0); ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY); for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++) crc = (crc >> 8) ^ zfs_crc64_table[(crc ^ c) & 0xFF]; /* * Only use 28 bits, since we need 4 bits in the cookie for the * collision differentiator. We MUST use the high bits, since * those are the onces that we first pay attention to when * chosing the bucket. */ crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1); return (crc); } typedef struct raidz_col { uint64_t rc_devidx; /* child device index for I/O */ uint64_t rc_offset; /* device offset */ uint64_t rc_size; /* I/O size */ void *rc_data; /* I/O data */ int rc_error; /* I/O error for this device */ uint8_t rc_tried; /* Did we attempt this I/O column? */ uint8_t rc_skipped; /* Did we skip this I/O column? */ } raidz_col_t; typedef struct raidz_map { uint64_t rm_cols; /* Regular column count */ uint64_t rm_scols; /* Count including skipped columns */ uint64_t rm_bigcols; /* Number of oversized columns */ uint64_t rm_asize; /* Actual total I/O size */ uint64_t rm_missingdata; /* Count of missing data devices */ uint64_t rm_missingparity; /* Count of missing parity devices */ uint64_t rm_firstdatacol; /* First data column/parity count */ uint64_t rm_nskip; /* Skipped sectors for padding */ uint64_t rm_skipstart; /* Column index of padding start */ uintptr_t rm_reports; /* # of referencing checksum reports */ uint8_t rm_freed; /* map no longer has referencing ZIO */ uint8_t rm_ecksuminjected; /* checksum error was injected */ raidz_col_t rm_col[1]; /* Flexible array of I/O columns */ } raidz_map_t; #define VDEV_RAIDZ_P 0 #define VDEV_RAIDZ_Q 1 #define VDEV_RAIDZ_R 2 #define VDEV_RAIDZ_MUL_2(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1d : 0)) #define VDEV_RAIDZ_MUL_4(x) (VDEV_RAIDZ_MUL_2(VDEV_RAIDZ_MUL_2(x))) /* * We provide a mechanism to perform the field multiplication operation on a * 64-bit value all at once rather than a byte at a time. This works by * creating a mask from the top bit in each byte and using that to * conditionally apply the XOR of 0x1d. */ #define VDEV_RAIDZ_64MUL_2(x, mask) \ { \ (mask) = (x) & 0x8080808080808080ULL; \ (mask) = ((mask) << 1) - ((mask) >> 7); \ (x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \ ((mask) & 0x1d1d1d1d1d1d1d1dULL); \ } #define VDEV_RAIDZ_64MUL_4(x, mask) \ { \ VDEV_RAIDZ_64MUL_2((x), mask); \ VDEV_RAIDZ_64MUL_2((x), mask); \ } /* * These two tables represent powers and logs of 2 in the Galois field defined * above. These values were computed by repeatedly multiplying by 2 as above. */ static const uint8_t vdev_raidz_pow2[256] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01 }; static const uint8_t vdev_raidz_log2[256] = { 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18, 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf, }; /* * Multiply a given number by 2 raised to the given power. */ static uint8_t vdev_raidz_exp2(uint8_t a, int exp) { if (a == 0) return (0); ASSERT(exp >= 0); ASSERT(vdev_raidz_log2[a] > 0 || a == 1); exp += vdev_raidz_log2[a]; if (exp > 255) exp -= 255; return (vdev_raidz_pow2[exp]); } static void vdev_raidz_generate_parity_p(raidz_map_t *rm) { uint64_t *p, *src, pcount __attribute__((unused)), ccount, i; int c; pcount = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { src = rm->rm_col[c].rc_data; p = rm->rm_col[VDEV_RAIDZ_P].rc_data; ccount = rm->rm_col[c].rc_size / sizeof (src[0]); if (c == rm->rm_firstdatacol) { ASSERT(ccount == pcount); for (i = 0; i < ccount; i++, src++, p++) { *p = *src; } } else { ASSERT(ccount <= pcount); for (i = 0; i < ccount; i++, src++, p++) { *p ^= *src; } } } } static void vdev_raidz_generate_parity_pq(raidz_map_t *rm) { uint64_t *p, *q, *src, pcnt, ccnt, mask, i; int c; pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == rm->rm_col[VDEV_RAIDZ_Q].rc_size); for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { src = rm->rm_col[c].rc_data; p = rm->rm_col[VDEV_RAIDZ_P].rc_data; q = rm->rm_col[VDEV_RAIDZ_Q].rc_data; ccnt = rm->rm_col[c].rc_size / sizeof (src[0]); if (c == rm->rm_firstdatacol) { ASSERT(ccnt == pcnt || ccnt == 0); for (i = 0; i < ccnt; i++, src++, p++, q++) { *p = *src; *q = *src; } for (; i < pcnt; i++, src++, p++, q++) { *p = 0; *q = 0; } } else { ASSERT(ccnt <= pcnt); /* * Apply the algorithm described above by multiplying * the previous result and adding in the new value. */ for (i = 0; i < ccnt; i++, src++, p++, q++) { *p ^= *src; VDEV_RAIDZ_64MUL_2(*q, mask); *q ^= *src; } /* * Treat short columns as though they are full of 0s. * Note that there's therefore nothing needed for P. */ for (; i < pcnt; i++, q++) { VDEV_RAIDZ_64MUL_2(*q, mask); } } } } static void vdev_raidz_generate_parity_pqr(raidz_map_t *rm) { uint64_t *p, *q, *r, *src, pcnt, ccnt, mask, i; int c; pcnt = rm->rm_col[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == rm->rm_col[VDEV_RAIDZ_Q].rc_size); ASSERT(rm->rm_col[VDEV_RAIDZ_P].rc_size == rm->rm_col[VDEV_RAIDZ_R].rc_size); for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { src = rm->rm_col[c].rc_data; p = rm->rm_col[VDEV_RAIDZ_P].rc_data; q = rm->rm_col[VDEV_RAIDZ_Q].rc_data; r = rm->rm_col[VDEV_RAIDZ_R].rc_data; ccnt = rm->rm_col[c].rc_size / sizeof (src[0]); if (c == rm->rm_firstdatacol) { ASSERT(ccnt == pcnt || ccnt == 0); for (i = 0; i < ccnt; i++, src++, p++, q++, r++) { *p = *src; *q = *src; *r = *src; } for (; i < pcnt; i++, src++, p++, q++, r++) { *p = 0; *q = 0; *r = 0; } } else { ASSERT(ccnt <= pcnt); /* * Apply the algorithm described above by multiplying * the previous result and adding in the new value. */ for (i = 0; i < ccnt; i++, src++, p++, q++, r++) { *p ^= *src; VDEV_RAIDZ_64MUL_2(*q, mask); *q ^= *src; VDEV_RAIDZ_64MUL_4(*r, mask); *r ^= *src; } /* * Treat short columns as though they are full of 0s. * Note that there's therefore nothing needed for P. */ for (; i < pcnt; i++, q++, r++) { VDEV_RAIDZ_64MUL_2(*q, mask); VDEV_RAIDZ_64MUL_4(*r, mask); } } } } /* * Generate RAID parity in the first virtual columns according to the number of * parity columns available. */ static void vdev_raidz_generate_parity(raidz_map_t *rm) { switch (rm->rm_firstdatacol) { case 1: vdev_raidz_generate_parity_p(rm); break; case 2: vdev_raidz_generate_parity_pq(rm); break; case 3: vdev_raidz_generate_parity_pqr(rm); break; default: panic("invalid RAID-Z configuration"); } } /* BEGIN CSTYLED */ /* * In the general case of reconstruction, we must solve the system of linear * equations defined by the coeffecients used to generate parity as well as * the contents of the data and parity disks. This can be expressed with * vectors for the original data (D) and the actual data (d) and parity (p) * and a matrix composed of the identity matrix (I) and a dispersal matrix (V): * * __ __ __ __ * | | __ __ | p_0 | * | V | | D_0 | | p_m-1 | * | | x | : | = | d_0 | * | I | | D_n-1 | | : | * | | ~~ ~~ | d_n-1 | * ~~ ~~ ~~ ~~ * * I is simply a square identity matrix of size n, and V is a vandermonde * matrix defined by the coeffecients we chose for the various parity columns * (1, 2, 4). Note that these values were chosen both for simplicity, speedy * computation as well as linear separability. * * __ __ __ __ * | 1 .. 1 1 1 | | p_0 | * | 2^n-1 .. 4 2 1 | __ __ | : | * | 4^n-1 .. 16 4 1 | | D_0 | | p_m-1 | * | 1 .. 0 0 0 | | D_1 | | d_0 | * | 0 .. 0 0 0 | x | D_2 | = | d_1 | * | : : : : | | : | | d_2 | * | 0 .. 1 0 0 | | D_n-1 | | : | * | 0 .. 0 1 0 | ~~ ~~ | : | * | 0 .. 0 0 1 | | d_n-1 | * ~~ ~~ ~~ ~~ * * Note that I, V, d, and p are known. To compute D, we must invert the * matrix and use the known data and parity values to reconstruct the unknown * data values. We begin by removing the rows in V|I and d|p that correspond * to failed or missing columns; we then make V|I square (n x n) and d|p * sized n by removing rows corresponding to unused parity from the bottom up * to generate (V|I)' and (d|p)'. We can then generate the inverse of (V|I)' * using Gauss-Jordan elimination. In the example below we use m=3 parity * columns, n=8 data columns, with errors in d_1, d_2, and p_1: * __ __ * | 1 1 1 1 1 1 1 1 | * | 128 64 32 16 8 4 2 1 | <-----+-+-- missing disks * | 19 205 116 29 64 16 4 1 | / / * | 1 0 0 0 0 0 0 0 | / / * | 0 1 0 0 0 0 0 0 | <--' / * (V|I) = | 0 0 1 0 0 0 0 0 | <---' * | 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 1 1 1 1 1 1 1 | * | 128 64 32 16 8 4 2 1 | * | 19 205 116 29 64 16 4 1 | * | 1 0 0 0 0 0 0 0 | * | 0 1 0 0 0 0 0 0 | * (V|I)' = | 0 0 1 0 0 0 0 0 | * | 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 | * ~~ ~~ * * Here we employ Gauss-Jordan elimination to find the inverse of (V|I)'. We * have carefully chosen the seed values 1, 2, and 4 to ensure that this * matrix is not singular. * __ __ * | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 | * | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 | * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 | * | 19 205 116 29 64 16 4 1 0 1 0 0 0 0 0 0 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | * | 0 205 116 0 0 0 0 0 0 1 19 29 64 16 4 1 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | * | 0 0 185 0 0 0 0 0 205 1 222 208 141 221 201 204 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 | * | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 | * | 0 1 0 0 0 0 0 0 167 100 5 41 159 169 217 208 | * | 0 0 1 0 0 0 0 0 166 100 4 40 158 168 216 209 | * | 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 | * ~~ ~~ * __ __ * | 0 0 1 0 0 0 0 0 | * | 167 100 5 41 159 169 217 208 | * | 166 100 4 40 158 168 216 209 | * (V|I)'^-1 = | 0 0 0 1 0 0 0 0 | * | 0 0 0 0 1 0 0 0 | * | 0 0 0 0 0 1 0 0 | * | 0 0 0 0 0 0 1 0 | * | 0 0 0 0 0 0 0 1 | * ~~ ~~ * * We can then simply compute D = (V|I)'^-1 x (d|p)' to discover the values * of the missing data. * * As is apparent from the example above, the only non-trivial rows in the * inverse matrix correspond to the data disks that we're trying to * reconstruct. Indeed, those are the only rows we need as the others would * only be useful for reconstructing data known or assumed to be valid. For * that reason, we only build the coefficients in the rows that correspond to * targeted columns. */ /* END CSTYLED */ static void vdev_raidz_matrix_init(raidz_map_t *rm __unused, int n, int nmap, int *map, uint8_t **rows) { int i, j; int pow; ASSERT(n == rm->rm_cols - rm->rm_firstdatacol); /* * Fill in the missing rows of interest. */ for (i = 0; i < nmap; i++) { ASSERT3S(0, <=, map[i]); ASSERT3S(map[i], <=, 2); pow = map[i] * n; if (pow > 255) pow -= 255; ASSERT(pow <= 255); for (j = 0; j < n; j++) { pow -= map[i]; if (pow < 0) pow += 255; rows[i][j] = vdev_raidz_pow2[pow]; } } } static void vdev_raidz_matrix_invert(raidz_map_t *rm, int n, int nmissing, int *missing, uint8_t **rows, uint8_t **invrows, const uint8_t *used) { int i, j, ii, jj; uint8_t log; /* * Assert that the first nmissing entries from the array of used * columns correspond to parity columns and that subsequent entries * correspond to data columns. */ for (i = 0; i < nmissing; i++) { ASSERT3S(used[i], <, rm->rm_firstdatacol); } for (; i < n; i++) { ASSERT3S(used[i], >=, rm->rm_firstdatacol); } /* * First initialize the storage where we'll compute the inverse rows. */ for (i = 0; i < nmissing; i++) { for (j = 0; j < n; j++) { invrows[i][j] = (i == j) ? 1 : 0; } } /* * Subtract all trivial rows from the rows of consequence. */ for (i = 0; i < nmissing; i++) { for (j = nmissing; j < n; j++) { ASSERT3U(used[j], >=, rm->rm_firstdatacol); jj = used[j] - rm->rm_firstdatacol; ASSERT3S(jj, <, n); invrows[i][j] = rows[i][jj]; rows[i][jj] = 0; } } /* * For each of the rows of interest, we must normalize it and subtract * a multiple of it from the other rows. */ for (i = 0; i < nmissing; i++) { for (j = 0; j < missing[i]; j++) { ASSERT3U(rows[i][j], ==, 0); } ASSERT3U(rows[i][missing[i]], !=, 0); /* * Compute the inverse of the first element and multiply each * element in the row by that value. */ log = 255 - vdev_raidz_log2[rows[i][missing[i]]]; for (j = 0; j < n; j++) { rows[i][j] = vdev_raidz_exp2(rows[i][j], log); invrows[i][j] = vdev_raidz_exp2(invrows[i][j], log); } for (ii = 0; ii < nmissing; ii++) { if (i == ii) continue; ASSERT3U(rows[ii][missing[i]], !=, 0); log = vdev_raidz_log2[rows[ii][missing[i]]]; for (j = 0; j < n; j++) { rows[ii][j] ^= vdev_raidz_exp2(rows[i][j], log); invrows[ii][j] ^= vdev_raidz_exp2(invrows[i][j], log); } } } /* * Verify that the data that is left in the rows are properly part of * an identity matrix. */ for (i = 0; i < nmissing; i++) { for (j = 0; j < n; j++) { if (j == missing[i]) { ASSERT3U(rows[i][j], ==, 1); } else { ASSERT3U(rows[i][j], ==, 0); } } } } static void vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing, int *missing, uint8_t **invrows, const uint8_t *used) { int i, j, x, cc, c; uint8_t *src; uint64_t ccount; uint8_t *dst[VDEV_RAIDZ_MAXPARITY]; uint64_t dcount[VDEV_RAIDZ_MAXPARITY]; uint8_t log, val; int ll; uint8_t *invlog[VDEV_RAIDZ_MAXPARITY]; uint8_t *p, *pp; size_t psize; log = 0; /* gcc */ psize = sizeof (invlog[0][0]) * n * nmissing; p = malloc(psize); if (p == NULL) { printf("Out of memory\n"); return; } for (pp = p, i = 0; i < nmissing; i++) { invlog[i] = pp; pp += n; } for (i = 0; i < nmissing; i++) { for (j = 0; j < n; j++) { ASSERT3U(invrows[i][j], !=, 0); invlog[i][j] = vdev_raidz_log2[invrows[i][j]]; } } for (i = 0; i < n; i++) { c = used[i]; ASSERT3U(c, <, rm->rm_cols); src = rm->rm_col[c].rc_data; ccount = rm->rm_col[c].rc_size; for (j = 0; j < nmissing; j++) { cc = missing[j] + rm->rm_firstdatacol; ASSERT3U(cc, >=, rm->rm_firstdatacol); ASSERT3U(cc, <, rm->rm_cols); ASSERT3U(cc, !=, c); dst[j] = rm->rm_col[cc].rc_data; dcount[j] = rm->rm_col[cc].rc_size; } ASSERT(ccount >= rm->rm_col[missing[0]].rc_size || i > 0); for (x = 0; x < ccount; x++, src++) { if (*src != 0) log = vdev_raidz_log2[*src]; for (cc = 0; cc < nmissing; cc++) { if (x >= dcount[cc]) continue; if (*src == 0) { val = 0; } else { if ((ll = log + invlog[cc][i]) >= 255) ll -= 255; val = vdev_raidz_pow2[ll]; } if (i == 0) dst[cc][x] = val; else dst[cc][x] ^= val; } } } free(p); } static int vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts) { int n, i, c, t, tt; int nmissing_rows; int missing_rows[VDEV_RAIDZ_MAXPARITY]; int parity_map[VDEV_RAIDZ_MAXPARITY]; uint8_t *p, *pp; size_t psize; uint8_t *rows[VDEV_RAIDZ_MAXPARITY]; uint8_t *invrows[VDEV_RAIDZ_MAXPARITY]; uint8_t *used; int code = 0; n = rm->rm_cols - rm->rm_firstdatacol; /* * Figure out which data columns are missing. */ nmissing_rows = 0; for (t = 0; t < ntgts; t++) { if (tgts[t] >= rm->rm_firstdatacol) { missing_rows[nmissing_rows++] = tgts[t] - rm->rm_firstdatacol; } } /* * Figure out which parity columns to use to help generate the missing * data columns. */ for (tt = 0, c = 0, i = 0; i < nmissing_rows; c++) { ASSERT(tt < ntgts); ASSERT(c < rm->rm_firstdatacol); /* * Skip any targeted parity columns. */ if (c == tgts[tt]) { tt++; continue; } code |= 1 << c; parity_map[i] = c; i++; } ASSERT(code != 0); ASSERT3U(code, <, 1 << VDEV_RAIDZ_MAXPARITY); psize = (sizeof (rows[0][0]) + sizeof (invrows[0][0])) * nmissing_rows * n + sizeof (used[0]) * n; p = malloc(psize); if (p == NULL) { printf("Out of memory\n"); return (code); } for (pp = p, i = 0; i < nmissing_rows; i++) { rows[i] = pp; pp += n; invrows[i] = pp; pp += n; } used = pp; for (i = 0; i < nmissing_rows; i++) { used[i] = parity_map[i]; } for (tt = 0, c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { if (tt < nmissing_rows && c == missing_rows[tt] + rm->rm_firstdatacol) { tt++; continue; } ASSERT3S(i, <, n); used[i] = c; i++; } /* * Initialize the interesting rows of the matrix. */ vdev_raidz_matrix_init(rm, n, nmissing_rows, parity_map, rows); /* * Invert the matrix. */ vdev_raidz_matrix_invert(rm, n, nmissing_rows, missing_rows, rows, invrows, used); /* * Reconstruct the missing data using the generated matrix. */ vdev_raidz_matrix_reconstruct(rm, n, nmissing_rows, missing_rows, invrows, used); free(p); return (code); } static int vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt) { int tgts[VDEV_RAIDZ_MAXPARITY]; int ntgts; int i, c; int code; int nbadparity, nbaddata; /* * The tgts list must already be sorted. */ for (i = 1; i < nt; i++) { ASSERT(t[i] > t[i - 1]); } nbadparity = rm->rm_firstdatacol; nbaddata = rm->rm_cols - nbadparity; ntgts = 0; for (i = 0, c = 0; c < rm->rm_cols; c++) { if (i < nt && c == t[i]) { tgts[ntgts++] = c; i++; } else if (rm->rm_col[c].rc_error != 0) { tgts[ntgts++] = c; } else if (c >= rm->rm_firstdatacol) { nbaddata--; } else { nbadparity--; } } ASSERT(ntgts >= nt); ASSERT(nbaddata >= 0); ASSERT(nbaddata + nbadparity == ntgts); code = vdev_raidz_reconstruct_general(rm, tgts, ntgts); ASSERT(code < (1 << VDEV_RAIDZ_MAXPARITY)); ASSERT(code > 0); return (code); } static raidz_map_t * vdev_raidz_map_alloc(void *data, off_t offset, size_t size, uint64_t unit_shift, uint64_t dcols, uint64_t nparity) { raidz_map_t *rm; uint64_t b = offset >> unit_shift; uint64_t s = size >> unit_shift; uint64_t f = b % dcols; uint64_t o = (b / dcols) << unit_shift; uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot; q = s / (dcols - nparity); r = s - q * (dcols - nparity); bc = (r == 0 ? 0 : r + nparity); tot = s + nparity * (q + (r == 0 ? 0 : 1)); if (q == 0) { acols = bc; scols = MIN(dcols, roundup(bc, nparity + 1)); } else { acols = dcols; scols = dcols; } ASSERT3U(acols, <=, scols); rm = malloc(offsetof(raidz_map_t, rm_col[scols])); if (rm == NULL) return (rm); rm->rm_cols = acols; rm->rm_scols = scols; rm->rm_bigcols = bc; rm->rm_skipstart = bc; rm->rm_missingdata = 0; rm->rm_missingparity = 0; rm->rm_firstdatacol = nparity; rm->rm_reports = 0; rm->rm_freed = 0; rm->rm_ecksuminjected = 0; asize = 0; for (c = 0; c < scols; c++) { col = f + c; coff = o; if (col >= dcols) { col -= dcols; coff += 1ULL << unit_shift; } rm->rm_col[c].rc_devidx = col; rm->rm_col[c].rc_offset = coff; rm->rm_col[c].rc_data = NULL; rm->rm_col[c].rc_error = 0; rm->rm_col[c].rc_tried = 0; rm->rm_col[c].rc_skipped = 0; if (c >= acols) rm->rm_col[c].rc_size = 0; else if (c < bc) rm->rm_col[c].rc_size = (q + 1) << unit_shift; else rm->rm_col[c].rc_size = q << unit_shift; asize += rm->rm_col[c].rc_size; } ASSERT3U(asize, ==, tot << unit_shift); rm->rm_asize = roundup(asize, (nparity + 1) << unit_shift); rm->rm_nskip = roundup(tot, nparity + 1) - tot; ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift); ASSERT3U(rm->rm_nskip, <=, nparity); for (c = 0; c < rm->rm_firstdatacol; c++) { rm->rm_col[c].rc_data = malloc(rm->rm_col[c].rc_size); if (rm->rm_col[c].rc_data == NULL) { c++; while (c != 0) free(rm->rm_col[--c].rc_data); free(rm); return (NULL); } } rm->rm_col[c].rc_data = data; for (c = c + 1; c < acols; c++) rm->rm_col[c].rc_data = (char *)rm->rm_col[c - 1].rc_data + rm->rm_col[c - 1].rc_size; /* * If all data stored spans all columns, there's a danger that parity * will always be on the same device and, since parity isn't read * during normal operation, that that device's I/O bandwidth won't be * used effectively. We therefore switch the parity every 1MB. * * ... at least that was, ostensibly, the theory. As a practical * matter unless we juggle the parity between all devices evenly, we * won't see any benefit. Further, occasional writes that aren't a * multiple of the LCM of the number of children and the minimum * stripe width are sufficient to avoid pessimal behavior. * Unfortunately, this decision created an implicit on-disk format * requirement that we need to support for all eternity, but only * for single-parity RAID-Z. * * If we intend to skip a sector in the zeroth column for padding * we must make sure to note this swap. We will never intend to * skip the first column since at least one data and one parity * column must appear in each row. */ ASSERT(rm->rm_cols >= 2); ASSERT(rm->rm_col[0].rc_size == rm->rm_col[1].rc_size); if (rm->rm_firstdatacol == 1 && (offset & (1ULL << 20))) { devidx = rm->rm_col[0].rc_devidx; o = rm->rm_col[0].rc_offset; rm->rm_col[0].rc_devidx = rm->rm_col[1].rc_devidx; rm->rm_col[0].rc_offset = rm->rm_col[1].rc_offset; rm->rm_col[1].rc_devidx = devidx; rm->rm_col[1].rc_offset = o; if (rm->rm_skipstart == 0) rm->rm_skipstart = 1; } return (rm); } static void vdev_raidz_map_free(raidz_map_t *rm) { int c; for (c = rm->rm_firstdatacol - 1; c >= 0; c--) free(rm->rm_col[c].rc_data); free(rm); } static vdev_t * vdev_child(vdev_t *pvd, uint64_t devidx) { vdev_t *cvd; STAILQ_FOREACH(cvd, &pvd->v_children, v_childlink) { if (cvd->v_id == devidx) break; } return (cvd); } /* * We keep track of whether or not there were any injected errors, so that * any ereports we generate can note it. */ static int raidz_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data, uint64_t size __unused) { return (zio_checksum_verify(spa, bp, data)); } /* * Generate the parity from the data columns. If we tried and were able to * read the parity without error, verify that the generated parity matches the * data we read. If it doesn't, we fire off a checksum error. Return the * number such failures. */ static int raidz_parity_verify(raidz_map_t *rm) { void *orig[VDEV_RAIDZ_MAXPARITY]; int c, ret = 0; raidz_col_t *rc; for (c = 0; c < rm->rm_firstdatacol; c++) { rc = &rm->rm_col[c]; if (!rc->rc_tried || rc->rc_error != 0) continue; orig[c] = malloc(rc->rc_size); if (orig[c] != NULL) { bcopy(rc->rc_data, orig[c], rc->rc_size); } else { printf("Out of memory\n"); } } vdev_raidz_generate_parity(rm); for (c = rm->rm_firstdatacol - 1; c >= 0; c--) { rc = &rm->rm_col[c]; if (!rc->rc_tried || rc->rc_error != 0) continue; if (orig[c] == NULL || bcmp(orig[c], rc->rc_data, rc->rc_size) != 0) { rc->rc_error = ECKSUM; ret++; } free(orig[c]); } return (ret); } /* * Iterate over all combinations of bad data and attempt a reconstruction. * Note that the algorithm below is non-optimal because it doesn't take into * account how reconstruction is actually performed. For example, with * triple-parity RAID-Z the reconstruction procedure is the same if column 4 * is targeted as invalid as if columns 1 and 4 are targeted since in both * cases we'd only use parity information in column 0. */ static int vdev_raidz_combrec(const spa_t *spa, raidz_map_t *rm, const blkptr_t *bp, void *data, off_t offset __unused, uint64_t bytes, int total_errors, int data_errors) { raidz_col_t *rc; void *orig[VDEV_RAIDZ_MAXPARITY]; int tstore[VDEV_RAIDZ_MAXPARITY + 2]; int *tgts = &tstore[1]; int current, next, i, c, n; int code, ret = 0; ASSERT(total_errors < rm->rm_firstdatacol); /* * This simplifies one edge condition. */ tgts[-1] = -1; for (n = 1; n <= rm->rm_firstdatacol - total_errors; n++) { /* * Initialize the targets array by finding the first n columns * that contain no error. * * If there were no data errors, we need to ensure that we're * always explicitly attempting to reconstruct at least one * data column. To do this, we simply push the highest target * up into the data columns. */ for (c = 0, i = 0; i < n; i++) { if (i == n - 1 && data_errors == 0 && c < rm->rm_firstdatacol) { c = rm->rm_firstdatacol; } while (rm->rm_col[c].rc_error != 0) { c++; ASSERT3S(c, <, rm->rm_cols); } tgts[i] = c++; } /* * Setting tgts[n] simplifies the other edge condition. */ tgts[n] = rm->rm_cols; /* * These buffers were allocated in previous iterations. */ for (i = 0; i < n - 1; i++) { ASSERT(orig[i] != NULL); } orig[n - 1] = malloc(rm->rm_col[0].rc_size); if (orig[n - 1] == NULL) { ret = ENOMEM; goto done; } current = 0; next = tgts[current]; while (current != n) { tgts[current] = next; current = 0; /* * Save off the original data that we're going to * attempt to reconstruct. */ for (i = 0; i < n; i++) { ASSERT(orig[i] != NULL); c = tgts[i]; ASSERT3S(c, >=, 0); ASSERT3S(c, <, rm->rm_cols); rc = &rm->rm_col[c]; bcopy(rc->rc_data, orig[i], rc->rc_size); } /* * Attempt a reconstruction and exit the outer loop on * success. */ code = vdev_raidz_reconstruct(rm, tgts, n); if (raidz_checksum_verify(spa, bp, data, bytes) == 0) { for (i = 0; i < n; i++) { c = tgts[i]; rc = &rm->rm_col[c]; ASSERT(rc->rc_error == 0); rc->rc_error = ECKSUM; } ret = code; goto done; } /* * Restore the original data. */ for (i = 0; i < n; i++) { c = tgts[i]; rc = &rm->rm_col[c]; bcopy(orig[i], rc->rc_data, rc->rc_size); } do { /* * Find the next valid column after the current * position.. */ for (next = tgts[current] + 1; next < rm->rm_cols && rm->rm_col[next].rc_error != 0; next++) continue; ASSERT(next <= tgts[current + 1]); /* * If that spot is available, we're done here. */ if (next != tgts[current + 1]) break; /* * Otherwise, find the next valid column after * the previous position. */ for (c = tgts[current - 1] + 1; rm->rm_col[c].rc_error != 0; c++) continue; tgts[current] = c; current++; } while (current != n); } } n--; done: for (i = n - 1; i >= 0; i--) { free(orig[i]); } return (ret); } static int vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data, off_t offset, size_t bytes) { vdev_t *tvd = vd->v_top; vdev_t *cvd; raidz_map_t *rm; raidz_col_t *rc; int c, error; int unexpected_errors; int parity_errors; int parity_untried; int data_errors; int total_errors; int n; int tgts[VDEV_RAIDZ_MAXPARITY]; int code; rc = NULL; /* gcc */ error = 0; rm = vdev_raidz_map_alloc(data, offset, bytes, tvd->v_ashift, vd->v_nchildren, vd->v_nparity); if (rm == NULL) return (ENOMEM); /* * Iterate over the columns in reverse order so that we hit the parity * last -- any errors along the way will force us to read the parity. */ for (c = rm->rm_cols - 1; c >= 0; c--) { rc = &rm->rm_col[c]; cvd = vdev_child(vd, rc->rc_devidx); if (cvd == NULL || cvd->v_state != VDEV_STATE_HEALTHY) { if (c >= rm->rm_firstdatacol) rm->rm_missingdata++; else rm->rm_missingparity++; rc->rc_error = ENXIO; rc->rc_tried = 1; /* don't even try */ rc->rc_skipped = 1; continue; } #if 0 /* XXX: Too hard for the boot code. */ if (vdev_dtl_contains(cvd, DTL_MISSING, zio->io_txg, 1)) { if (c >= rm->rm_firstdatacol) rm->rm_missingdata++; else rm->rm_missingparity++; rc->rc_error = ESTALE; rc->rc_skipped = 1; continue; } #endif if (c >= rm->rm_firstdatacol || rm->rm_missingdata > 0) { rc->rc_error = cvd->v_read(cvd, NULL, rc->rc_data, rc->rc_offset, rc->rc_size); rc->rc_tried = 1; rc->rc_skipped = 0; } } reconstruct: unexpected_errors = 0; parity_errors = 0; parity_untried = 0; data_errors = 0; total_errors = 0; ASSERT(rm->rm_missingparity <= rm->rm_firstdatacol); ASSERT(rm->rm_missingdata <= rm->rm_cols - rm->rm_firstdatacol); for (c = 0; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; if (rc->rc_error) { ASSERT(rc->rc_error != ECKSUM); /* child has no bp */ if (c < rm->rm_firstdatacol) parity_errors++; else data_errors++; if (!rc->rc_skipped) unexpected_errors++; total_errors++; } else if (c < rm->rm_firstdatacol && !rc->rc_tried) { parity_untried++; } } /* * There are three potential phases for a read: * 1. produce valid data from the columns read * 2. read all disks and try again * 3. perform combinatorial reconstruction * * Each phase is progressively both more expensive and less likely to * occur. If we encounter more errors than we can repair or all phases * fail, we have no choice but to return an error. */ /* * If the number of errors we saw was correctable -- less than or equal * to the number of parity disks read -- attempt to produce data that * has a valid checksum. Naturally, this case applies in the absence of * any errors. */ if (total_errors <= rm->rm_firstdatacol - parity_untried) { int rv; if (data_errors == 0) { rv = raidz_checksum_verify(vd->v_spa, bp, data, bytes); if (rv == 0) { /* * If we read parity information (unnecessarily * as it happens since no reconstruction was * needed) regenerate and verify the parity. * We also regenerate parity when resilvering * so we can write it out to the failed device * later. */ if (parity_errors + parity_untried < rm->rm_firstdatacol) { n = raidz_parity_verify(rm); unexpected_errors += n; ASSERT(parity_errors + n <= rm->rm_firstdatacol); } goto done; } } else { /* * We either attempt to read all the parity columns or * none of them. If we didn't try to read parity, we * wouldn't be here in the correctable case. There must * also have been fewer parity errors than parity * columns or, again, we wouldn't be in this code path. */ ASSERT(parity_untried == 0); ASSERT(parity_errors < rm->rm_firstdatacol); /* * Identify the data columns that reported an error. */ n = 0; for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; if (rc->rc_error != 0) { ASSERT(n < VDEV_RAIDZ_MAXPARITY); tgts[n++] = c; } } ASSERT(rm->rm_firstdatacol >= n); code = vdev_raidz_reconstruct(rm, tgts, n); rv = raidz_checksum_verify(vd->v_spa, bp, data, bytes); if (rv == 0) { /* * If we read more parity disks than were used * for reconstruction, confirm that the other * parity disks produced correct data. This * routine is suboptimal in that it regenerates * the parity that we already used in addition * to the parity that we're attempting to * verify, but this should be a relatively * uncommon case, and can be optimized if it * becomes a problem. Note that we regenerate * parity when resilvering so we can write it * out to failed devices later. */ if (parity_errors < rm->rm_firstdatacol - n) { n = raidz_parity_verify(rm); unexpected_errors += n; ASSERT(parity_errors + n <= rm->rm_firstdatacol); } goto done; } } } /* * This isn't a typical situation -- either we got a read * error or a child silently returned bad data. Read every * block so we can try again with as much data and parity as * we can track down. If we've already been through once * before, all children will be marked as tried so we'll * proceed to combinatorial reconstruction. */ unexpected_errors = 1; rm->rm_missingdata = 0; rm->rm_missingparity = 0; n = 0; for (c = 0; c < rm->rm_cols; c++) { rc = &rm->rm_col[c]; if (rc->rc_tried) continue; cvd = vdev_child(vd, rc->rc_devidx); ASSERT(cvd != NULL); rc->rc_error = cvd->v_read(cvd, NULL, rc->rc_data, rc->rc_offset, rc->rc_size); if (rc->rc_error == 0) n++; rc->rc_tried = 1; rc->rc_skipped = 0; } /* * If we managed to read anything more, retry the * reconstruction. */ if (n > 0) goto reconstruct; /* * At this point we've attempted to reconstruct the data given the * errors we detected, and we've attempted to read all columns. There * must, therefore, be one or more additional problems -- silent errors * resulting in invalid data rather than explicit I/O errors resulting * in absent data. We check if there is enough additional data to * possibly reconstruct the data and then perform combinatorial * reconstruction over all possible combinations. If that fails, * we're cooked. */ if (total_errors > rm->rm_firstdatacol) { error = EIO; } else if (total_errors < rm->rm_firstdatacol && (code = vdev_raidz_combrec(vd->v_spa, rm, bp, data, offset, bytes, total_errors, data_errors)) != 0) { /* * If we didn't use all the available parity for the * combinatorial reconstruction, verify that the remaining * parity is correct. */ if (code != (1 << rm->rm_firstdatacol) - 1) (void) raidz_parity_verify(rm); } else { /* * We're here because either: * * total_errors == rm_first_datacol, or * vdev_raidz_combrec() failed * * In either case, there is enough bad data to prevent * reconstruction. * * Start checksum ereports for all children which haven't * failed, and the IO wasn't speculative. */ error = ECKSUM; } done: vdev_raidz_map_free(rm); return (error); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Zero-length encoding. This is a fast and simple algorithm to eliminate * runs of zeroes. Each chunk of compressed data begins with a length byte, b. * If b < n (where n is the compression parameter) then the next b + 1 bytes * are literal values. If b >= n then the next (256 - b + 1) bytes are zero. */ static int zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) { unsigned char *src = s_start; unsigned char *dst = d_start; unsigned char *s_end = src + s_len; unsigned char *d_end = dst + d_len; while (src < s_end && dst < d_end) { int len = 1 + *src++; if (len <= n) { while (len-- != 0) *dst++ = *src++; } else { len -= n; while (len-- != 0) *dst++ = 0; } } return (dst == d_end ? 0 : -1); } /* * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension * Support code is derived from software contributed to Berkeley * by Atsushi Murai (amurai@spec.co.jp). * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94 */ #ifndef CD9660_RRIP_H #define CD9660_RRIP_H typedef struct { char type [ISODCL(0, 1)]; uchar_t length [ISODCL(2, 2)]; /* 711 */ uchar_t version [ISODCL(3, 3)]; } ISO_SUSP_HEADER; typedef struct { ISO_SUSP_HEADER h; char mode [ISODCL(4, 11)]; /* 733 */ char links [ISODCL(12, 19)]; /* 733 */ char uid [ISODCL(20, 27)]; /* 733 */ char gid [ISODCL(28, 35)]; /* 733 */ } ISO_RRIP_ATTR; typedef struct { ISO_SUSP_HEADER h; char dev_t_high [ISODCL(4, 11)]; /* 733 */ char dev_t_low [ISODCL(12, 19)]; /* 733 */ } ISO_RRIP_DEVICE; #define ISO_SUSP_CFLAG_CONTINUE 0x01 #define ISO_SUSP_CFLAG_CURRENT 0x02 #define ISO_SUSP_CFLAG_PARENT 0x04 #define ISO_SUSP_CFLAG_ROOT 0x08 #define ISO_SUSP_CFLAG_VOLROOT 0x10 #define ISO_SUSP_CFLAG_HOST 0x20 typedef struct { uchar_t cflag [ISODCL(1, 1)]; uchar_t clen [ISODCL(2, 2)]; uchar_t name [1]; /* XXX */ } ISO_RRIP_SLINK_COMPONENT; #define ISO_RRIP_SLSIZ 2 typedef struct { ISO_SUSP_HEADER h; uchar_t flags [ISODCL(4, 4)]; uchar_t component [ISODCL(5, 5)]; } ISO_RRIP_SLINK; typedef struct { ISO_SUSP_HEADER h; char flags [ISODCL(4, 4)]; } ISO_RRIP_ALTNAME; typedef struct { ISO_SUSP_HEADER h; char dir_loc [ISODCL(4, 11)]; /* 733 */ } ISO_RRIP_CLINK; typedef struct { ISO_SUSP_HEADER h; char dir_loc [ISODCL(4, 11)]; /* 733 */ } ISO_RRIP_PLINK; typedef struct { ISO_SUSP_HEADER h; } ISO_RRIP_RELDIR; #define ISO_SUSP_TSTAMP_FORM17 0x80 #define ISO_SUSP_TSTAMP_FORM7 0x00 #define ISO_SUSP_TSTAMP_CREAT 0x01 #define ISO_SUSP_TSTAMP_MODIFY 0x02 #define ISO_SUSP_TSTAMP_ACCESS 0x04 #define ISO_SUSP_TSTAMP_ATTR 0x08 #define ISO_SUSP_TSTAMP_BACKUP 0x10 #define ISO_SUSP_TSTAMP_EXPIRE 0x20 #define ISO_SUSP_TSTAMP_EFFECT 0x40 typedef struct { ISO_SUSP_HEADER h; uchar_t flags [ISODCL(4, 4)]; uchar_t time [ISODCL(5, 5)]; } ISO_RRIP_TSTAMP; typedef struct { ISO_SUSP_HEADER h; uchar_t flags [ISODCL(4, 4)]; } ISO_RRIP_IDFLAG; typedef struct { ISO_SUSP_HEADER h; char len_id [ISODCL(4, 4)]; char len_des [ISODCL(5, 5)]; char len_src [ISODCL(6, 6)]; char version [ISODCL(7, 7)]; } ISO_RRIP_EXTREF; typedef struct { ISO_SUSP_HEADER h; char check [ISODCL(4, 5)]; char skip [ISODCL(6, 6)]; } ISO_RRIP_OFFSET; typedef struct { ISO_SUSP_HEADER h; uchar_t location [ISODCL(4, 11)]; uchar_t offset [ISODCL(12, 19)]; uchar_t length [ISODCL(20, 27)]; } ISO_RRIP_CONT; #endif /* CD9660_RRIP_H */ /* * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension * Support code is derived from software contributed to Berkeley * by Atsushi Murai (amurai@spec.co.jp). * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)iso.h 8.6 (Berkeley) 5/10/95 */ #ifndef ISO_H #define ISO_H #define ISODCL(from, to) (to - from + 1) struct iso_volume_descriptor { char type[ISODCL(1, 1)]; /* 711 */ char id[ISODCL(2, 6)]; char version[ISODCL(7, 7)]; char unused[ISODCL(8, 8)]; char type_sierra[ISODCL(9, 9)]; /* 711 */ char id_sierra[ISODCL(10, 14)]; char version_sierra[ISODCL(15, 15)]; char data[ISODCL(16, 2048)]; }; /* volume descriptor types */ #define ISO_VD_PRIMARY 1 #define ISO_VD_SUPPLEMENTARY 2 #define ISO_VD_END 255 #define ISO_STANDARD_ID "CD001" #define ISO_ECMA_ID "CDW01" #define ISO_SIERRA_ID "CDROM" struct iso_primary_descriptor { uchar_t type [ISODCL(1, 1)]; /* 711 */ char id [ISODCL(2, 6)]; char version [ISODCL(7, 7)]; /* 711 */ char unused1 [ISODCL(8, 8)]; char system_id [ISODCL(9, 40)]; /* achars */ char volume_id [ISODCL(41, 72)]; /* dchars */ char unused2 [ISODCL(73, 80)]; char volume_space_size [ISODCL(81, 88)]; /* 733 */ char unused3 [ISODCL(89, 120)]; char volume_set_size [ISODCL(121, 124)]; /* 723 */ char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ uchar_t logical_block_size [ISODCL(129, 132)]; /* 723 */ char path_table_size [ISODCL(133, 140)]; /* 733 */ char type_l_path_table [ISODCL(141, 144)]; /* 731 */ char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ char type_m_path_table [ISODCL(149, 152)]; /* 732 */ char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ char volume_set_id [ISODCL(191, 318)]; /* dchars */ char publisher_id [ISODCL(319, 446)]; /* achars */ char preparer_id [ISODCL(447, 574)]; /* achars */ char application_id [ISODCL(575, 702)]; /* achars */ char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ char file_structure_version [ISODCL(882, 882)]; /* 711 */ char unused4 [ISODCL(883, 883)]; char application_data [ISODCL(884, 1395)]; char unused5 [ISODCL(1396, 2048)]; } __packed; #define ISO_DEFAULT_BLOCK_SHIFT 11 #define ISO_DEFAULT_BLOCK_SIZE (1 << ISO_DEFAULT_BLOCK_SHIFT) /* * Used by Microsoft Joliet extension to ISO9660. Almost the same * as PVD, but byte position 8 is a flag, and 89-120 is for escape. */ struct iso_supplementary_descriptor { char type [ISODCL(1, 1)]; /* 711 */ char id [ISODCL(2, 6)]; char version [ISODCL(7, 7)]; /* 711 */ char flags [ISODCL(8, 8)]; /* 711? */ char system_id [ISODCL(9, 40)]; /* achars */ char volume_id [ISODCL(41, 72)]; /* dchars */ char unused2 [ISODCL(73, 80)]; char volume_space_size [ISODCL(81, 88)]; /* 733 */ char escape [ISODCL(89, 120)]; char volume_set_size [ISODCL(121, 124)]; /* 723 */ char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ char logical_block_size [ISODCL(129, 132)]; /* 723 */ char path_table_size [ISODCL(133, 140)]; /* 733 */ char type_l_path_table [ISODCL(141, 144)]; /* 731 */ char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ char type_m_path_table [ISODCL(149, 152)]; /* 732 */ char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ char volume_set_id [ISODCL(191, 318)]; /* dchars */ char publisher_id [ISODCL(319, 446)]; /* achars */ char preparer_id [ISODCL(447, 574)]; /* achars */ char application_id [ISODCL(575, 702)]; /* achars */ char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ char file_structure_version [ISODCL(882, 882)]; /* 711 */ char unused4 [ISODCL(883, 883)]; char application_data [ISODCL(884, 1395)]; char unused5 [ISODCL(1396, 2048)]; }; struct iso_sierra_primary_descriptor { char unknown1 [ISODCL(1, 8)]; /* 733 */ char type [ISODCL(9, 9)]; /* 711 */ char id [ISODCL(10, 14)]; char version [ISODCL(15, 15)]; /* 711 */ char unused1 [ISODCL(16, 16)]; char system_id [ISODCL(17, 48)]; /* achars */ char volume_id [ISODCL(49, 80)]; /* dchars */ char unused2 [ISODCL(81, 88)]; char volume_space_size [ISODCL(89, 96)]; /* 733 */ char unused3 [ISODCL(97, 128)]; char volume_set_size [ISODCL(129, 132)]; /* 723 */ char volume_sequence_number [ISODCL(133, 136)]; /* 723 */ char logical_block_size [ISODCL(137, 140)]; /* 723 */ char path_table_size [ISODCL(141, 148)]; /* 733 */ char type_l_path_table [ISODCL(149, 152)]; /* 731 */ char opt_type_l_path_table [ISODCL(153, 156)]; /* 731 */ char unknown2 [ISODCL(157, 160)]; /* 731 */ char unknown3 [ISODCL(161, 164)]; /* 731 */ char type_m_path_table [ISODCL(165, 168)]; /* 732 */ char opt_type_m_path_table [ISODCL(169, 172)]; /* 732 */ char unknown4 [ISODCL(173, 176)]; /* 732 */ char unknown5 [ISODCL(177, 180)]; /* 732 */ char root_directory_record [ISODCL(181, 214)]; /* 9.1 */ char volume_set_id [ISODCL(215, 342)]; /* dchars */ char publisher_id [ISODCL(343, 470)]; /* achars */ char preparer_id [ISODCL(471, 598)]; /* achars */ char application_id [ISODCL(599, 726)]; /* achars */ char copyright_id [ISODCL(727, 790)]; /* achars */ char creation_date [ISODCL(791, 806)]; /* ? */ char modification_date [ISODCL(807, 822)]; /* ? */ char expiration_date [ISODCL(823, 838)]; /* ? */ char effective_date [ISODCL(839, 854)]; /* ? */ char file_structure_version [ISODCL(855, 855)]; /* 711 */ char unused4 [ISODCL(856, 2048)]; }; struct iso_directory_record { uchar_t length [ISODCL(1, 1)]; /* 711 */ uchar_t ext_attr_length [ISODCL(2, 2)]; /* 711 */ uchar_t extent [ISODCL(3, 10)]; /* 733 */ uchar_t size [ISODCL(11, 18)]; /* 733 */ char date [ISODCL(19, 25)]; /* 7 by 711 */ uchar_t flags [ISODCL(26, 26)]; char file_unit_size [ISODCL(27, 27)]; /* 711 */ char interleave [ISODCL(28, 28)]; /* 711 */ char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ uchar_t name_len [ISODCL(33, 33)]; /* 711 */ char name [1]; /* XXX */ } __packed; /* * can't take sizeof(iso_directory_record), because of possible alignment * of the last entry (34 instead of 33) */ #define ISO_DIRECTORY_RECORD_SIZE 33 struct iso_extended_attributes { uchar_t owner [ISODCL(1, 4)]; /* 723 */ uchar_t group [ISODCL(5, 8)]; /* 723 */ uchar_t perm [ISODCL(9, 10)]; /* 9.5.3 */ char ctime [ISODCL(11, 27)]; /* 8.4.26.1 */ char mtime [ISODCL(28, 44)]; /* 8.4.26.1 */ char xtime [ISODCL(45, 61)]; /* 8.4.26.1 */ char ftime [ISODCL(62, 78)]; /* 8.4.26.1 */ char recfmt [ISODCL(79, 79)]; /* 711 */ char recattr [ISODCL(80, 80)]; /* 711 */ uchar_t reclen [ISODCL(81, 84)]; /* 723 */ char system_id [ISODCL(85, 116)]; /* achars */ char system_use [ISODCL(117, 180)]; char version [ISODCL(181, 181)]; /* 711 */ char len_esc [ISODCL(182, 182)]; /* 711 */ char reserved [ISODCL(183, 246)]; uchar_t len_au [ISODCL(247, 250)]; /* 723 */ }; #ifdef _KERNEL /* CD-ROM Format type */ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_JOLIET, ISO_FTYPE_ECMA, ISO_FTYPE_HIGH_SIERRA }; #ifndef ISOFSMNT_ROOT #define ISOFSMNT_ROOT 0 #endif /* * When ino_t becomes 64-bit, we can remove this definition in favor of ino_t. */ typedef __uint64_t cd_ino_t; struct iso_mnt { uint64_t im_flags; struct mount *im_mountp; struct cdev *im_dev; struct vnode *im_devvp; struct g_consumer *im_cp; struct bufobj *im_bo; int logical_block_size; int im_bshift; int im_bmask; int volume_space_size; char root[ISODCL(157, 190)]; int root_extent; int root_size; enum ISO_FTYPE iso_ftype; int rr_skip; int rr_skip0; int joliet_level; void *im_d2l; void *im_l2d; }; struct ifid { ushort_t ifid_len; ushort_t ifid_pad; cd_ino_t ifid_ino; long ifid_start; }; #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data)) #define blkoff(imp, loc) ((loc) & (imp)->im_bmask) #define lblktosize(imp, blk) ((blk) << (imp)->im_bshift) #define lblkno(imp, loc) ((loc) >> (imp)->im_bshift) #define blksize(imp, ip, lbn) ((imp)->logical_block_size) int cd9660_vget_internal(struct mount *, cd_ino_t, int, struct vnode **, int, struct iso_directory_record *); #define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \ size_t, struct proc *))eopnotsupp) extern struct vop_vector cd9660_vnodeops; extern struct vop_vector cd9660_fifoops; int isochar(uchar_t *, uchar_t *, int, ushort_t *, int *, int, void *); int isofncmp(uchar_t *, int, uchar_t *, int, int, int, void *, void *); void isofntrans(uchar_t *, int, uchar_t *, ushort_t *, int, int, int, int, void *); cd_ino_t isodirino(struct iso_directory_record *, struct iso_mnt *); ushort_t sgetrune(const char *, size_t, char const **, int, void *); #endif /* _KERNEL */ /* * The isonum_xxx functions are inlined anyway, and could come handy even * outside the kernel. Thus we don't hide them here. */ /* * 7xy * x -> 1 = 8 bits, 2 = 16 bits, 3 = 32 bits * y -> 1 = little-endian, 2 = big-endian, 3 = both (le then be) */ static __inline uint8_t isonum_711(const unsigned char *p) { return (p[0]); } static __inline int8_t isonum_712(const unsigned char *p) { return ((signed char)p[0]); } static __inline uint8_t isonum_713(const unsigned char *p) { return (p[0]); } static __inline uint16_t isonum_721(const unsigned char *p) { return (p[0] | p[1] << 8); } static __inline uint16_t isonum_722(const unsigned char *p) { return (p[1] | p[0] << 8); } static __inline uint16_t isonum_723(const unsigned char *p) { return (p[0] | p[1] << 8); } static __inline uint32_t isonum_731(const unsigned char *p) { return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24); } static __inline uint32_t isonum_732(const unsigned char *p) { return (p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24); } static __inline uint32_t isonum_733(const unsigned char *p) { return (p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24); } /* * Associated files have a leading '='. */ #define ASSOCCHAR '=' #endif /* ISO_H */ /*- * Copyright (c) 1982, 1986, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)uio.h 8.5 (Berkeley) 2/22/94 * $FreeBSD$ */ #ifndef _SYS__IOVEC_H_ #define _SYS__IOVEC_H_ #include #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif struct iovec { void *iov_base; /* Base address. */ size_t iov_len; /* Length. */ }; #endif /* !_SYS__IOVEC_H_ */ /*- * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. * * 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. Berkeley Software Design Inc's name may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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. * * $FreeBSD$ */ #ifndef _SYS__LOCK_H_ #define _SYS__LOCK_H_ struct lock_object { const char *lo_name; /* Individual lock name. */ u_int lo_flags; u_int lo_data; /* General class specific data. */ struct witness *lo_witness; /* Data for witness. */ }; #endif /* !_SYS__LOCK_H_ */ /*- * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. * * 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. Berkeley Software Design Inc's name may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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. * * $FreeBSD$ */ #ifndef _SYS__MUTEX_H_ #define _SYS__MUTEX_H_ #include /* * Sleep/spin mutex. * * All mutex implementations must always have a member called mtx_lock. * Other locking primitive structures are not allowed to use this name * for their members. * If this rule needs to change, the bits in the mutex implementation must * be modified appropriately. */ struct mtx { struct lock_object lock_object; /* Common lock properties. */ volatile uintptr_t mtx_lock; /* Owner and flags. */ }; /* * Members of struct mtx_padalign must mirror members of struct mtx. * mtx_padalign mutexes can use the mtx(9) API transparently without * modification. * Pad-aligned mutexes used within structures should generally be the * first member of the struct. Otherwise, the compiler can generate * additional padding for the struct to keep a correct alignment for * the mutex. */ struct mtx_padalign { struct lock_object lock_object; /* Common lock properties. */ volatile uintptr_t mtx_lock; /* Owner and flags. */ } __aligned(CACHE_LINE_SIZE); #endif /* !_SYS__MUTEX_H_ */ /*- * Copyright (c) 2003 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * * $FreeBSD$ */ #ifndef NULL #if !defined(__cplusplus) #define NULL ((void *)0) #else #if __cplusplus >= 201103L #define NULL nullptr #elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4 #define NULL __null #else #if defined(__LP64__) #define NULL (0L) #else #define NULL 0 #endif /* __LP64__ */ #endif /* __GNUG__ */ #endif /* !__cplusplus */ #endif /* * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu * Copyright (c) 1995-1998 by John Birrell * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Chris Provenzano. * 4. The name of Chris Provenzano may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. * * $FreeBSD$ */ #ifndef _SYS__PTHREADTYPES_H_ #define _SYS__PTHREADTYPES_H_ /* * Forward structure definitions. * * These are mostly opaque to the user. */ struct pthread; struct pthread_attr; struct pthread_cond; struct pthread_cond_attr; struct pthread_mutex; struct pthread_mutex_attr; struct pthread_once; struct pthread_rwlock; struct pthread_rwlockattr; struct pthread_barrier; struct pthread_barrier_attr; struct pthread_spinlock; /* * Primitive system data type definitions required by P1003.1c. * * Note that P1003.1c specifies that there are no defined comparison * or assignment operators for the types pthread_attr_t, pthread_cond_t, * pthread_condattr_t, pthread_mutex_t, pthread_mutexattr_t. */ #ifndef _PTHREAD_T_DECLARED typedef struct pthread *pthread_t; #define _PTHREAD_T_DECLARED #endif typedef struct pthread_attr *pthread_attr_t; typedef struct pthread_mutex *pthread_mutex_t; typedef struct pthread_mutex_attr *pthread_mutexattr_t; typedef struct pthread_cond *pthread_cond_t; typedef struct pthread_cond_attr *pthread_condattr_t; typedef int pthread_key_t; typedef struct pthread_once pthread_once_t; typedef struct pthread_rwlock *pthread_rwlock_t; typedef struct pthread_rwlockattr *pthread_rwlockattr_t; typedef struct pthread_barrier *pthread_barrier_t; typedef struct pthread_barrierattr *pthread_barrierattr_t; typedef struct pthread_spinlock *pthread_spinlock_t; /* * Additional type definitions: * * Note that P1003.1c reserves the prefixes pthread_ and PTHREAD_ for * use in header symbols. */ typedef void *pthread_addr_t; typedef void *(*pthread_startroutine_t)(void *); /* * Once definitions. */ struct pthread_once { int state; pthread_mutex_t mutex; }; #endif /* ! _SYS__PTHREADTYPES_H_ */ /*- * Copyright (c) 2006 John Baldwin * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS__RWLOCK_H_ #define _SYS__RWLOCK_H_ #include /* * Reader/writer lock. * * All reader/writer lock implementations must always have a member * called rw_lock. Other locking primitive structures are not allowed to * use this name for their members. * If this rule needs to change, the bits in the reader/writer lock * implementation must be modified appropriately. */ struct rwlock { struct lock_object lock_object; volatile uintptr_t rw_lock; }; /* * Members of struct rwlock_padalign must mirror members of struct rwlock. * rwlock_padalign rwlocks can use the rwlock(9) API transparently without * modification. * Pad-aligned rwlocks used within structures should generally be the * first member of the struct. Otherwise, the compiler can generate * additional padding for the struct to keep a correct alignment for * the rwlock. */ struct rwlock_padalign { struct lock_object lock_object; volatile uintptr_t rw_lock; } __aligned(CACHE_LINE_SIZE); #endif /* !_SYS__RWLOCK_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)signal.h 8.4 (Berkeley) 5/4/95 * $FreeBSD$ */ #ifndef _SYS__SIGSET_H_ #define _SYS__SIGSET_H_ /* * sigset_t macros. */ #define _SIG_WORDS 4 #define _SIG_MAXSIG 128 #define _SIG_IDX(sig) ((sig) - 1) #define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5) #define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31)) #define _SIG_VALID(sig) ((sig) <= _SIG_MAXSIG && (sig) > 0) typedef struct __sigset { __uint32_t __bits[_SIG_WORDS]; } __sigset_t; #if defined(_KERNEL) && defined(COMPAT_43) typedef unsigned int osigset_t; #endif #endif /* !_SYS__SIGSET_H_ */ /*- * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)socket.h 8.4 (Berkeley) 2/21/94 * $FreeBSD$ */ #ifndef _SYS__SOCKADDR_STORAGE_H_ #define _SYS__SOCKADDR_STORAGE_H_ /* * RFC 2553: protocol-independent placeholder for socket addresses */ #define _SS_MAXSIZE 128U #define _SS_ALIGNSIZE (sizeof(__int64_t)) #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) - \ sizeof(sa_family_t)) #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) - \ sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE) struct sockaddr_storage { unsigned char ss_len; /* address length */ sa_family_t ss_family; /* address family */ char __ss_pad1[_SS_PAD1SIZE]; __int64_t __ss_align; /* force desired struct alignment */ char __ss_pad2[_SS_PAD2SIZE]; }; #endif /* !_SYS__SOCKADDR_STORAGE_H_ */ /*- * Copyright (c) 2011 David E. O'Brien * Copyright (c) 2001 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS__STDINT_H_ #define _SYS__STDINT_H_ #ifndef _INT8_T_DECLARED typedef __int8_t int8_t; #define _INT8_T_DECLARED #endif #ifndef _INT16_T_DECLARED typedef __int16_t int16_t; #define _INT16_T_DECLARED #endif #ifndef _INT32_T_DECLARED typedef __int32_t int32_t; #define _INT32_T_DECLARED #endif #ifndef _INT64_T_DECLARED typedef __int64_t int64_t; #define _INT64_T_DECLARED #endif #ifndef _UINT8_T_DECLARED typedef __uint8_t uint8_t; #define _UINT8_T_DECLARED #endif #ifndef _UINT16_T_DECLARED typedef __uint16_t uint16_t; #define _UINT16_T_DECLARED #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _UINT64_T_DECLARED typedef __uint64_t uint64_t; #define _UINT64_T_DECLARED #endif #ifndef _INTPTR_T_DECLARED typedef __intptr_t intptr_t; #define _INTPTR_T_DECLARED #endif #ifndef _UINTPTR_T_DECLARED typedef __uintptr_t uintptr_t; #define _UINTPTR_T_DECLARED #endif #ifndef _INTMAX_T_DECLARED typedef __intmax_t intmax_t; #define _INTMAX_T_DECLARED #endif #ifndef _UINTMAX_T_DECLARED typedef __uintmax_t uintmax_t; #define _UINTMAX_T_DECLARED #endif #endif /* !_SYS__STDINT_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)time.h 8.5 (Berkeley) 5/4/95 * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp * $FreeBSD$ */ #ifndef _SYS__TIMESPEC_H_ #define _SYS__TIMESPEC_H_ #include #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* and nanoseconds */ }; #endif /* !_SYS__TIMESPEC_H_ */ /*- * Copyright (c) 2002 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS__TIMEVAL_H_ #define _SYS__TIMEVAL_H_ #include #ifndef _SUSECONDS_T_DECLARED typedef __suseconds_t suseconds_t; #define _SUSECONDS_T_DECLARED #endif #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif /* * Structure returned by gettimeofday(2) system call, and used in other calls. */ struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* and microseconds */ }; #endif /* !_SYS__TIMEVAL_H_ */ /*- * Copyright (c) 2002 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS__TYPES_H_ #define _SYS__TYPES_H_ #include #include /* * Standard type definitions. */ typedef __int32_t __blksize_t; /* file block size */ typedef __int64_t __blkcnt_t; /* file block count */ typedef __int32_t __clockid_t; /* clock_gettime()... */ typedef __uint32_t __fflags_t; /* file flags */ typedef __uint64_t __fsblkcnt_t; typedef __uint64_t __fsfilcnt_t; typedef __uint32_t __gid_t; typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */ typedef __uint32_t __ino_t; /* inode number */ typedef long __key_t; /* IPC key (for Sys V IPC) */ typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */ typedef __uint16_t __mode_t; /* permissions */ typedef int __accmode_t; /* access permissions */ typedef int __nl_item; typedef __uint16_t __nlink_t; /* link count */ typedef __int64_t __off_t; /* file offset */ typedef __int32_t __pid_t; /* process [group] */ typedef __int64_t __rlim_t; /* resource limit - intentionally */ /* signed, because of legacy code */ /* that uses -1 for RLIM_INFINITY */ typedef __uint8_t __sa_family_t; typedef __uint32_t __socklen_t; typedef long __suseconds_t; /* microseconds (signed) */ typedef struct __timer *__timer_t; /* timer_gettime()... */ typedef struct __mq *__mqd_t; /* mq_open()... */ typedef __uint32_t __uid_t; typedef unsigned int __useconds_t; /* microseconds (unsigned) */ typedef int __cpuwhich_t; /* which parameter for cpuset. */ typedef int __cpulevel_t; /* level parameter for cpuset. */ typedef int __cpusetid_t; /* cpuset identifier. */ /* * Unusual type definitions. */ /* * rune_t is declared to be an ``int'' instead of the more natural * ``unsigned long'' or ``long''. Two things are happening here. It is not * unsigned so that EOF (-1) can be naturally assigned to it and used. Also, * it looks like 10646 will be a 31 bit standard. This means that if your * ints cannot hold 32 bits, you will be in trouble. The reason an int was * chosen over a long is that the is*() and to*() routines take ints (says * ANSI C), but they use __ct_rune_t instead of int. * * NOTE: rune_t is not covered by ANSI nor other standards, and should not * be instantiated outside of lib/libc/locale. Use wchar_t. wint_t and * rune_t must be the same type. Also, wint_t should be able to hold all * members of the largest character set plus one extra value (WEOF), and * must be at least 16 bits. */ typedef int __ct_rune_t; /* arg type for ctype funcs */ typedef __ct_rune_t __rune_t; /* rune_t (see above) */ typedef __ct_rune_t __wint_t; /* wint_t (see above) */ /* Clang already provides these types as built-ins, but only in C++ mode. */ #if !defined(__clang__) || !defined(__cplusplus) typedef __uint_least16_t __char16_t; typedef __uint_least32_t __char32_t; #endif /* In C++11, char16_t and char32_t are built-in types. */ #if defined(__cplusplus) && __cplusplus >= 201103L #define _CHAR16_T_DECLARED #define _CHAR32_T_DECLARED #endif typedef __uint32_t __dev_t; /* device number */ typedef __uint32_t __fixpt_t; /* fixed point number */ /* * mbstate_t is an opaque object to keep conversion state during multibyte * stream conversions. */ typedef union { char __mbstate8[128]; __int64_t _mbstateL; /* for alignment */ } __mbstate_t; typedef unsigned long __rman_res_t; #endif /* !_SYS__TYPES_H_ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Vixie. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ #ifndef _SYS_BITSTRING_H_ #define _SYS_BITSTRING_H_ typedef unsigned char bitstr_t; /* internal macros */ /* byte of the bitstring bit is in */ #define _bit_byte(bit) \ ((bit) >> 3) /* mask for the bit within its byte */ #define _bit_mask(bit) \ (1 << ((bit)&0x7)) /* external macros */ /* bytes in a bitstring of nbits bits */ #define bitstr_size(nbits) \ (((nbits) + 7) >> 3) /* allocate a bitstring */ #define bit_alloc(nbits) \ (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t)) /* allocate a bitstring on the stack */ #define bit_decl(name, nbits) \ ((name)[bitstr_size(nbits)]) /* is bit N of bitstring name set? */ #define bit_test(name, bit) \ ((name)[_bit_byte(bit)] & _bit_mask(bit)) /* set bit N of bitstring name */ #define bit_set(name, bit) \ ((name)[_bit_byte(bit)] |= _bit_mask(bit)) /* clear bit N of bitstring name */ #define bit_clear(name, bit) \ ((name)[_bit_byte(bit)] &= ~_bit_mask(bit)) /* clear bits start ... stop in bitstring */ #define bit_nclear(name, start, stop) do { \ register bitstr_t *_name = (name); \ register int _start = (start), _stop = (stop); \ register int _startbyte = _bit_byte(_start); \ register int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ (0xff << ((_stop&0x7) + 1))); \ } else { \ _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \ while (++_startbyte < _stopbyte) \ _name[_startbyte] = 0; \ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ } \ } while (0) /* set bits start ... stop in bitstring */ #define bit_nset(name, start, stop) do { \ register bitstr_t *_name = (name); \ register int _start = (start), _stop = (stop); \ register int _startbyte = _bit_byte(_start); \ register int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] |= ((0xff << (_start&0x7)) & \ (0xff >> (7 - (_stop&0x7)))); \ } else { \ _name[_startbyte] |= 0xff << ((_start)&0x7); \ while (++_startbyte < _stopbyte) \ _name[_startbyte] = 0xff; \ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ } \ } while (0) /* find first bit clear in name */ #define bit_ffc(name, nbits, value) do { \ register bitstr_t *_name = (name); \ register int _byte, _nbits = (nbits); \ register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \ if (_nbits > 0) \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte] != 0xff) { \ bitstr_t _lb; \ _value = _byte << 3; \ for (_lb = _name[_byte]; (_lb&0x1); \ ++_value, _lb >>= 1); \ break; \ } \ if (_value >= nbits) \ _value = -1; \ *(value) = _value; \ } while (0) /* find first bit set in name */ #define bit_ffs(name, nbits, value) do { \ register bitstr_t *_name = (name); \ register int _byte, _nbits = (nbits); \ register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \ if (_nbits > 0) \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte]) { \ bitstr_t _lb; \ _value = _byte << 3; \ for (_lb = _name[_byte]; !(_lb&0x1); \ ++_value, _lb >>= 1); \ break; \ } \ if (_value >= nbits) \ _value = -1; \ *(value) = _value; \ } while (0) #endif /* !_SYS_BITSTRING_H_ */ /*- * Copyright (c) 2014 Roger Pau Monné * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_BOOT_H_ #define _SYS_BOOT_H_ /* * Return a 'boothowto' value corresponding to the kernel arguments in * (kargs) and any relevant environment variables. */ static struct { const char *ev; int mask; } howto_names[] = { { "boot_askname", RB_ASKNAME}, { "boot_cdrom", RB_CDROM}, { "boot_ddb", RB_KDB}, { "boot_dfltroot", RB_DFLTROOT}, { "boot_gdb", RB_GDB}, { "boot_multicons", RB_MULTIPLE}, { "boot_mute", RB_MUTE}, { "boot_pause", RB_PAUSE}, { "boot_serial", RB_SERIAL}, { "boot_single", RB_SINGLE}, { "boot_verbose", RB_VERBOSE}, { NULL, 0} }; #endif /* !_SYS_BOOT_H_ */ /*- * Copyright (c) 2005-2009 Apple Inc. * All rights reserved. * * 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. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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. * * P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#10 * $FreeBSD$ */ #ifndef _BSM_AUDIT_H #define _BSM_AUDIT_H #include #include #define AUDIT_RECORD_MAGIC 0x828a0f1b #define MAX_AUDIT_RECORDS 20 #define MAXAUDITDATA (0x8000 - 1) #define MAX_AUDIT_RECORD_SIZE MAXAUDITDATA #define MIN_AUDIT_FILE_SIZE (512 * 1024) /* * Minimum noumber of free blocks on the filesystem containing the audit * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0 * as the kernel does an unsigned compare, plus we want to leave a few blocks * free so userspace can terminate the log, etc. */ #define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 /* * Triggers for the audit daemon. */ #define AUDIT_TRIGGER_MIN 1 #define AUDIT_TRIGGER_LOW_SPACE 1 /* Below low watermark. */ #define AUDIT_TRIGGER_ROTATE_KERNEL 2 /* Kernel requests rotate. */ #define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */ #define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */ #define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */ #define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */ #define AUDIT_TRIGGER_INITIALIZE 7 /* User initialize of auditd. */ #define AUDIT_TRIGGER_EXPIRE_TRAILS 8 /* User expiration of trails. */ #define AUDIT_TRIGGER_MAX 8 /* * The special device filename (FreeBSD). */ #define AUDITDEV_FILENAME "audit" #define AUDIT_TRIGGER_FILE ("/dev/" AUDITDEV_FILENAME) /* * Pre-defined audit IDs */ #define AU_DEFAUDITID (uid_t)(-1) #define AU_DEFAUDITSID 0 #define AU_ASSIGN_ASID -1 /* * IPC types. */ #define AT_IPC_MSG ((u_char)1) /* Message IPC id. */ #define AT_IPC_SEM ((u_char)2) /* Semaphore IPC id. */ #define AT_IPC_SHM ((u_char)3) /* Shared mem IPC id. */ /* * Audit conditions. */ #define AUC_UNSET 0 #define AUC_AUDITING 1 #define AUC_NOAUDIT 2 #define AUC_DISABLED -1 /* * auditon(2) commands. */ #define A_OLDGETPOLICY 2 #define A_OLDSETPOLICY 3 #define A_GETKMASK 4 #define A_SETKMASK 5 #define A_OLDGETQCTRL 6 #define A_OLDSETQCTRL 7 #define A_GETCWD 8 #define A_GETCAR 9 #define A_GETSTAT 12 #define A_SETSTAT 13 #define A_SETUMASK 14 #define A_SETSMASK 15 #define A_OLDGETCOND 20 #define A_OLDSETCOND 21 #define A_GETCLASS 22 #define A_SETCLASS 23 #define A_GETPINFO 24 #define A_SETPMASK 25 #define A_SETFSIZE 26 #define A_GETFSIZE 27 #define A_GETPINFO_ADDR 28 #define A_GETKAUDIT 29 #define A_SETKAUDIT 30 #define A_SENDTRIGGER 31 #define A_GETSINFO_ADDR 32 #define A_GETPOLICY 33 #define A_SETPOLICY 34 #define A_GETQCTRL 35 #define A_SETQCTRL 36 #define A_GETCOND 37 #define A_SETCOND 38 /* * Audit policy controls. */ #define AUDIT_CNT 0x0001 #define AUDIT_AHLT 0x0002 #define AUDIT_ARGV 0x0004 #define AUDIT_ARGE 0x0008 #define AUDIT_SEQ 0x0010 #define AUDIT_WINDATA 0x0020 #define AUDIT_USER 0x0040 #define AUDIT_GROUP 0x0080 #define AUDIT_TRAIL 0x0100 #define AUDIT_PATH 0x0200 #define AUDIT_SCNT 0x0400 #define AUDIT_PUBLIC 0x0800 #define AUDIT_ZONENAME 0x1000 #define AUDIT_PERZONE 0x2000 /* * Default audit queue control parameters. */ #define AQ_HIWATER 100 #define AQ_MAXHIGH 10000 #define AQ_LOWATER 10 #define AQ_BUFSZ MAXAUDITDATA #define AQ_MAXBUFSZ 1048576 /* * Default minimum percentage free space on file system. */ #define AU_FS_MINFREE 20 /* * Type definitions used indicating the length of variable length addresses * in tokens containing addresses, such as header fields. */ #define AU_IPv4 4 #define AU_IPv6 16 __BEGIN_DECLS typedef uid_t au_id_t; typedef pid_t au_asid_t; typedef u_int16_t au_event_t; typedef u_int16_t au_emod_t; typedef u_int32_t au_class_t; typedef u_int64_t au_asflgs_t __attribute__ ((aligned (8))); struct au_tid { dev_t port; u_int32_t machine; }; typedef struct au_tid au_tid_t; struct au_tid_addr { dev_t at_port; u_int32_t at_type; u_int32_t at_addr[4]; }; typedef struct au_tid_addr au_tid_addr_t; struct au_mask { unsigned int am_success; /* Success bits. */ unsigned int am_failure; /* Failure bits. */ }; typedef struct au_mask au_mask_t; struct auditinfo { au_id_t ai_auid; /* Audit user ID. */ au_mask_t ai_mask; /* Audit masks. */ au_tid_t ai_termid; /* Terminal ID. */ au_asid_t ai_asid; /* Audit session ID. */ }; typedef struct auditinfo auditinfo_t; struct auditinfo_addr { au_id_t ai_auid; /* Audit user ID. */ au_mask_t ai_mask; /* Audit masks. */ au_tid_addr_t ai_termid; /* Terminal ID. */ au_asid_t ai_asid; /* Audit session ID. */ au_asflgs_t ai_flags; /* Audit session flags. */ }; typedef struct auditinfo_addr auditinfo_addr_t; struct auditpinfo { pid_t ap_pid; /* ID of target process. */ au_id_t ap_auid; /* Audit user ID. */ au_mask_t ap_mask; /* Audit masks. */ au_tid_t ap_termid; /* Terminal ID. */ au_asid_t ap_asid; /* Audit session ID. */ }; typedef struct auditpinfo auditpinfo_t; struct auditpinfo_addr { pid_t ap_pid; /* ID of target process. */ au_id_t ap_auid; /* Audit user ID. */ au_mask_t ap_mask; /* Audit masks. */ au_tid_addr_t ap_termid; /* Terminal ID. */ au_asid_t ap_asid; /* Audit session ID. */ au_asflgs_t ap_flags; /* Audit session flags. */ }; typedef struct auditpinfo_addr auditpinfo_addr_t; struct au_session { auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */ au_mask_t as_mask; /* Process Audit Masks. */ }; typedef struct au_session au_session_t; /* * Contents of token_t are opaque outside of libbsm. */ typedef struct au_token token_t; /* * Kernel audit queue control parameters: * Default: Maximum: * aq_hiwater: AQ_HIWATER (100) AQ_MAXHIGH (10000) * aq_lowater: AQ_LOWATER (10) mach_port_name_t audit_session_self(void); au_asid_t audit_session_join(mach_port_name_t port); #endif /* __APPLE_API_PRIVATE */ #endif /* defined(_KERNEL) || defined(KERNEL) */ __END_DECLS #endif /* !_BSM_AUDIT_H */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Berkeley Software Design, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 * $FreeBSD$ */ #ifndef _SYS_CDEFS_H_ #define _SYS_CDEFS_H_ /* * Testing against Clang-specific extensions. */ #ifndef __has_attribute #define __has_attribute(x) 0 #endif #ifndef __has_extension #define __has_extension __has_feature #endif #ifndef __has_feature #define __has_feature(x) 0 #endif #ifndef __has_include #define __has_include(x) 0 #endif #ifndef __has_builtin #define __has_builtin(x) 0 #endif #if defined(__cplusplus) #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif /* * This code has been put in place to help reduce the addition of * compiler specific defines in FreeBSD code. It helps to aid in * having a compiler-agnostic source tree. */ #if defined(__GNUC__) || defined(__INTEL_COMPILER) #if __GNUC__ >= 3 || defined(__INTEL_COMPILER) #define __GNUCLIKE_ASM 3 #define __GNUCLIKE_MATH_BUILTIN_CONSTANTS #else #define __GNUCLIKE_ASM 2 #endif #define __GNUCLIKE___TYPEOF 1 #define __GNUCLIKE___OFFSETOF 1 #define __GNUCLIKE___SECTION 1 #ifndef __INTEL_COMPILER #define __GNUCLIKE_CTOR_SECTION_HANDLING 1 #endif #define __GNUCLIKE_BUILTIN_CONSTANT_P 1 #if defined(__INTEL_COMPILER) && defined(__cplusplus) && \ __INTEL_COMPILER < 800 #undef __GNUCLIKE_BUILTIN_CONSTANT_P #endif #if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) #define __GNUCLIKE_BUILTIN_VARARGS 1 #define __GNUCLIKE_BUILTIN_STDARG 1 #define __GNUCLIKE_BUILTIN_VAALIST 1 #endif #if defined(__GNUC__) #define __GNUC_VA_LIST_COMPATIBILITY 1 #endif /* * Compiler memory barriers, specific to gcc and clang. */ #if defined(__GNUC__) #define __compiler_membar() __asm __volatile(" " : : : "memory") #endif #ifndef __INTEL_COMPILER #define __GNUCLIKE_BUILTIN_NEXT_ARG 1 #define __GNUCLIKE_MATH_BUILTIN_RELOPS #endif #define __GNUCLIKE_BUILTIN_MEMCPY 1 /* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */ #define __CC_SUPPORTS_INLINE 1 #define __CC_SUPPORTS___INLINE 1 #define __CC_SUPPORTS___INLINE__ 1 #define __CC_SUPPORTS___FUNC__ 1 #define __CC_SUPPORTS_WARNING 1 #define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */ #define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1 #endif /* __GNUC__ || __INTEL_COMPILER */ /* * Macro to test if we're using a specific version of gcc or later. */ #if defined(__GNUC__) && !defined(__INTEL_COMPILER) #define __GNUC_PREREQ__(ma, mi) \ (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) #else #define __GNUC_PREREQ__(ma, mi) 0 #endif /* * The __CONCAT macro is used to concatenate parts of symbol names, e.g. * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI * mode -- there must be no spaces between its arguments, and for nested * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also * concatenate double-quoted strings produced by the __STRING macro, but * this only works with ANSI C. * * __XSTRING is like __STRING, but it expands any macros in its argument * first. It is only available with ANSI C. */ #if defined(__STDC__) || defined(__cplusplus) #define __P(protos) protos /* full-blown ANSI C */ #define __CONCAT1(x,y) x ## y #define __CONCAT(x,y) __CONCAT1(x,y) #define __STRING(x) #x /* stringify without expanding x */ #define __XSTRING(x) __STRING(x) /* expand x, then stringify */ #define __const const /* define reserved names to standard */ #define __signed signed #define __volatile volatile #if defined(__cplusplus) #define __inline inline /* convert to C++ keyword */ #else #if !(defined(__CC_SUPPORTS___INLINE)) #define __inline /* delete GCC keyword */ #endif /* ! __CC_SUPPORTS___INLINE */ #endif /* !__cplusplus */ #else /* !(__STDC__ || __cplusplus) */ #define __P(protos) () /* traditional C preprocessor */ #define __CONCAT(x,y) x/**/y #define __STRING(x) "x" #if !defined(__CC_SUPPORTS___INLINE) #define __const /* delete pseudo-ANSI C keywords */ #define __inline #define __signed #define __volatile /* * In non-ANSI C environments, new programs will want ANSI-only C keywords * deleted from the program and old programs will want them left alone. * When using a compiler other than gcc, programs using the ANSI C keywords * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. * When using "gcc -traditional", we assume that this is the intent; if * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. */ #ifndef NO_ANSI_KEYWORDS #define const /* delete ANSI C keywords */ #define inline #define signed #define volatile #endif /* !NO_ANSI_KEYWORDS */ #endif /* !__CC_SUPPORTS___INLINE */ #endif /* !(__STDC__ || __cplusplus) */ /* * Compiler-dependent macros to help declare dead (non-returning) and * pure (no side effects) functions, and unused variables. They are * null except for versions of gcc that are known to support the features * properly (old versions of gcc-2 supported the dead and pure features * in a different (wrong) way). If we do not provide an implementation * for a given compiler, let the compile fail if it is told to use * a feature that we cannot live without. */ #ifdef lint #define __dead2 #define __pure2 #define __unused #define __packed #define __aligned(x) #define __alloc_align(x) #define __alloc_size(x) #define __section(x) #define __weak_symbol #else #define __weak_symbol __attribute__((__weak__)) #if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER) #define __dead2 #define __pure2 #define __unused #endif #if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER) #define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused /* XXX Find out what to do for __packed, __aligned and __section */ #endif #if __GNUC_PREREQ__(2, 7) || defined(__INTEL_COMPILER) #define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused __attribute__((__unused__)) #define __used __attribute__((__used__)) #define __packed __attribute__((__packed__)) #define __aligned(x) __attribute__((__aligned__(x))) #define __section(x) __attribute__((__section__(x))) #endif #if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__) #define __alloc_size(x) __attribute__((__alloc_size__(x))) #define __alloc_size2(n, x) __attribute__((__alloc_size__(n, x))) #else #define __alloc_size(x) #define __alloc_size2(n, x) #endif #if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__) #define __alloc_align(x) __attribute__((__alloc_align__(x))) #else #define __alloc_align(x) #endif #endif /* lint */ #if !__GNUC_PREREQ__(2, 95) #define __alignof(x) __offsetof(struct { char __a; x __b; }, __b) #endif /* * Keywords added in C11. */ #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L || defined(lint) #if !__has_extension(c_alignas) #if (defined(__cplusplus) && __cplusplus >= 201103L) || \ __has_extension(cxx_alignas) #define _Alignas(x) alignas(x) #else /* XXX: Only emulates _Alignas(constant-expression); not _Alignas(type-name). */ #define _Alignas(x) __aligned(x) #endif #endif #if defined(__cplusplus) && __cplusplus >= 201103L #define _Alignof(x) alignof(x) #else #define _Alignof(x) __alignof(x) #endif #if !__has_extension(c_atomic) && !__has_extension(cxx_atomic) /* * No native support for _Atomic(). Place object in structure to prevent * most forms of direct non-atomic access. */ #define _Atomic(T) struct { T volatile __val; } #endif #if defined(__cplusplus) && __cplusplus >= 201103L #define _Noreturn [[noreturn]] #else #define _Noreturn __dead2 #endif #if !__has_extension(c_static_assert) #if (defined(__cplusplus) && __cplusplus >= 201103L) || \ __has_extension(cxx_static_assert) #define _Static_assert(x, y) static_assert(x, y) #elif __GNUC_PREREQ__(4,6) /* Nothing, gcc 4.6 and higher has _Static_assert built-in */ #elif defined(__COUNTER__) #define _Static_assert(x, y) __Static_assert(x, __COUNTER__) #define __Static_assert(x, y) ___Static_assert(x, y) #define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1] \ __unused #else #define _Static_assert(x, y) struct __hack #endif #endif #if !__has_extension(c_thread_local) /* * XXX: Some compilers (Clang 3.3, GCC 4.7) falsely announce C++11 mode * without actually supporting the thread_local keyword. Don't check for * the presence of C++11 when defining _Thread_local. */ #if /* (defined(__cplusplus) && __cplusplus >= 201103L) || */ \ __has_extension(cxx_thread_local) #define _Thread_local thread_local #else #define _Thread_local __thread #endif #endif #endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */ /* * Emulation of C11 _Generic(). Unlike the previously defined C11 * keywords, it is not possible to implement this using exactly the same * syntax. Therefore implement something similar under the name * __generic(). Unlike _Generic(), this macro can only distinguish * between a single type, so it requires nested invocations to * distinguish multiple cases. */ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ __has_extension(c_generic_selections) #define __generic(expr, t, yes, no) \ _Generic(expr, t: yes, default: no) #elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus) #define __generic(expr, t, yes, no) \ __builtin_choose_expr( \ __builtin_types_compatible_p(__typeof(expr), t), yes, no) #endif #if __GNUC_PREREQ__(2, 96) #define __malloc_like __attribute__((__malloc__)) #define __pure __attribute__((__pure__)) #else #define __malloc_like #define __pure #endif #if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) #define __always_inline __attribute__((__always_inline__)) #else #define __always_inline #endif #if __GNUC_PREREQ__(3, 1) #define __noinline __attribute__ ((__noinline__)) #else #define __noinline #endif #if __GNUC_PREREQ__(3, 3) #define __nonnull(x) __attribute__((__nonnull__(x))) #define __nonnull_all __attribute__((__nonnull__)) #else #define __nonnull(x) #define __nonnull_all #endif #if __GNUC_PREREQ__(3, 4) #define __fastcall __attribute__((__fastcall__)) #define __result_use_check __attribute__((__warn_unused_result__)) #else #define __fastcall #define __result_use_check #endif #if __GNUC_PREREQ__(4, 1) #define __returns_twice __attribute__((__returns_twice__)) #else #define __returns_twice #endif #if __GNUC_PREREQ__(4, 6) || __has_builtin(__builtin_unreachable) #define __unreachable() __builtin_unreachable() #else #define __unreachable() ((void)0) #endif /* XXX: should use `#if __STDC_VERSION__ < 199901'. */ #if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) #define __func__ NULL #endif #if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901 #define __LONG_LONG_SUPPORTED #endif /* C++11 exposes a load of C99 stuff */ #if defined(__cplusplus) && __cplusplus >= 201103L #define __LONG_LONG_SUPPORTED #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS #endif #endif /* * GCC 2.95 provides `__restrict' as an extension to C90 to support the * C99-specific `restrict' type qualifier. We happen to use `__restrict' as * a way to define the `restrict' type qualifier without disturbing older * software that is unaware of C99 keywords. */ #if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95) #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint) #define __restrict #else #define __restrict restrict #endif #endif /* * GNU C version 2.96 adds explicit branch prediction so that * the CPU back-end can hint the processor and also so that * code blocks can be reordered such that the predicted path * sees a more linear flow, thus improving cache behavior, etc. * * The following two macros provide us with a way to utilize this * compiler feature. Use __predict_true() if you expect the expression * to evaluate to true, and __predict_false() if you expect the * expression to evaluate to false. * * A few notes about usage: * * * Generally, __predict_false() error condition checks (unless * you have some _strong_ reason to do otherwise, in which case * document it), and/or __predict_true() `no-error' condition * checks, assuming you want to optimize for the no-error case. * * * Other than that, if you don't know the likelihood of a test * succeeding from empirical or other `hard' evidence, don't * make predictions. * * * These are meant to be used in places that are run `a lot'. * It is wasteful to make predictions in code that is run * seldomly (e.g. at subsystem initialization time) as the * basic block reordering that this affects can often generate * larger code. */ #if __GNUC_PREREQ__(2, 96) #define __predict_true(exp) __builtin_expect((exp), 1) #define __predict_false(exp) __builtin_expect((exp), 0) #else #define __predict_true(exp) (exp) #define __predict_false(exp) (exp) #endif #if __GNUC_PREREQ__(4, 0) #define __null_sentinel __attribute__((__sentinel__)) #define __exported __attribute__((__visibility__("default"))) #define __hidden __attribute__((__visibility__("hidden"))) #else #define __null_sentinel #define __exported #define __hidden #endif /* * We define this here since , , and * require it. */ #if __GNUC_PREREQ__(4, 1) #define __offsetof(type, field) __builtin_offsetof(type, field) #else #ifndef __cplusplus #define __offsetof(type, field) \ ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field)) #else #define __offsetof(type, field) \ (__offsetof__ (reinterpret_cast <__size_t> \ (&reinterpret_cast \ (static_cast (0)->field)))) #endif #endif #define __rangeof(type, start, end) \ (__offsetof(type, end) - __offsetof(type, start)) /* * Given the pointer x to the member m of the struct s, return * a pointer to the containing structure. When using GCC, we first * assign pointer x to a local variable, to check that its type is * compatible with member m. */ #if __GNUC_PREREQ__(3, 1) #define __containerof(x, s, m) ({ \ const volatile __typeof(((s *)0)->m) *__x = (x); \ __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\ }) #else #define __containerof(x, s, m) \ __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m)) #endif /* * Compiler-dependent macros to declare that functions take printf-like * or scanf-like arguments. They are null except for versions of gcc * that are known to support the features properly (old versions of gcc-2 * didn't permit keeping the keywords out of the application namespace). */ #if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) #define __printflike(fmtarg, firstvararg) #define __scanflike(fmtarg, firstvararg) #define __format_arg(fmtarg) #define __strfmonlike(fmtarg, firstvararg) #define __strftimelike(fmtarg, firstvararg) #else #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #define __scanflike(fmtarg, firstvararg) \ __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) #define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg))) #define __strfmonlike(fmtarg, firstvararg) \ __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) #define __strftimelike(fmtarg, firstvararg) \ __attribute__((__format__ (__strftime__, fmtarg, firstvararg))) #endif /* * FORTIFY_SOURCE, and perhaps other compiler-specific features, require * the use of non-standard inlining. In general we should try to avoid * using these but GCC-compatible compilers tend to support the extensions * well enough to use them in limited cases. */ #if defined(__GNUC_GNU_INLINE__) || defined(__GNUC_STDC_INLINE__) #if __GNUC_PREREQ__(4, 3) || __has_attribute(__artificial__) #define __gnu_inline __attribute__((__gnu_inline__, __artificial__)) #else #define __gnu_inline __attribute__((__gnu_inline__)) #endif /* artificial */ #else #define __gnu_inline #endif /* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ #if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 && \ defined(__GNUC__) && !defined(__INTEL_COMPILER) #define __printf0like(fmtarg, firstvararg) \ __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) #else #define __printf0like(fmtarg, firstvararg) #endif #if defined(__GNUC__) || defined(__INTEL_COMPILER) #ifndef __INTEL_COMPILER #define __strong_reference(sym,aliassym) \ extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))) #endif #ifdef __STDC__ #define __weak_reference(sym,alias) \ __asm__(".weak " #alias); \ __asm__(".equ " #alias ", " #sym) #define __warn_references(sym,msg) \ __asm__(".section .gnu.warning." #sym); \ __asm__(".asciz \"" msg "\""); \ __asm__(".previous") #define __sym_compat(sym,impl,verid) \ __asm__(".symver " #impl ", " #sym "@" #verid) #define __sym_default(sym,impl,verid) \ __asm__(".symver " #impl ", " #sym "@@" #verid) #else #define __weak_reference(sym,alias) \ __asm__(".weak alias"); \ __asm__(".equ alias, sym") #define __warn_references(sym,msg) \ __asm__(".section .gnu.warning.sym"); \ __asm__(".asciz \"msg\""); \ __asm__(".previous") #define __sym_compat(sym,impl,verid) \ __asm__(".symver impl, sym@verid") #define __sym_default(impl,sym,verid) \ __asm__(".symver impl, sym@@verid") #endif /* __STDC__ */ #endif /* __GNUC__ || __INTEL_COMPILER */ #define __GLOBL(sym) __asm__(".globl " __XSTRING(sym)) #define __WEAK(sym) __asm__(".weak " __XSTRING(sym)) #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"") #else /* * The following definition might not work well if used in header files, * but it should be better than nothing. If you want a "do nothing" * version, then it should generate some harmless declaration, such as: * #define __IDSTRING(name,string) struct __hack */ #define __IDSTRING(name,string) static const char name[] __unused = string #endif /* * Embed the rcs id of a source file in the resulting library. Note that in * more recent ELF binutils, we use .ident allowing the ID to be stripped. * Usage: * __FBSDID("$FreeBSD$"); */ #ifndef __FBSDID #if !defined(lint) && !defined(STRIP_FBSDID) #define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) #else #define __FBSDID(s) struct __hack #endif #endif #ifndef __RCSID #ifndef NO__RCSID #define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s) #else #define __RCSID(s) struct __hack #endif #endif #ifndef __RCSID_SOURCE #ifndef NO__RCSID_SOURCE #define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s) #else #define __RCSID_SOURCE(s) struct __hack #endif #endif #ifndef __SCCSID #ifndef NO__SCCSID #define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s) #else #define __SCCSID(s) struct __hack #endif #endif #ifndef __COPYRIGHT #ifndef NO__COPYRIGHT #define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s) #else #define __COPYRIGHT(s) struct __hack #endif #endif #ifndef __DECONST #define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var)) #endif #ifndef __DEVOLATILE #define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var)) #endif #ifndef __DEQUALIFY #define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var)) #endif /*- * The following definitions are an extension of the behavior originally * implemented in , but with a different level of granularity. * POSIX.1 requires that the macros we test be defined before any standard * header file is included. * * Here's a quick run-down of the versions: * defined(_POSIX_SOURCE) 1003.1-1988 * _POSIX_C_SOURCE == 1 1003.1-1990 * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option * _POSIX_C_SOURCE == 199309 1003.1b-1993 * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995, * and the omnibus ISO/IEC 9945-1: 1996 * _POSIX_C_SOURCE == 200112 1003.1-2001 * _POSIX_C_SOURCE == 200809 1003.1-2008 * * In addition, the X/Open Portability Guide, which is now the Single UNIX * Specification, defines a feature-test macro which indicates the version of * that specification, and which subsumes _POSIX_C_SOURCE. * * Our macros begin with two underscores to avoid namespace screwage. */ /* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */ #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1 #undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */ #define _POSIX_C_SOURCE 199009 #endif /* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */ #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199209 #endif /* Deal with various X/Open Portability Guides and Single UNIX Spec. */ #ifdef _XOPEN_SOURCE #if _XOPEN_SOURCE - 0 >= 700 #define __XSI_VISIBLE 700 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809 #elif _XOPEN_SOURCE - 0 >= 600 #define __XSI_VISIBLE 600 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112 #elif _XOPEN_SOURCE - 0 >= 500 #define __XSI_VISIBLE 500 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199506 #endif #endif /* * Deal with all versions of POSIX. The ordering relative to the tests above is * important. */ #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) #define _POSIX_C_SOURCE 198808 #endif #ifdef _POSIX_C_SOURCE #if _POSIX_C_SOURCE >= 200809 #define __POSIX_VISIBLE 200809 #define __ISO_C_VISIBLE 1999 #elif _POSIX_C_SOURCE >= 200112 #define __POSIX_VISIBLE 200112 #define __ISO_C_VISIBLE 1999 #elif _POSIX_C_SOURCE >= 199506 #define __POSIX_VISIBLE 199506 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199309 #define __POSIX_VISIBLE 199309 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199209 #define __POSIX_VISIBLE 199209 #define __ISO_C_VISIBLE 1990 #elif _POSIX_C_SOURCE >= 199009 #define __POSIX_VISIBLE 199009 #define __ISO_C_VISIBLE 1990 #else #define __POSIX_VISIBLE 198808 #define __ISO_C_VISIBLE 0 #endif /* _POSIX_C_SOURCE */ #else /*- * Deal with _ANSI_SOURCE: * If it is defined, and no other compilation environment is explicitly * requested, then define our internal feature-test macros to zero. This * makes no difference to the preprocessor (undefined symbols in preprocessing * expressions are defined to have value zero), but makes it more convenient for * a test program to print out the values. * * If a program mistakenly defines _ANSI_SOURCE and some other macro such as * _POSIX_C_SOURCE, we will assume that it wants the broader compilation * environment (and in fact we will never get here). */ #if defined(_ANSI_SOURCE) /* Hide almost everything. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1990 #elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1999 #elif defined(_C11_SOURCE) /* Localism to specify strict C11 env. */ #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 2011 #else /* Default environment: show everything. */ #define __POSIX_VISIBLE 200809 #define __XSI_VISIBLE 700 #define __BSD_VISIBLE 1 #define __ISO_C_VISIBLE 2011 #endif #endif #if defined(__mips) || defined(__powerpc64__) || defined(__riscv__) #define __NO_TLS 1 #endif /* * Type Safety Checking * * Clang provides additional attributes to enable checking type safety * properties that cannot be enforced by the C type system. */ #if __has_attribute(__argument_with_type_tag__) && \ __has_attribute(__type_tag_for_datatype__) && !defined(lint) #define __arg_type_tag(arg_kind, arg_idx, type_tag_idx) \ __attribute__((__argument_with_type_tag__(arg_kind, arg_idx, type_tag_idx))) #define __datatype_type_tag(kind, type) \ __attribute__((__type_tag_for_datatype__(kind, type))) #else #define __arg_type_tag(arg_kind, arg_idx, type_tag_idx) #define __datatype_type_tag(kind, type) #endif /* * Lock annotations. * * Clang provides support for doing basic thread-safety tests at * compile-time, by marking which locks will/should be held when * entering/leaving a functions. * * Furthermore, it is also possible to annotate variables and structure * members to enforce that they are only accessed when certain locks are * held. */ #if __has_extension(c_thread_safety_attributes) #define __lock_annotate(x) __attribute__((x)) #else #define __lock_annotate(x) #endif /* Structure implements a lock. */ #define __lockable __lock_annotate(lockable) /* Function acquires an exclusive or shared lock. */ #define __locks_exclusive(...) \ __lock_annotate(exclusive_lock_function(__VA_ARGS__)) #define __locks_shared(...) \ __lock_annotate(shared_lock_function(__VA_ARGS__)) /* Function attempts to acquire an exclusive or shared lock. */ #define __trylocks_exclusive(...) \ __lock_annotate(exclusive_trylock_function(__VA_ARGS__)) #define __trylocks_shared(...) \ __lock_annotate(shared_trylock_function(__VA_ARGS__)) /* Function releases a lock. */ #define __unlocks(...) __lock_annotate(unlock_function(__VA_ARGS__)) /* Function asserts that an exclusive or shared lock is held. */ #define __asserts_exclusive(...) \ __lock_annotate(assert_exclusive_lock(__VA_ARGS__)) #define __asserts_shared(...) \ __lock_annotate(assert_shared_lock(__VA_ARGS__)) /* Function requires that an exclusive or shared lock is or is not held. */ #define __requires_exclusive(...) \ __lock_annotate(exclusive_locks_required(__VA_ARGS__)) #define __requires_shared(...) \ __lock_annotate(shared_locks_required(__VA_ARGS__)) #define __requires_unlocked(...) \ __lock_annotate(locks_excluded(__VA_ARGS__)) /* Function should not be analyzed. */ #define __no_lock_analysis __lock_annotate(no_thread_safety_analysis) /* Guard variables and structure members by lock. */ #define __guarded_by(x) __lock_annotate(guarded_by(x)) #define __pt_guarded_by(x) __lock_annotate(pt_guarded_by(x)) #endif /* !_SYS_CDEFS_H_ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)dirent.h 8.3 (Berkeley) 8/10/94 * $FreeBSD$ */ #ifndef _SYS_DIRENT_H_ #define _SYS_DIRENT_H_ #include #include /* * The dirent structure defines the format of directory entries returned by * the getdirentries(2) system call. * * A directory entry has a struct dirent at the front of it, containing its * inode number, the length of the entry, and the length of the name * contained in the entry. These are followed by the name padded to a 4 * byte boundary with null bytes. All names are guaranteed null terminated. * The maximum length of a name in a directory is MAXNAMLEN. */ struct dirent { __uint32_t d_fileno; /* file number of entry */ __uint16_t d_reclen; /* length of this record */ __uint8_t d_type; /* file type, see below */ __uint8_t d_namlen; /* length of string in d_name */ #if __BSD_VISIBLE #define MAXNAMLEN 255 char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ #else char d_name[255 + 1]; /* name must be no longer than this */ #endif }; #if __BSD_VISIBLE /* * File types */ #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 #define DT_DIR 4 #define DT_BLK 6 #define DT_REG 8 #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 /* * Convert between stat structure types and directory types. */ #define IFTODT(mode) (((mode) & 0170000) >> 12) #define DTTOIF(dirtype) ((dirtype) << 12) /* * The _GENERIC_DIRSIZ macro gives the minimum record length which will hold * the directory entry. This returns the amount of space in struct direct * without the d_name field, plus enough space for the name with a terminating * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. * * XXX although this macro is in the implementation namespace, it requires * a manifest constant that is not. */ #define _GENERIC_DIRSIZ(dp) \ ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) #endif /* __BSD_VISIBLE */ #ifdef _KERNEL #define GENERIC_DIRSIZ(dp) _GENERIC_DIRSIZ(dp) #endif #endif /* !_SYS_DIRENT_H_ */ /*- * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * * $FreeBSD$ * */ #ifndef _SYS_DISK_H_ #define _SYS_DISK_H_ #include #include #ifdef _KERNEL #ifndef _SYS_CONF_H_ #include /* XXX: temporary to avoid breakage */ #endif void disk_err(struct bio *bp, const char *what, int blkdone, int nl); #endif #define DIOCGSECTORSIZE _IOR('d', 128, u_int) /* * Get the sector size of the device in bytes. The sector size is the * smallest unit of data which can be transferred from this device. * Usually this is a power of 2 but it might not be (i.e. CDROM audio). */ #define DIOCGMEDIASIZE _IOR('d', 129, uint64_t) /* Get media size in bytes */ /* * Get the size of the entire device in bytes. This should be a * multiple of the sector size. */ #define DIOCGFWSECTORS _IOR('d', 130, u_int) /* Get firmware's sectorcount */ /* * Get the firmware's notion of number of sectors per track. This * value is mostly used for compatibility with various ill designed * disk label formats. Don't use it unless you have to. */ #define DIOCGFWHEADS _IOR('d', 131, u_int) /* Get firmware's headcount */ /* * Get the firmwares notion of number of heads per cylinder. This * value is mostly used for compatibility with various ill designed * disk label formats. Don't use it unless you have to. */ #define DIOCSKERNELDUMP _IOW('d', 133, u_int) /* Set/Clear kernel dumps */ /* * Enable/Disable (the argument is boolean) the device for kernel * core dumps. */ #define DIOCGFRONTSTUFF _IOR('d', 134, off_t) /* * Many disk formats have some amount of space reserved at the * start of the disk to hold bootblocks, various disklabels and * similar stuff. This ioctl returns the number of such bytes * which may apply to the device. */ #define DIOCGFLUSH _IO('d', 135) /* Flush write cache */ /* * Flush write cache of the device. */ #define DIOCGDELETE _IOW('d', 136, off_t[2]) /* Delete data */ /* * Mark data on the device as unused. */ #define DISK_IDENT_SIZE 256 #define DIOCGIDENT _IOR('d', 137, char[DISK_IDENT_SIZE]) /*- * Get the ident of the given provider. Ident is (most of the time) * a uniqe and fixed provider's identifier. Ident's properties are as * follow: * - ident value is preserved between reboots, * - provider can be detached/attached and ident is preserved, * - provider's name can change - ident can't, * - ident value should not be based on on-disk metadata; in other * words copying whole data from one disk to another should not * yield the same ident for the other disk, * - there could be more than one provider with the same ident, but * only if they point at exactly the same physical storage, this is * the case for multipathing for example, * - GEOM classes that consumes single providers and provide single * providers, like geli, gbde, should just attach class name to the * ident of the underlying provider, * - ident is an ASCII string (is printable), * - ident is optional and applications can't relay on its presence. */ #define DIOCGPROVIDERNAME _IOR('d', 138, char[MAXPATHLEN]) /* * Store the provider name, given a device path, in a buffer. The buffer * must be at least MAXPATHLEN bytes long. */ #define DIOCGSTRIPESIZE _IOR('d', 139, off_t) /* Get stripe size in bytes */ /* * Get the size of the device's optimal access block in bytes. * This should be a multiple of the sector size. */ #define DIOCGSTRIPEOFFSET _IOR('d', 140, off_t) /* Get stripe offset in bytes */ /* * Get the offset of the first device's optimal access block in bytes. * This should be a multiple of the sector size. */ #define DIOCGPHYSPATH _IOR('d', 141, char[MAXPATHLEN]) /* * Get a string defining the physical path for a given provider. * This has similar rules to ident, but is intended to uniquely * identify the physical location of the device, not the current * occupant of that location. */ struct diocgattr_arg { char name[64]; int len; union { char str[DISK_IDENT_SIZE]; off_t off; int i; } value; }; #define DIOCGATTR _IOWR('d', 142, struct diocgattr_arg) #endif /* _SYS_DISK_H_ */ /*- * Copyright (c) 1987, 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD$ */ #ifndef _SYS_DISKLABEL_H_ #define _SYS_DISKLABEL_H_ #ifndef _KERNEL #include #endif #include /* * Disk description table, see disktab(5) */ #define _PATH_DISKTAB "/etc/disktab" /* * Each disk has a label which includes information about the hardware * disk geometry, filesystem partitions, and drive specific information. * The label is in block 0 or 1, possibly offset from the beginning * to leave room for a bootstrap, etc. */ /* XXX these should be defined per controller (or drive) elsewhere, not here! */ #if defined(__i386__) || defined(__amd64__) || defined(__arm__) || \ defined(__powerpc__) || defined(__mips__) #define LABELSECTOR 1 /* sector containing label */ #define LABELOFFSET 0 /* offset of label in sector */ #endif #define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */ #ifndef MAXPARTITIONS #define MAXPARTITIONS 8 #endif /* Size of bootblock area in sector-size neutral bytes */ #define BBSIZE 8192 #define LABEL_PART 2 /* partition containing label */ #define RAW_PART 2 /* partition containing whole disk */ #define SWAP_PART 1 /* partition normally containing swap */ struct disklabel { u_int32_t d_magic; /* the magic number */ u_int16_t d_type; /* drive type */ u_int16_t d_subtype; /* controller/d_type specific */ char d_typename[16]; /* type name, e.g. "eagle" */ char d_packname[16]; /* pack identifier */ /* disk geometry: */ u_int32_t d_secsize; /* # of bytes per sector */ u_int32_t d_nsectors; /* # of data sectors per track */ u_int32_t d_ntracks; /* # of tracks per cylinder */ u_int32_t d_ncylinders; /* # of data cylinders per unit */ u_int32_t d_secpercyl; /* # of data sectors per cylinder */ u_int32_t d_secperunit; /* # of data sectors per unit */ /* * Spares (bad sector replacements) below are not counted in * d_nsectors or d_secpercyl. Spare sectors are assumed to * be physical sectors which occupy space at the end of each * track and/or cylinder. */ u_int16_t d_sparespertrack; /* # of spare sectors per track */ u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */ /* * Alternate cylinders include maintenance, replacement, configuration * description areas, etc. */ u_int32_t d_acylinders; /* # of alt. cylinders per unit */ /* hardware characteristics: */ /* * d_interleave, d_trackskew and d_cylskew describe perturbations * in the media format used to compensate for a slow controller. * Interleave is physical sector interleave, set up by the * formatter or controller when formatting. When interleaving is * in use, logically adjacent sectors are not physically * contiguous, but instead are separated by some number of * sectors. It is specified as the ratio of physical sectors * traversed per logical sector. Thus an interleave of 1:1 * implies contiguous layout, while 2:1 implies that logical * sector 0 is separated by one sector from logical sector 1. * d_trackskew is the offset of sector 0 on track N relative to * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew * is the offset of sector 0 on cylinder N relative to sector 0 * on cylinder N-1. */ u_int16_t d_rpm; /* rotational speed */ u_int16_t d_interleave; /* hardware sector interleave */ u_int16_t d_trackskew; /* sector 0 skew, per track */ u_int16_t d_cylskew; /* sector 0 skew, per cylinder */ u_int32_t d_headswitch; /* head switch time, usec */ u_int32_t d_trkseek; /* track-to-track seek, usec */ u_int32_t d_flags; /* generic flags */ #define NDDATA 5 u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ #define NSPARE 5 u_int32_t d_spare[NSPARE]; /* reserved for future use */ u_int32_t d_magic2; /* the magic number (again) */ u_int16_t d_checksum; /* xor of data incl. partitions */ /* filesystem and partition information: */ u_int16_t d_npartitions; /* number of partitions in following */ u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ u_int32_t d_sbsize; /* max size of fs superblock, bytes */ struct partition { /* the partition table */ u_int32_t p_size; /* number of sectors in partition */ u_int32_t p_offset; /* starting sector */ u_int32_t p_fsize; /* filesystem basic fragment size */ u_int8_t p_fstype; /* filesystem type, see below */ u_int8_t p_frag; /* filesystem fragments per block */ u_int16_t p_cpg; /* filesystem cylinders per group */ } d_partitions[MAXPARTITIONS]; /* actually may be more */ }; #ifdef CTASSERT CTASSERT(sizeof(struct disklabel) == 148 + MAXPARTITIONS * 16); #endif static __inline u_int16_t dkcksum(struct disklabel *lp); static __inline u_int16_t dkcksum(struct disklabel *lp) { u_int16_t *start, *end; u_int16_t sum = 0; start = (u_int16_t *)lp; end = (u_int16_t *)&lp->d_partitions[lp->d_npartitions]; while (start < end) sum ^= *start++; return (sum); } /* d_type values: */ #define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ #define DTYPE_MSCP 2 /* MSCP */ #define DTYPE_DEC 3 /* other DEC (rk, rl) */ #define DTYPE_SCSI 4 /* SCSI */ #define DTYPE_ESDI 5 /* ESDI interface */ #define DTYPE_ST506 6 /* ST506 etc. */ #define DTYPE_HPIB 7 /* CS/80 on HP-IB */ #define DTYPE_HPFL 8 /* HP Fiber-link */ #define DTYPE_FLOPPY 10 /* floppy */ #define DTYPE_CCD 11 /* concatenated disk */ #define DTYPE_VINUM 12 /* vinum volume */ #define DTYPE_DOC2K 13 /* Msys DiskOnChip */ #define DTYPE_RAID 14 /* CMU RAIDFrame */ #define DTYPE_JFS2 16 /* IBM JFS 2 */ #ifdef DKTYPENAMES static const char *dktypenames[] = { "unknown", "SMD", "MSCP", "old DEC", "SCSI", "ESDI", "ST506", "HP-IB", "HP-FL", "type 9", "floppy", "CCD", "Vinum", "DOC2K", "Raid", "?", "jfs", NULL }; #define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1) #endif /* * Filesystem type and version. * Used to interpret other filesystem-specific * per-partition information. */ #define FS_UNUSED 0 /* unused */ #define FS_SWAP 1 /* swap */ #define FS_V6 2 /* Sixth Edition */ #define FS_V7 3 /* Seventh Edition */ #define FS_SYSV 4 /* System V */ #define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ #define FS_V8 6 /* Eighth Edition, 4K blocks */ #define FS_BSDFFS 7 /* 4.2BSD fast filesystem */ #define FS_MSDOS 8 /* MSDOS filesystem */ #define FS_BSDLFS 9 /* 4.4BSD log-structured filesystem */ #define FS_OTHER 10 /* in use, but unknown/unsupported */ #define FS_HPFS 11 /* OS/2 high-performance filesystem */ #define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ #define FS_BOOT 13 /* partition contains bootstrap */ #define FS_VINUM 14 /* Vinum drive */ #define FS_RAID 15 /* RAIDFrame drive */ #define FS_FILECORE 16 /* Acorn Filecore Filing System */ #define FS_EXT2FS 17 /* ext2fs */ #define FS_NTFS 18 /* Windows/NT file system */ #define FS_CCD 20 /* concatenated disk component */ #define FS_JFS2 21 /* IBM JFS2 */ #define FS_HAMMER 22 /* DragonFlyBSD Hammer FS */ #define FS_HAMMER2 23 /* DragonFlyBSD Hammer2 FS */ #define FS_UDF 24 /* UDF */ #define FS_EFS 26 /* SGI's Extent File system */ #define FS_ZFS 27 /* Sun's ZFS */ #ifdef FSTYPENAMES static const char *fstypenames[] = { "unused", "swap", "Version 6", "Version 7", "System V", "4.1BSD", "Eighth Edition", "4.2BSD", "MSDOS", "4.4LFS", "unknown", "HPFS", "ISO9660", "boot", "vinum", "raid", "Filecore", "EXT2FS", "NTFS", "?", "ccd", "jfs", "HAMMER", "HAMMER2", "UDF", "?", "EFS", "ZFS", "?", "?", NULL }; #define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1) #endif /* * flags shared by various drives: */ #define D_REMOVABLE 0x01 /* removable media */ #define D_ECC 0x02 /* supports ECC */ #define D_BADSECT 0x04 /* supports bad sector forw. */ #define D_RAMDISK 0x08 /* disk emulator */ #define D_CHAIN 0x10 /* can do back-back transfers */ /* * NB: defines ioctls from 'd'/128 and up. */ /* * Functions for proper encoding/decoding of struct disklabel into/from * bytestring. */ void bsd_partition_le_dec(u_char *ptr, struct partition *d); int bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart); void bsd_partition_le_enc(u_char *ptr, struct partition *d); void bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d); #ifndef _KERNEL __BEGIN_DECLS struct disklabel *getdiskbyname(const char *); __END_DECLS #endif #endif /* !_SYS_DISKLABEL_H_ */ /*- * Copyright (c) 1987, 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD$ */ #ifndef _SYS_DISKMBR_H_ #define _SYS_DISKMBR_H_ #include #define DOSBBSECTOR 0 /* DOS boot block relative sector number */ #define DOSDSNOFF 440 /* WinNT/2K/XP Drive Serial Number offset */ #define DOSPARTOFF 446 #define DOSPARTSIZE 16 #define NDOSPART 4 #define NEXTDOSPART 32 #define DOSMAGICOFFSET 510 #define DOSMAGIC 0xAA55 #define DOSPTYP_EXT 0x05 /* DOS extended partition */ #define DOSPTYP_FAT16 0x06 /* FAT16 partition */ #define DOSPTYP_NTFS 0x07 /* NTFS partition */ #define DOSPTYP_FAT32 0x0b /* FAT32 partition */ #define DOSPTYP_EXTLBA 0x0f /* DOS extended partition */ #define DOSPTYP_PPCBOOT 0x41 /* PReP/CHRP boot partition */ #define DOSPTYP_LDM 0x42 /* Win2k dynamic extended partition */ #define DOSPTYP_LINSWP 0x82 /* Linux swap partition */ #define DOSPTYP_LINUX 0x83 /* Linux partition */ #define DOSPTYP_LINLVM 0x8e /* Linux LVM partition */ #define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */ #define DOSPTYP_APPLE_UFS 0xa8 /* Apple Mac OS X UFS */ #define DOSPTYP_APPLE_BOOT 0xab /* Apple Mac OS X boot */ #define DOSPTYP_HFS 0xaf /* HFS/HFS+ partition type */ #define DOSPTYP_SUNIXOS2 0xbf /* Solaris2 partition */ #define DOSPTYP_PMBR 0xee /* GPT Protective MBR */ #define DOSPTYP_EFI 0xef /* EFI FAT parition */ #define DOSPTYP_VMFS 0xfb /* VMware VMFS partition */ #define DOSPTYP_VMKDIAG 0xfc /* VMware vmkDiagnostic partition */ #define DOSPTYP_LINRAID 0xfd /* Linux raid partition */ struct dos_partition { unsigned char dp_flag; /* bootstrap flags */ unsigned char dp_shd; /* starting head */ unsigned char dp_ssect; /* starting sector */ unsigned char dp_scyl; /* starting cylinder */ unsigned char dp_typ; /* partition type */ unsigned char dp_ehd; /* end head */ unsigned char dp_esect; /* end sector */ unsigned char dp_ecyl; /* end cylinder */ u_int32_t dp_start; /* absolute starting sector number */ u_int32_t dp_size; /* partition size in sectors */ }; #ifdef CTASSERT CTASSERT(sizeof (struct dos_partition) == DOSPARTSIZE); #endif void dos_partition_dec(void const *pp, struct dos_partition *d); void dos_partition_enc(void *pp, struct dos_partition *d); #define DPSECT(s) ((s) & 0x3f) /* isolate relevant bits of sector */ #define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* and those that are cylinder */ #define DIOCSMBR _IOW('M', 129, u_char[512]) #endif /* !_SYS_DISKMBR_H_ */ /*- * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * * $FreeBSD$ */ #ifndef _SYS_EFI_H_ #define _SYS_EFI_H_ #include #define EFI_PAGE_SHIFT 12 #define EFI_PAGE_SIZE (1 << EFI_PAGE_SHIFT) #define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1) #define EFI_TABLE_ACPI20 \ {0x8868e871,0xe4f1,0x11d3,0xbc,0x22,{0x00,0x80,0xc7,0x3c,0x88,0x81}} #define EFI_TABLE_SAL \ {0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}} enum efi_reset { EFI_RESET_COLD, EFI_RESET_WARM }; typedef uint16_t efi_char; typedef unsigned long efi_status; struct efi_cfgtbl { struct uuid ct_uuid; uint64_t ct_data; }; struct efi_md { uint32_t md_type; #define EFI_MD_TYPE_NULL 0 #define EFI_MD_TYPE_CODE 1 /* Loader text. */ #define EFI_MD_TYPE_DATA 2 /* Loader data. */ #define EFI_MD_TYPE_BS_CODE 3 /* Boot services text. */ #define EFI_MD_TYPE_BS_DATA 4 /* Boot services data. */ #define EFI_MD_TYPE_RT_CODE 5 /* Runtime services text. */ #define EFI_MD_TYPE_RT_DATA 6 /* Runtime services data. */ #define EFI_MD_TYPE_FREE 7 /* Unused/free memory. */ #define EFI_MD_TYPE_BAD 8 /* Bad memory */ #define EFI_MD_TYPE_RECLAIM 9 /* ACPI reclaimable memory. */ #define EFI_MD_TYPE_FIRMWARE 10 /* ACPI NV memory */ #define EFI_MD_TYPE_IOMEM 11 /* Memory-mapped I/O. */ #define EFI_MD_TYPE_IOPORT 12 /* I/O port space. */ #define EFI_MD_TYPE_PALCODE 13 /* PAL */ uint32_t __pad; uint64_t md_phys; void *md_virt; uint64_t md_pages; uint64_t md_attr; #define EFI_MD_ATTR_UC 0x0000000000000001UL #define EFI_MD_ATTR_WC 0x0000000000000002UL #define EFI_MD_ATTR_WT 0x0000000000000004UL #define EFI_MD_ATTR_WB 0x0000000000000008UL #define EFI_MD_ATTR_UCE 0x0000000000000010UL #define EFI_MD_ATTR_WP 0x0000000000001000UL #define EFI_MD_ATTR_RP 0x0000000000002000UL #define EFI_MD_ATTR_XP 0x0000000000004000UL #define EFI_MD_ATTR_RT 0x8000000000000000UL }; struct efi_tm { uint16_t tm_year; /* 1998 - 20XX */ uint8_t tm_mon; /* 1 - 12 */ uint8_t tm_mday; /* 1 - 31 */ uint8_t tm_hour; /* 0 - 23 */ uint8_t tm_min; /* 0 - 59 */ uint8_t tm_sec; /* 0 - 59 */ uint8_t __pad1; uint32_t tm_nsec; /* 0 - 999,999,999 */ int16_t tm_tz; /* -1440 to 1440 or 2047 */ uint8_t tm_dst; uint8_t __pad2; }; struct efi_tmcap { uint32_t tc_res; /* 1e-6 parts per million */ uint32_t tc_prec; /* hertz */ uint8_t tc_stz; /* Set clears sub-second time */ }; struct efi_tblhdr { uint64_t th_sig; uint32_t th_rev; uint32_t th_hdrsz; uint32_t th_crc32; uint32_t __res; }; struct efi_rt { struct efi_tblhdr rt_hdr; efi_status (*rt_gettime)(struct efi_tm *, struct efi_tmcap *); efi_status (*rt_settime)(struct efi_tm *); efi_status (*rt_getwaketime)(uint8_t *, uint8_t *, struct efi_tm *); efi_status (*rt_setwaketime)(uint8_t, struct efi_tm *); efi_status (*rt_setvirtual)(u_long, u_long, uint32_t, struct efi_md *); efi_status (*rt_cvtptr)(u_long, void **); efi_status (*rt_getvar)(efi_char *, struct uuid *, uint32_t *, u_long *, void *); efi_status (*rt_scanvar)(u_long *, efi_char *, struct uuid *); efi_status (*rt_setvar)(efi_char *, struct uuid *, uint32_t, u_long, void *); efi_status (*rt_gethicnt)(uint32_t *); efi_status (*rt_reset)(enum efi_reset, efi_status, u_long, efi_char *); }; struct efi_systbl { struct efi_tblhdr st_hdr; #define EFI_SYSTBL_SIG 0x5453595320494249UL efi_char *st_fwvendor; uint32_t st_fwrev; uint32_t __pad; void *st_cin; void *st_cinif; void *st_cout; void *st_coutif; void *st_cerr; void *st_cerrif; uint64_t st_rt; void *st_bs; u_long st_entries; uint64_t st_cfgtbl; }; extern vm_paddr_t efi_systbl; #endif /* _SYS_EFI_H_ */ /*- * Copyright (c) 2001 David E. O'Brien. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ /* * This is a Solaris compatibility header */ #ifndef _SYS_ELF_H_ #define _SYS_ELF_H_ #include #include #include #include #endif /* !_SYS_ELF_H_ */ /*- * Copyright (c) 1996-1998 John D. Polstra. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_ELF32_H_ #define _SYS_ELF32_H_ 1 #include /* * ELF definitions common to all 32-bit architectures. */ typedef uint32_t Elf32_Addr; typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Off; typedef int32_t Elf32_Sword; typedef uint32_t Elf32_Word; typedef uint64_t Elf32_Lword; typedef Elf32_Word Elf32_Hashelt; /* Non-standard class-dependent datatype used for abstraction. */ typedef Elf32_Word Elf32_Size; typedef Elf32_Sword Elf32_Ssize; /* * ELF header. */ typedef struct { unsigned char e_ident[EI_NIDENT]; /* File identification. */ Elf32_Half e_type; /* File type. */ Elf32_Half e_machine; /* Machine architecture. */ Elf32_Word e_version; /* ELF format version. */ Elf32_Addr e_entry; /* Entry point. */ Elf32_Off e_phoff; /* Program header file offset. */ Elf32_Off e_shoff; /* Section header file offset. */ Elf32_Word e_flags; /* Architecture-specific flags. */ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ Elf32_Half e_phentsize; /* Size of program header entry. */ Elf32_Half e_phnum; /* Number of program header entries. */ Elf32_Half e_shentsize; /* Size of section header entry. */ Elf32_Half e_shnum; /* Number of section header entries. */ Elf32_Half e_shstrndx; /* Section name strings section. */ } Elf32_Ehdr; /* * Shared object information, found in SHT_MIPS_LIBLIST. */ typedef struct { Elf32_Word l_name; /* The name of a shared object. */ Elf32_Word l_time_stamp; /* 32-bit timestamp. */ Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ Elf32_Word l_version; /* Interface version string index. */ Elf32_Word l_flags; /* Flags (LL_*). */ } Elf32_Lib; /* * Section header. */ typedef struct { Elf32_Word sh_name; /* Section name (index into the section header string table). */ Elf32_Word sh_type; /* Section type. */ Elf32_Word sh_flags; /* Section flags. */ Elf32_Addr sh_addr; /* Address in memory image. */ Elf32_Off sh_offset; /* Offset in file. */ Elf32_Word sh_size; /* Size in bytes. */ Elf32_Word sh_link; /* Index of a related section. */ Elf32_Word sh_info; /* Depends on section type. */ Elf32_Word sh_addralign; /* Alignment in bytes. */ Elf32_Word sh_entsize; /* Size of each entry in section. */ } Elf32_Shdr; /* * Program header. */ typedef struct { Elf32_Word p_type; /* Entry type. */ Elf32_Off p_offset; /* File offset of contents. */ Elf32_Addr p_vaddr; /* Virtual address in memory image. */ Elf32_Addr p_paddr; /* Physical address (not used). */ Elf32_Word p_filesz; /* Size of contents in file. */ Elf32_Word p_memsz; /* Size of contents in memory. */ Elf32_Word p_flags; /* Access permission flags. */ Elf32_Word p_align; /* Alignment in memory and file. */ } Elf32_Phdr; /* * Dynamic structure. The ".dynamic" section contains an array of them. */ typedef struct { Elf32_Sword d_tag; /* Entry type. */ union { Elf32_Word d_val; /* Integer value. */ Elf32_Addr d_ptr; /* Address value. */ } d_un; } Elf32_Dyn; /* * Relocation entries. */ /* Relocations that don't need an addend field. */ typedef struct { Elf32_Addr r_offset; /* Location to be relocated. */ Elf32_Word r_info; /* Relocation type and symbol index. */ } Elf32_Rel; /* Relocations that need an addend field. */ typedef struct { Elf32_Addr r_offset; /* Location to be relocated. */ Elf32_Word r_info; /* Relocation type and symbol index. */ Elf32_Sword r_addend; /* Addend. */ } Elf32_Rela; /* Macros for accessing the fields of r_info. */ #define ELF32_R_SYM(info) ((info) >> 8) #define ELF32_R_TYPE(info) ((unsigned char)(info)) /* Macro for constructing r_info from field values. */ #define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) /* * Note entry header */ typedef Elf_Note Elf32_Nhdr; /* * Move entry */ typedef struct { Elf32_Lword m_value; /* symbol value */ Elf32_Word m_info; /* size + index */ Elf32_Word m_poffset; /* symbol offset */ Elf32_Half m_repeat; /* repeat count */ Elf32_Half m_stride; /* stride info */ } Elf32_Move; /* * The macros compose and decompose values for Move.r_info * * sym = ELF32_M_SYM(M.m_info) * size = ELF32_M_SIZE(M.m_info) * M.m_info = ELF32_M_INFO(sym, size) */ #define ELF32_M_SYM(info) ((info)>>8) #define ELF32_M_SIZE(info) ((unsigned char)(info)) #define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) /* * Hardware/Software capabilities entry */ typedef struct { Elf32_Word c_tag; /* how to interpret value */ union { Elf32_Word c_val; Elf32_Addr c_ptr; } c_un; } Elf32_Cap; /* * Symbol table entries. */ typedef struct { Elf32_Word st_name; /* String table index of name. */ Elf32_Addr st_value; /* Symbol value. */ Elf32_Word st_size; /* Size of associated object. */ unsigned char st_info; /* Type and binding information. */ unsigned char st_other; /* Reserved (not used). */ Elf32_Half st_shndx; /* Section index of symbol. */ } Elf32_Sym; /* Macros for accessing the fields of st_info. */ #define ELF32_ST_BIND(info) ((info) >> 4) #define ELF32_ST_TYPE(info) ((info) & 0xf) /* Macro for constructing st_info from field values. */ #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) /* Macro for accessing the fields of st_other. */ #define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) /* Structures used by Sun & GNU symbol versioning. */ typedef struct { Elf32_Half vd_version; Elf32_Half vd_flags; Elf32_Half vd_ndx; Elf32_Half vd_cnt; Elf32_Word vd_hash; Elf32_Word vd_aux; Elf32_Word vd_next; } Elf32_Verdef; typedef struct { Elf32_Word vda_name; Elf32_Word vda_next; } Elf32_Verdaux; typedef struct { Elf32_Half vn_version; Elf32_Half vn_cnt; Elf32_Word vn_file; Elf32_Word vn_aux; Elf32_Word vn_next; } Elf32_Verneed; typedef struct { Elf32_Word vna_hash; Elf32_Half vna_flags; Elf32_Half vna_other; Elf32_Word vna_name; Elf32_Word vna_next; } Elf32_Vernaux; typedef Elf32_Half Elf32_Versym; typedef struct { Elf32_Half si_boundto; /* direct bindings - symbol bound to */ Elf32_Half si_flags; /* per symbol flags */ } Elf32_Syminfo; #endif /* !_SYS_ELF32_H_ */ /*- * Copyright (c) 1996-1998 John D. Polstra. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_ELF64_H_ #define _SYS_ELF64_H_ 1 #include /* * ELF definitions common to all 64-bit architectures. */ typedef uint64_t Elf64_Addr; typedef uint16_t Elf64_Half; typedef uint64_t Elf64_Off; typedef int32_t Elf64_Sword; typedef int64_t Elf64_Sxword; typedef uint32_t Elf64_Word; typedef uint64_t Elf64_Lword; typedef uint64_t Elf64_Xword; /* * Types of dynamic symbol hash table bucket and chain elements. * * This is inconsistent among 64 bit architectures, so a machine dependent * typedef is required. */ typedef Elf64_Word Elf64_Hashelt; /* Non-standard class-dependent datatype used for abstraction. */ typedef Elf64_Xword Elf64_Size; typedef Elf64_Sxword Elf64_Ssize; /* * ELF header. */ typedef struct { unsigned char e_ident[EI_NIDENT]; /* File identification. */ Elf64_Half e_type; /* File type. */ Elf64_Half e_machine; /* Machine architecture. */ Elf64_Word e_version; /* ELF format version. */ Elf64_Addr e_entry; /* Entry point. */ Elf64_Off e_phoff; /* Program header file offset. */ Elf64_Off e_shoff; /* Section header file offset. */ Elf64_Word e_flags; /* Architecture-specific flags. */ Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ Elf64_Half e_phentsize; /* Size of program header entry. */ Elf64_Half e_phnum; /* Number of program header entries. */ Elf64_Half e_shentsize; /* Size of section header entry. */ Elf64_Half e_shnum; /* Number of section header entries. */ Elf64_Half e_shstrndx; /* Section name strings section. */ } Elf64_Ehdr; /* * Shared object information, found in SHT_MIPS_LIBLIST. */ typedef struct { Elf64_Word l_name; /* The name of a shared object. */ Elf64_Word l_time_stamp; /* 64-bit timestamp. */ Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */ Elf64_Word l_version; /* Interface version string index. */ Elf64_Word l_flags; /* Flags (LL_*). */ } Elf64_Lib; /* * Section header. */ typedef struct { Elf64_Word sh_name; /* Section name (index into the section header string table). */ Elf64_Word sh_type; /* Section type. */ Elf64_Xword sh_flags; /* Section flags. */ Elf64_Addr sh_addr; /* Address in memory image. */ Elf64_Off sh_offset; /* Offset in file. */ Elf64_Xword sh_size; /* Size in bytes. */ Elf64_Word sh_link; /* Index of a related section. */ Elf64_Word sh_info; /* Depends on section type. */ Elf64_Xword sh_addralign; /* Alignment in bytes. */ Elf64_Xword sh_entsize; /* Size of each entry in section. */ } Elf64_Shdr; /* * Program header. */ typedef struct { Elf64_Word p_type; /* Entry type. */ Elf64_Word p_flags; /* Access permission flags. */ Elf64_Off p_offset; /* File offset of contents. */ Elf64_Addr p_vaddr; /* Virtual address in memory image. */ Elf64_Addr p_paddr; /* Physical address (not used). */ Elf64_Xword p_filesz; /* Size of contents in file. */ Elf64_Xword p_memsz; /* Size of contents in memory. */ Elf64_Xword p_align; /* Alignment in memory and file. */ } Elf64_Phdr; /* * Dynamic structure. The ".dynamic" section contains an array of them. */ typedef struct { Elf64_Sxword d_tag; /* Entry type. */ union { Elf64_Xword d_val; /* Integer value. */ Elf64_Addr d_ptr; /* Address value. */ } d_un; } Elf64_Dyn; /* * Relocation entries. */ /* Relocations that don't need an addend field. */ typedef struct { Elf64_Addr r_offset; /* Location to be relocated. */ Elf64_Xword r_info; /* Relocation type and symbol index. */ } Elf64_Rel; /* Relocations that need an addend field. */ typedef struct { Elf64_Addr r_offset; /* Location to be relocated. */ Elf64_Xword r_info; /* Relocation type and symbol index. */ Elf64_Sxword r_addend; /* Addend. */ } Elf64_Rela; /* Macros for accessing the fields of r_info. */ #define ELF64_R_SYM(info) ((info) >> 32) #define ELF64_R_TYPE(info) ((info) & 0xffffffffL) /* Macro for constructing r_info from field values. */ #define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) #define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) #define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) #define ELF64_R_TYPE_INFO(data, type) \ (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) /* * Note entry header */ typedef Elf_Note Elf64_Nhdr; /* * Move entry */ typedef struct { Elf64_Lword m_value; /* symbol value */ Elf64_Xword m_info; /* size + index */ Elf64_Xword m_poffset; /* symbol offset */ Elf64_Half m_repeat; /* repeat count */ Elf64_Half m_stride; /* stride info */ } Elf64_Move; #define ELF64_M_SYM(info) ((info)>>8) #define ELF64_M_SIZE(info) ((unsigned char)(info)) #define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) /* * Hardware/Software capabilities entry */ typedef struct { Elf64_Xword c_tag; /* how to interpret value */ union { Elf64_Xword c_val; Elf64_Addr c_ptr; } c_un; } Elf64_Cap; /* * Symbol table entries. */ typedef struct { Elf64_Word st_name; /* String table index of name. */ unsigned char st_info; /* Type and binding information. */ unsigned char st_other; /* Reserved (not used). */ Elf64_Half st_shndx; /* Section index of symbol. */ Elf64_Addr st_value; /* Symbol value. */ Elf64_Xword st_size; /* Size of associated object. */ } Elf64_Sym; /* Macros for accessing the fields of st_info. */ #define ELF64_ST_BIND(info) ((info) >> 4) #define ELF64_ST_TYPE(info) ((info) & 0xf) /* Macro for constructing st_info from field values. */ #define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) /* Macro for accessing the fields of st_other. */ #define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) /* Structures used by Sun & GNU-style symbol versioning. */ typedef struct { Elf64_Half vd_version; Elf64_Half vd_flags; Elf64_Half vd_ndx; Elf64_Half vd_cnt; Elf64_Word vd_hash; Elf64_Word vd_aux; Elf64_Word vd_next; } Elf64_Verdef; typedef struct { Elf64_Word vda_name; Elf64_Word vda_next; } Elf64_Verdaux; typedef struct { Elf64_Half vn_version; Elf64_Half vn_cnt; Elf64_Word vn_file; Elf64_Word vn_aux; Elf64_Word vn_next; } Elf64_Verneed; typedef struct { Elf64_Word vna_hash; Elf64_Half vna_flags; Elf64_Half vna_other; Elf64_Word vna_name; Elf64_Word vna_next; } Elf64_Vernaux; typedef Elf64_Half Elf64_Versym; typedef struct { Elf64_Half si_boundto; /* direct bindings - symbol bound to */ Elf64_Half si_flags; /* per symbol flags */ } Elf64_Syminfo; #endif /* !_SYS_ELF64_H_ */ /*- * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien * Copyright (c) 1998 John D. Polstra. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_ELF_COMMON_H_ #define _SYS_ELF_COMMON_H_ 1 /* * ELF definitions that are independent of architecture or word size. */ /* * Note header. The ".note" section contains an array of notes. Each * begins with this header, aligned to a word boundary. Immediately * following the note header is n_namesz bytes of name, padded to the * next word boundary. Then comes n_descsz bytes of descriptor, again * padded to a word boundary. The values of n_namesz and n_descsz do * not include the padding. */ typedef struct { u_int32_t n_namesz; /* Length of name. */ u_int32_t n_descsz; /* Length of descriptor. */ u_int32_t n_type; /* Type of this note. */ } Elf_Note; /* * Option kinds. */ #define ODK_NULL 0 /* undefined */ #define ODK_REGINFO 1 /* register usage info */ #define ODK_EXCEPTIONS 2 /* exception processing info */ #define ODK_PAD 3 /* section padding */ #define ODK_HWPATCH 4 /* hardware patch applied */ #define ODK_FILL 5 /* fill value used by the linker */ #define ODK_TAGS 6 /* reserved space for tools */ #define ODK_HWAND 7 /* hardware AND patch applied */ #define ODK_HWOR 8 /* hardware OR patch applied */ #define ODK_GP_GROUP 9 /* GP group for text/data sections */ #define ODK_IDENT 10 /* ID information */ #define ODK_PAGESIZE 11 /* page size information */ /* * ODK_EXCEPTIONS info field masks. */ #define OEX_FPU_MIN 0x0000001f /* min FPU exception required */ #define OEX_FPU_MAX 0x00001f00 /* max FPU exception allowed */ #define OEX_PAGE0 0x00010000 /* page zero must be mapped */ #define OEX_SMM 0x00020000 /* run in sequential memory mode */ #define OEX_PRECISEFP 0x00040000 /* run in precise FP exception mode */ #define OEX_DISMISS 0x00080000 /* dismiss invalid address traps */ /* * ODK_PAD info field masks. */ #define OPAD_PREFIX 0x0001 #define OPAD_POSTFIX 0x0002 #define OPAD_SYMBOL 0x0004 /* * ODK_HWPATCH info field masks. */ #define OHW_R4KEOP 0x00000001 /* patch for R4000 branch at end-of-page bug */ #define OHW_R8KPFETCH 0x00000002 /* R8000 prefetch bug may occur */ #define OHW_R5KEOP 0x00000004 /* patch for R5000 branch at end-of-page bug */ #define OHW_R5KCVTL 0x00000008 /* R5000 cvt.[ds].l bug: clean == 1 */ #define OHW_R10KLDL 0x00000010UL /* need patch for R10000 misaligned load */ /* * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks. */ #define OHWA0_R4KEOP_CHECKED 0x00000001 /* object checked for R4000 end-of-page bug */ #define OHWA0_R4KEOP_CLEAN 0x00000002 /* object verified clean for R4000 end-of-page bug */ #define OHWO0_FIXADE 0x00000001 /* object requires call to fixade */ /* * ODK_IDENT/ODK_GP_GROUP info field masks. */ #define OGP_GROUP 0x0000ffff /* GP group number */ #define OGP_SELF 0x00010000 /* GP group is self-contained */ /* * The header for GNU-style hash sections. */ typedef struct { u_int32_t gh_nbuckets; /* Number of hash buckets. */ u_int32_t gh_symndx; /* First visible symbol in .dynsym. */ u_int32_t gh_maskwords; /* #maskwords used in bloom filter. */ u_int32_t gh_shift2; /* Bloom filter shift count. */ } Elf_GNU_Hash_Header; /* Indexes into the e_ident array. Keep synced with http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ #define EI_MAG0 0 /* Magic number, byte 0. */ #define EI_MAG1 1 /* Magic number, byte 1. */ #define EI_MAG2 2 /* Magic number, byte 2. */ #define EI_MAG3 3 /* Magic number, byte 3. */ #define EI_CLASS 4 /* Class of machine. */ #define EI_DATA 5 /* Data format. */ #define EI_VERSION 6 /* ELF format version. */ #define EI_OSABI 7 /* Operating system / ABI identification */ #define EI_ABIVERSION 8 /* ABI version */ #define OLD_EI_BRAND 8 /* Start of architecture identification. */ #define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ #define EI_NIDENT 16 /* Size of e_ident array. */ /* Values for the magic number bytes. */ #define ELFMAG0 0x7f #define ELFMAG1 'E' #define ELFMAG2 'L' #define ELFMAG3 'F' #define ELFMAG "\177ELF" /* magic string */ #define SELFMAG 4 /* magic string size */ /* Values for e_ident[EI_VERSION] and e_version. */ #define EV_NONE 0 #define EV_CURRENT 1 /* Values for e_ident[EI_CLASS]. */ #define ELFCLASSNONE 0 /* Unknown class. */ #define ELFCLASS32 1 /* 32-bit architecture. */ #define ELFCLASS64 2 /* 64-bit architecture. */ /* Values for e_ident[EI_DATA]. */ #define ELFDATANONE 0 /* Unknown data format. */ #define ELFDATA2LSB 1 /* 2's complement little-endian. */ #define ELFDATA2MSB 2 /* 2's complement big-endian. */ /* Values for e_ident[EI_OSABI]. */ #define ELFOSABI_NONE 0 /* UNIX System V ABI */ #define ELFOSABI_HPUX 1 /* HP-UX operating system */ #define ELFOSABI_NETBSD 2 /* NetBSD */ #define ELFOSABI_LINUX 3 /* GNU/Linux */ #define ELFOSABI_HURD 4 /* GNU/Hurd */ #define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ #define ELFOSABI_SOLARIS 6 /* Solaris */ #define ELFOSABI_AIX 7 /* AIX */ #define ELFOSABI_IRIX 8 /* IRIX */ #define ELFOSABI_FREEBSD 9 /* FreeBSD */ #define ELFOSABI_TRU64 10 /* TRU64 UNIX */ #define ELFOSABI_MODESTO 11 /* Novell Modesto */ #define ELFOSABI_OPENBSD 12 /* OpenBSD */ #define ELFOSABI_OPENVMS 13 /* Open VMS */ #define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ #define ELFOSABI_AROS 15 /* Amiga Research OS */ #define ELFOSABI_FENIXOS 16 /* FenixOS */ #define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ #define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ #define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ #define ELFOSABI_GNU ELFOSABI_LINUX /* e_ident */ #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ (ehdr).e_ident[EI_MAG3] == ELFMAG3) /* Values for e_type. */ #define ET_NONE 0 /* Unknown type. */ #define ET_REL 1 /* Relocatable. */ #define ET_EXEC 2 /* Executable. */ #define ET_DYN 3 /* Shared object. */ #define ET_CORE 4 /* Core file. */ #define ET_LOOS 0xfe00 /* First operating system specific. */ #define ET_HIOS 0xfeff /* Last operating system-specific. */ #define ET_LOPROC 0xff00 /* First processor-specific. */ #define ET_HIPROC 0xffff /* Last processor-specific. */ /* Values for e_machine. */ #define EM_NONE 0 /* Unknown machine. */ #define EM_M32 1 /* AT&T WE32100. */ #define EM_SPARC 2 /* Sun SPARC. */ #define EM_386 3 /* Intel i386. */ #define EM_68K 4 /* Motorola 68000. */ #define EM_88K 5 /* Motorola 88000. */ #define EM_IAMCU 6 /* Intel MCU. */ #define EM_860 7 /* Intel i860. */ #define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ #define EM_S370 9 /* IBM System/370. */ #define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ #define EM_PARISC 15 /* HP PA-RISC. */ #define EM_VPP500 17 /* Fujitsu VPP500. */ #define EM_SPARC32PLUS 18 /* SPARC v8plus. */ #define EM_960 19 /* Intel 80960. */ #define EM_PPC 20 /* PowerPC 32-bit. */ #define EM_PPC64 21 /* PowerPC 64-bit. */ #define EM_S390 22 /* IBM System/390. */ #define EM_V800 36 /* NEC V800. */ #define EM_FR20 37 /* Fujitsu FR20. */ #define EM_RH32 38 /* TRW RH-32. */ #define EM_RCE 39 /* Motorola RCE. */ #define EM_ARM 40 /* ARM. */ #define EM_SH 42 /* Hitachi SH. */ #define EM_SPARCV9 43 /* SPARC v9 64-bit. */ #define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ #define EM_ARC 45 /* Argonaut RISC Core. */ #define EM_H8_300 46 /* Hitachi H8/300. */ #define EM_H8_300H 47 /* Hitachi H8/300H. */ #define EM_H8S 48 /* Hitachi H8S. */ #define EM_H8_500 49 /* Hitachi H8/500. */ #define EM_IA_64 50 /* Intel IA-64 Processor. */ #define EM_MIPS_X 51 /* Stanford MIPS-X. */ #define EM_COLDFIRE 52 /* Motorola ColdFire. */ #define EM_68HC12 53 /* Motorola M68HC12. */ #define EM_MMA 54 /* Fujitsu MMA. */ #define EM_PCP 55 /* Siemens PCP. */ #define EM_NCPU 56 /* Sony nCPU. */ #define EM_NDR1 57 /* Denso NDR1 microprocessor. */ #define EM_STARCORE 58 /* Motorola Star*Core processor. */ #define EM_ME16 59 /* Toyota ME16 processor. */ #define EM_ST100 60 /* STMicroelectronics ST100 processor. */ #define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ #define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ #define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ #define EM_PDSP 63 /* Sony DSP Processor. */ #define EM_FX66 66 /* Siemens FX66 microcontroller. */ #define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 microcontroller. */ #define EM_ST7 68 /* STmicroelectronics ST7 8-bit microcontroller. */ #define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */ #define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */ #define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */ #define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */ #define EM_SVX 73 /* Silicon Graphics SVx. */ #define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */ #define EM_VAX 75 /* Digital VAX. */ #define EM_CRIS 76 /* Axis Communications 32-bit embedded processor. */ #define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor. */ #define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */ #define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */ #define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */ #define EM_HUANY 81 /* Harvard University machine-independent object files. */ #define EM_PRISM 82 /* SiTera Prism. */ #define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */ #define EM_FR30 84 /* Fujitsu FR30. */ #define EM_D10V 85 /* Mitsubishi D10V. */ #define EM_D30V 86 /* Mitsubishi D30V. */ #define EM_V850 87 /* NEC v850. */ #define EM_M32R 88 /* Mitsubishi M32R. */ #define EM_MN10300 89 /* Matsushita MN10300. */ #define EM_MN10200 90 /* Matsushita MN10200. */ #define EM_PJ 91 /* picoJava. */ #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */ #define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */ #define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor. */ #define EM_NS32K 97 /* National Semiconductor 32000 series. */ #define EM_TPC 98 /* Tenor Network TPC processor. */ #define EM_SNP1K 99 /* Trebia SNP 1000 processor. */ #define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */ #define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */ #define EM_MAX 102 /* MAX Processor. */ #define EM_CR 103 /* National Semiconductor CompactRISC microprocessor. */ #define EM_F2MC16 104 /* Fujitsu F2MC16. */ #define EM_MSP430 105 /* Texas Instruments embedded microcontroller msp430. */ #define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */ #define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */ #define EM_SEP 108 /* Sharp embedded microprocessor. */ #define EM_ARCA 109 /* Arca RISC Microprocessor. */ #define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ #define EM_AARCH64 183 /* AArch64 (64-bit ARM) */ #define EM_RISCV 243 /* RISC-V */ /* Non-standard or deprecated. */ #define EM_486 6 /* Intel i486. */ #define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ #define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ #define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ /** * e_flags */ #define EF_ARM_RELEXEC 0x1 #define EF_ARM_HASENTRY 0x2 #define EF_ARM_SYMSARESORTED 0x4 #define EF_ARM_DYNSYMSUSESEGIDX 0x8 #define EF_ARM_MAPSYMSFIRST 0x10 #define EF_ARM_LE8 0x00400000 #define EF_ARM_BE8 0x00800000 #define EF_ARM_EABIMASK 0xFF000000 #define EF_ARM_EABI_UNKNOWN 0x00000000 #define EF_ARM_EABI_VER1 0x01000000 #define EF_ARM_EABI_VER2 0x02000000 #define EF_ARM_EABI_VER3 0x03000000 #define EF_ARM_EABI_VER4 0x04000000 #define EF_ARM_EABI_VER5 0x05000000 #define EF_ARM_INTERWORK 0x00000004 #define EF_ARM_APCS_26 0x00000008 #define EF_ARM_APCS_FLOAT 0x00000010 #define EF_ARM_PIC 0x00000020 #define EF_ARM_ALIGN8 0x00000040 #define EF_ARM_NEW_ABI 0x00000080 #define EF_ARM_OLD_ABI 0x00000100 #define EF_ARM_SOFT_FLOAT 0x00000200 #define EF_ARM_VFP_FLOAT 0x00000400 #define EF_ARM_MAVERICK_FLOAT 0x00000800 #define EF_MIPS_NOREORDER 0x00000001 #define EF_MIPS_PIC 0x00000002 /* Contains PIC code */ #define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */ #define EF_MIPS_UCODE 0x00000010 #define EF_MIPS_ABI2 0x00000020 /* N32 */ #define EF_MIPS_OPTIONS_FIRST 0x00000080 #define EF_MIPS_ARCH_ASE 0x0F000000 /* Architectural extensions */ #define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* MDMX multimedia extension */ #define EF_MIPS_ARCH_ASE_M16 0x04000000 /* MIPS-16 ISA extensions */ #define EF_MIPS_ARCH 0xF0000000 /* Architecture field */ #define EF_PPC_EMB 0x80000000 #define EF_PPC_RELOCATABLE 0x00010000 #define EF_PPC_RELOCATABLE_LIB 0x00008000 #define EF_SPARC_EXT_MASK 0x00ffff00 #define EF_SPARC_32PLUS 0x00000100 #define EF_SPARC_SUN_US1 0x00000200 #define EF_SPARC_HAL_R1 0x00000200 #define EF_SPARC_SUN_US3 0x00000800 #define EF_SPARCV9_MM 0x00000003 #define EF_SPARCV9_TSO 0x00000000 #define EF_SPARCV9_PSO 0x00000001 #define EF_SPARCV9_RMO 0x00000002 /* Special section indexes. */ #define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ #define SHN_LORESERVE 0xff00 /* First of reserved range. */ #define SHN_LOPROC 0xff00 /* First processor-specific. */ #define SHN_HIPROC 0xff1f /* Last processor-specific. */ #define SHN_LOOS 0xff20 /* First operating system-specific. */ #define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj linker only: Cached global in local symtab. */ #define SHN_HIOS 0xff3f /* Last operating system-specific. */ #define SHN_ABS 0xfff1 /* Absolute values. */ #define SHN_COMMON 0xfff2 /* Common data. */ #define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ #define SHN_HIRESERVE 0xffff /* Last of reserved range. */ /* sh_type */ #define SHT_NULL 0 /* inactive */ #define SHT_PROGBITS 1 /* program defined information */ #define SHT_SYMTAB 2 /* symbol table section */ #define SHT_STRTAB 3 /* string table section */ #define SHT_RELA 4 /* relocation section with addends */ #define SHT_HASH 5 /* symbol hash table section */ #define SHT_DYNAMIC 6 /* dynamic section */ #define SHT_NOTE 7 /* note section */ #define SHT_NOBITS 8 /* no space section */ #define SHT_REL 9 /* relocation section - no addends */ #define SHT_SHLIB 10 /* reserved - purpose unknown */ #define SHT_DYNSYM 11 /* dynamic symbol table section */ #define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ #define SHT_FINI_ARRAY 15 /* Termination function pointers. */ #define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ #define SHT_GROUP 17 /* Section group. */ #define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ #define SHT_LOOS 0x60000000 /* First of OS specific semantics */ #define SHT_LOSUNW 0x6ffffff4 #define SHT_SUNW_dof 0x6ffffff4 #define SHT_SUNW_cap 0x6ffffff5 #define SHT_GNU_ATTRIBUTES 0x6ffffff5 #define SHT_SUNW_SIGNATURE 0x6ffffff6 #define SHT_GNU_HASH 0x6ffffff6 #define SHT_GNU_LIBLIST 0x6ffffff7 #define SHT_SUNW_ANNOTATE 0x6ffffff7 #define SHT_SUNW_DEBUGSTR 0x6ffffff8 #define SHT_SUNW_DEBUG 0x6ffffff9 #define SHT_SUNW_move 0x6ffffffa #define SHT_SUNW_COMDAT 0x6ffffffb #define SHT_SUNW_syminfo 0x6ffffffc #define SHT_SUNW_verdef 0x6ffffffd #define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ #define SHT_SUNW_verneed 0x6ffffffe #define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ #define SHT_SUNW_versym 0x6fffffff #define SHT_GNU_versym 0x6fffffff /* Symbol version table */ #define SHT_HISUNW 0x6fffffff #define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ #define SHT_LOPROC 0x70000000 /* reserved range for processor */ #define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ #define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */ #define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map. */ #define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes. */ #define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */ #define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */ #define SHT_MIPS_LIBLIST 0x70000000 #define SHT_MIPS_MSYM 0x70000001 #define SHT_MIPS_CONFLICT 0x70000002 #define SHT_MIPS_GPTAB 0x70000003 #define SHT_MIPS_UCODE 0x70000004 #define SHT_MIPS_DEBUG 0x70000005 #define SHT_MIPS_REGINFO 0x70000006 #define SHT_MIPS_PACKAGE 0x70000007 #define SHT_MIPS_PACKSYM 0x70000008 #define SHT_MIPS_RELD 0x70000009 #define SHT_MIPS_IFACE 0x7000000b #define SHT_MIPS_CONTENT 0x7000000c #define SHT_MIPS_OPTIONS 0x7000000d #define SHT_MIPS_DELTASYM 0x7000001b #define SHT_MIPS_DELTAINST 0x7000001c #define SHT_MIPS_DELTACLASS 0x7000001d #define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ #define SHT_MIPS_DELTADECL 0x7000001f #define SHT_MIPS_SYMBOL_LIB 0x70000020 #define SHT_MIPS_EVENTS 0x70000021 #define SHT_MIPS_TRANSLATE 0x70000022 #define SHT_MIPS_PIXIE 0x70000023 #define SHT_MIPS_XLATE 0x70000024 #define SHT_MIPS_XLATE_DEBUG 0x70000025 #define SHT_MIPS_WHIRL 0x70000026 #define SHT_MIPS_EH_REGION 0x70000027 #define SHT_MIPS_XLATE_OLD 0x70000028 #define SHT_MIPS_PDR_EXCEPTION 0x70000029 #define SHT_MIPS_ABIFLAGS 0x7000002a #define SHT_SPARC_GOTDATA 0x70000000 #define SHTORDERED #define SHT_HIPROC 0x7fffffff /* specific section header types */ #define SHT_LOUSER 0x80000000 /* reserved range for application */ #define SHT_HIUSER 0xffffffff /* specific indexes */ /* Flags for sh_flags. */ #define SHF_WRITE 0x1 /* Section contains writable data. */ #define SHF_ALLOC 0x2 /* Section occupies memory. */ #define SHF_EXECINSTR 0x4 /* Section contains instructions. */ #define SHF_MERGE 0x10 /* Section may be merged. */ #define SHF_STRINGS 0x20 /* Section contains strings. */ #define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ #define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ #define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ #define SHF_GROUP 0x200 /* Member of section group. */ #define SHF_TLS 0x400 /* Section contains TLS data. */ #define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ #define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ /* Flags for section groups. */ #define GRP_COMDAT 0x1 /* COMDAT semantics. */ /* * Flags / mask for .gnu.versym sections. */ #define VERSYM_VERSION 0x7fff #define VERSYM_HIDDEN 0x8000 /* Values for p_type. */ #define PT_NULL 0 /* Unused entry. */ #define PT_LOAD 1 /* Loadable segment. */ #define PT_DYNAMIC 2 /* Dynamic linking information segment. */ #define PT_INTERP 3 /* Pathname of interpreter. */ #define PT_NOTE 4 /* Auxiliary information. */ #define PT_SHLIB 5 /* Reserved (not used). */ #define PT_PHDR 6 /* Location of program header itself. */ #define PT_TLS 7 /* Thread local storage segment */ #define PT_LOOS 0x60000000 /* First OS-specific. */ #define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ #define PT_GNU_EH_FRAME 0x6474e550 #define PT_GNU_STACK 0x6474e551 #define PT_GNU_RELRO 0x6474e552 #define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps (currently arm). */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ #define PT_SUNWDTRACE 0x6ffffffc /* private */ #define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ #define PT_HISUNW 0x6fffffff #define PT_HIOS 0x6fffffff /* Last OS-specific. */ #define PT_LOPROC 0x70000000 /* First processor-specific type. */ #define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ /* Values for p_flags. */ #define PF_X 0x1 /* Executable. */ #define PF_W 0x2 /* Writable. */ #define PF_R 0x4 /* Readable. */ #define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ #define PF_MASKPROC 0xf0000000 /* Processor-specific. */ /* Extended program header index. */ #define PN_XNUM 0xffff /* Values for d_tag. */ #define DT_NULL 0 /* Terminating entry. */ #define DT_NEEDED 1 /* String table offset of a needed shared library. */ #define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ #define DT_PLTGOT 3 /* Processor-dependent address. */ #define DT_HASH 4 /* Address of symbol hash table. */ #define DT_STRTAB 5 /* Address of string table. */ #define DT_SYMTAB 6 /* Address of symbol table. */ #define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ #define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ #define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ #define DT_STRSZ 10 /* Size of string table. */ #define DT_SYMENT 11 /* Size of each symbol table entry. */ #define DT_INIT 12 /* Address of initialization function. */ #define DT_FINI 13 /* Address of finalization function. */ #define DT_SONAME 14 /* String table offset of shared object name. */ #define DT_RPATH 15 /* String table offset of library path. [sup] */ #define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ #define DT_REL 17 /* Address of ElfNN_Rel relocations. */ #define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ #define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ #define DT_PLTREL 20 /* Type of relocation used for PLT. */ #define DT_DEBUG 21 /* Reserved (not used). */ #define DT_TEXTREL 22 /* Indicates there may be relocations in non-writable segments. [sup] */ #define DT_JMPREL 23 /* Address of PLT relocations. */ #define DT_BIND_NOW 24 /* [sup] */ #define DT_INIT_ARRAY 25 /* Address of the array of pointers to initialization functions */ #define DT_FINI_ARRAY 26 /* Address of the array of pointers to termination functions */ #define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of initialization functions. */ #define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of termination functions. */ #define DT_RUNPATH 29 /* String table offset of a null-terminated library search path string. */ #define DT_FLAGS 30 /* Object specific flag values. */ #define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING and less than DT_LOOS follow the rules for the interpretation of the d_un union as follows: even == 'd_ptr', odd == 'd_val' or none */ #define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to pre-initialization functions. */ #define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of pre-initialization functions. */ #define DT_MAXPOSTAGS 34 /* number of positive tags */ #define DT_LOOS 0x6000000d /* First OS-specific */ #define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ #define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ #define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ #define DT_SUNW_CAP 0x60000010 /* hardware/software */ #define DT_HIOS 0x6ffff000 /* Last OS-specific */ /* * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the * Dyn.d_un.d_val field of the Elf*_Dyn structure. */ #define DT_VALRNGLO 0x6ffffd00 #define DT_GNU_PRELINKED 0x6ffffdf5 /* prelinking timestamp */ #define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* size of conflict section */ #define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* size of library list */ #define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ #define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ #define DT_MOVEENT 0x6ffffdfa /* move table entry size */ #define DT_MOVESZ 0x6ffffdfb /* move table size */ #define DT_FEATURE 0x6ffffdfc /* feature holder */ #define DT_FEATURE_1 DT_FEATURE #define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ /* the following DT_* entry. */ /* See DF_P1_* definitions */ #define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ #define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ #define DT_VALRNGHI 0x6ffffdff /* * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. * * If any adjustment is made to the ELF object after it has been * built, these entries will need to be adjusted. */ #define DT_ADDRRNGLO 0x6ffffe00 #define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */ #define DT_GNU_CONFLICT 0x6ffffef8 /* address of conflict section */ #define DT_GNU_LIBLIST 0x6ffffef9 /* address of library list */ #define DT_CONFIG 0x6ffffefa /* configuration information */ #define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ #define DT_AUDIT 0x6ffffefc /* object auditing */ #define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ #define DT_MOVETAB 0x6ffffefe /* move table */ #define DT_SYMINFO 0x6ffffeff /* syminfo table */ #define DT_ADDRRNGHI 0x6ffffeff #define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ #define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ #define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ #define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ #define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ #define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ #define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ #define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ #define DT_LOPROC 0x70000000 /* First processor-specific type. */ #define DT_ARM_SYMTABSZ 0x70000001 #define DT_ARM_PREEMPTMAP 0x70000002 #define DT_SPARC_REGISTER 0x70000001 #define DT_DEPRECATED_SPARC_REGISTER 0x7000001 #define DT_MIPS_RLD_VERSION 0x70000001 #define DT_MIPS_TIME_STAMP 0x70000002 #define DT_MIPS_ICHECKSUM 0x70000003 #define DT_MIPS_IVERSION 0x70000004 #define DT_MIPS_FLAGS 0x70000005 #define DT_MIPS_BASE_ADDRESS 0x70000006 #define DT_MIPS_CONFLICT 0x70000008 #define DT_MIPS_LIBLIST 0x70000009 #define DT_MIPS_LOCAL_GOTNO 0x7000000a #define DT_MIPS_CONFLICTNO 0x7000000b #define DT_MIPS_LIBLISTNO 0x70000010 #define DT_MIPS_SYMTABNO 0x70000011 #define DT_MIPS_UNREFEXTNO 0x70000012 #define DT_MIPS_GOTSYM 0x70000013 #define DT_MIPS_HIPAGENO 0x70000014 #define DT_MIPS_RLD_MAP 0x70000016 #define DT_MIPS_DELTA_CLASS 0x70000017 #define DT_MIPS_DELTA_CLASS_NO 0x70000018 #define DT_MIPS_DELTA_INSTANCE 0x70000019 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A #define DT_MIPS_DELTA_RELOC 0x7000001B #define DT_MIPS_DELTA_RELOC_NO 0x7000001C #define DT_MIPS_DELTA_SYM 0x7000001D #define DT_MIPS_DELTA_SYM_NO 0x7000001E #define DT_MIPS_DELTA_CLASSSYM 0x70000020 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 #define DT_MIPS_CXX_FLAGS 0x70000022 #define DT_MIPS_PIXIE_INIT 0x70000023 #define DT_MIPS_SYMBOL_LIB 0x70000024 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 #define DT_MIPS_LOCAL_GOTIDX 0x70000026 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028 #define DT_MIPS_OPTIONS 0x70000029 #define DT_MIPS_INTERFACE 0x7000002A #define DT_MIPS_DYNSTR_ALIGN 0x7000002B #define DT_MIPS_INTERFACE_SIZE 0x7000002C #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D #define DT_MIPS_PERF_SUFFIX 0x7000002E #define DT_MIPS_COMPACT_SIZE 0x7000002F #define DT_MIPS_GP_VALUE 0x70000030 #define DT_MIPS_AUX_DYNAMIC 0x70000031 #define DT_MIPS_PLTGOT 0x70000032 #define DT_MIPS_RLD_OBJ_UPDATE 0x70000033 #define DT_MIPS_RWPLT 0x70000034 #define DT_PPC_GOT 0x70000000 #define DT_PPC_TLSOPT 0x70000001 #define DT_PPC64_GLINK 0x70000000 #define DT_PPC64_OPD 0x70000001 #define DT_PPC64_OPDSZ 0x70000002 #define DT_PPC64_TLSOPT 0x70000003 #define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ #define DT_USED 0x7ffffffe /* ignored - same as needed */ #define DT_FILTER 0x7fffffff /* shared library filter name */ #define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ /* Values for DT_FLAGS */ #define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may make reference to the $ORIGIN substitution string */ #define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ #define DF_TEXTREL 0x0004 /* Indicates there may be relocations in non-writable segments. */ #define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should process all relocations for the object containing this entry before transferring control to the program. */ #define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or executable contains code using a static thread-local storage scheme. */ /* Values for DT_FLAGS_1 */ #define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */ #define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */ #define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */ #define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */ #define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ #define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */ #define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */ #define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */ /* Values for l_flags. */ #define LL_NONE 0x0 /* no flags */ #define LL_EXACT_MATCH 0x1 /* require an exact match */ #define LL_IGNORE_INT_VER 0x2 /* ignore version incompatibilities */ #define LL_REQUIRE_MINOR 0x4 #define LL_EXPORTS 0x8 #define LL_DELAY_LOAD 0x10 #define LL_DELTA 0x20 /* Values for n_type used in executables. */ #define NT_FREEBSD_ABI_TAG 1 #define NT_FREEBSD_NOINIT_TAG 2 #define NT_FREEBSD_ARCH_TAG 3 /* Values for n_type. Used in core files. */ #define NT_PRSTATUS 1 /* Process status. */ #define NT_FPREGSET 2 /* Floating point registers. */ #define NT_PRPSINFO 3 /* Process state info. */ #define NT_THRMISC 7 /* Thread miscellaneous info. */ #define NT_PROCSTAT_PROC 8 /* Procstat proc data. */ #define NT_PROCSTAT_FILES 9 /* Procstat files data. */ #define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ #define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */ #define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */ #define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ #define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ #define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ #define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */ #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */ /* Symbol Binding - ELFNN_ST_BIND - st_info */ #define STB_LOCAL 0 /* Local symbol */ #define STB_GLOBAL 1 /* Global symbol */ #define STB_WEAK 2 /* like global - lower precedence */ #define STB_LOOS 10 /* Start of operating system reserved range. */ #define STB_GNU_UNIQUE 10 /* Unique symbol (GNU) */ #define STB_HIOS 12 /* End of operating system reserved range. */ #define STB_LOPROC 13 /* reserved range for processor */ #define STB_HIPROC 15 /* specific semantics. */ /* Symbol type - ELFNN_ST_TYPE - st_info */ #define STT_NOTYPE 0 /* Unspecified type. */ #define STT_OBJECT 1 /* Data object. */ #define STT_FUNC 2 /* Function. */ #define STT_SECTION 3 /* Section. */ #define STT_FILE 4 /* Source file. */ #define STT_COMMON 5 /* Uninitialized common block. */ #define STT_TLS 6 /* TLS object. */ #define STT_NUM 7 #define STT_LOOS 10 /* Reserved range for operating system */ #define STT_GNU_IFUNC 10 #define STT_HIOS 12 /* specific semantics. */ #define STT_LOPROC 13 /* Start of processor reserved range. */ #define STT_SPARC_REGISTER 13 /* SPARC register information. */ #define STT_HIPROC 15 /* End of processor reserved range. */ /* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ #define STV_DEFAULT 0x0 /* Default visibility (see binding). */ #define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ #define STV_HIDDEN 0x2 /* Not visible. */ #define STV_PROTECTED 0x3 /* Visible but not preemptible. */ #define STV_EXPORTED 0x4 #define STV_SINGLETON 0x5 #define STV_ELIMINATE 0x6 /* Special symbol table indexes. */ #define STN_UNDEF 0 /* Undefined symbol index. */ /* Symbol versioning flags. */ #define VER_DEF_CURRENT 1 #define VER_DEF_IDX(x) VER_NDX(x) #define VER_FLG_BASE 0x01 #define VER_FLG_WEAK 0x02 #define VER_NEED_CURRENT 1 #define VER_NEED_WEAK (1u << 15) #define VER_NEED_HIDDEN VER_NDX_HIDDEN #define VER_NEED_IDX(x) VER_NDX(x) #define VER_NDX_LOCAL 0 #define VER_NDX_GLOBAL 1 #define VER_NDX_GIVEN 2 #define VER_NDX_HIDDEN (1u << 15) #define VER_NDX(x) ((x) & ~(1u << 15)) #define CA_SUNW_NULL 0 #define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ #define CA_SUNW_SF_1 2 /* first software capabilities entry */ /* * Syminfo flag values */ #define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ /* to object containing defn. */ #define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ #define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ #define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ /* lazily-loaded */ #define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ /* object containing defn. */ #define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ /* directly bind to this symbol */ #define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ #define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ /* * Syminfo.si_boundto values. */ #define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ #define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ #define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ #define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ #define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ /* * Syminfo version values. */ #define SYMINFO_NONE 0 /* Syminfo version */ #define SYMINFO_CURRENT 1 #define SYMINFO_NUM 2 /* * Relocation types. * * All machine architectures are defined here to allow tools on one to * handle others. */ #define R_386_NONE 0 /* No relocation. */ #define R_386_32 1 /* Add symbol value. */ #define R_386_PC32 2 /* Add PC-relative symbol value. */ #define R_386_GOT32 3 /* Add PC-relative GOT offset. */ #define R_386_PLT32 4 /* Add PC-relative PLT offset. */ #define R_386_COPY 5 /* Copy data from shared object. */ #define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ #define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ #define R_386_RELATIVE 8 /* Add load address of shared object. */ #define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ #define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ #define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ #define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ #define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ #define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ #define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ #define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ #define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ #define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ #define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ #define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ #define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ #define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ #define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ #define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ #define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ #define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ #define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ #define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ #define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ #define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ #define R_AARCH64_NONE 0 /* No relocation */ #define R_AARCH64_ABS64 257 /* Absolute offset */ #define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */ #define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */ #define R_AARCH64_PREL64 260 /* PC relative */ #define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */ #define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */ #define R_AARCH64_COPY 1024 /* Copy data from shared object */ #define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */ #define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */ #define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */ #define R_AARCH64_TLS_DTPREL64 1028 #define R_AARCH64_TLS_DTPMOD64 1029 #define R_AARCH64_TLS_TPREL64 1030 #define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */ #define R_AARCH64_IRELATIVE 1032 #define R_ARM_NONE 0 /* No relocation. */ #define R_ARM_PC24 1 #define R_ARM_ABS32 2 #define R_ARM_REL32 3 #define R_ARM_PC13 4 #define R_ARM_ABS16 5 #define R_ARM_ABS12 6 #define R_ARM_THM_ABS5 7 #define R_ARM_ABS8 8 #define R_ARM_SBREL32 9 #define R_ARM_THM_PC22 10 #define R_ARM_THM_PC8 11 #define R_ARM_AMP_VCALL9 12 #define R_ARM_SWI24 13 #define R_ARM_THM_SWI8 14 #define R_ARM_XPC25 15 #define R_ARM_THM_XPC22 16 /* TLS relocations */ #define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ #define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ #define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ #define R_ARM_COPY 20 /* Copy data from shared object. */ #define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ #define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ #define R_ARM_RELATIVE 23 /* Add load address of shared object. */ #define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ #define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ #define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ #define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 #define R_ARM_RREL32 252 #define R_ARM_RABS32 253 #define R_ARM_RPC24 254 #define R_ARM_RBASE 255 /* Name Value Field Calculation */ #define R_IA_64_NONE 0 /* None */ #define R_IA_64_IMM14 0x21 /* immediate14 S + A */ #define R_IA_64_IMM22 0x22 /* immediate22 S + A */ #define R_IA_64_IMM64 0x23 /* immediate64 S + A */ #define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ #define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ #define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ #define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ #define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ #define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ #define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ #define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ #define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ #define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ #define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ #define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ #define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ #define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ #define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ #define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ #define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ #define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ #define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ #define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ #define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ #define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ #define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ #define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ #define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ #define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ #define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ #define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ #define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ #define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ #define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ #define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ #define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ #define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ #define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ #define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ #define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ #define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ #define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ #define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ #define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ #define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ #define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ #define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ #define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ #define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ #define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ #define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ #define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ #define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ #define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ #define R_IA_64_SUB 0x85 /* immediate64 A - S */ #define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ #define R_IA_64_LDXMOV 0x87 /* immediate22 special */ #define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ #define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ #define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ #define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ #define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ #define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ #define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ #define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ #define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ #define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ #define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ #define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ #define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ #define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ #define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ #define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ #define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ #define R_MIPS_NONE 0 /* No reloc */ #define R_MIPS_16 1 /* Direct 16 bit */ #define R_MIPS_32 2 /* Direct 32 bit */ #define R_MIPS_REL32 3 /* PC relative 32 bit */ #define R_MIPS_26 4 /* Direct 26 bit shifted */ #define R_MIPS_HI16 5 /* High 16 bit */ #define R_MIPS_LO16 6 /* Low 16 bit */ #define R_MIPS_GPREL16 7 /* GP relative 16 bit */ #define R_MIPS_LITERAL 8 /* 16 bit literal entry */ #define R_MIPS_GOT16 9 /* 16 bit GOT entry */ #define R_MIPS_PC16 10 /* PC relative 16 bit */ #define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ #define R_MIPS_GPREL32 12 /* GP relative 32 bit */ #define R_MIPS_64 18 /* Direct 64 bit */ #define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */ #define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */ #define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */ #define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */ #define R_PPC_NONE 0 /* No relocation. */ #define R_PPC_ADDR32 1 #define R_PPC_ADDR24 2 #define R_PPC_ADDR16 3 #define R_PPC_ADDR16_LO 4 #define R_PPC_ADDR16_HI 5 #define R_PPC_ADDR16_HA 6 #define R_PPC_ADDR14 7 #define R_PPC_ADDR14_BRTAKEN 8 #define R_PPC_ADDR14_BRNTAKEN 9 #define R_PPC_REL24 10 #define R_PPC_REL14 11 #define R_PPC_REL14_BRTAKEN 12 #define R_PPC_REL14_BRNTAKEN 13 #define R_PPC_GOT16 14 #define R_PPC_GOT16_LO 15 #define R_PPC_GOT16_HI 16 #define R_PPC_GOT16_HA 17 #define R_PPC_PLTREL24 18 #define R_PPC_COPY 19 #define R_PPC_GLOB_DAT 20 #define R_PPC_JMP_SLOT 21 #define R_PPC_RELATIVE 22 #define R_PPC_LOCAL24PC 23 #define R_PPC_UADDR32 24 #define R_PPC_UADDR16 25 #define R_PPC_REL32 26 #define R_PPC_PLT32 27 #define R_PPC_PLTREL32 28 #define R_PPC_PLT16_LO 29 #define R_PPC_PLT16_HI 30 #define R_PPC_PLT16_HA 31 #define R_PPC_SDAREL16 32 #define R_PPC_SECTOFF 33 #define R_PPC_SECTOFF_LO 34 #define R_PPC_SECTOFF_HI 35 #define R_PPC_SECTOFF_HA 36 /* * 64-bit relocations */ #define R_PPC64_ADDR64 38 #define R_PPC64_ADDR16_HIGHER 39 #define R_PPC64_ADDR16_HIGHERA 40 #define R_PPC64_ADDR16_HIGHEST 41 #define R_PPC64_ADDR16_HIGHESTA 42 #define R_PPC64_UADDR64 43 #define R_PPC64_REL64 44 #define R_PPC64_PLT64 45 #define R_PPC64_PLTREL64 46 #define R_PPC64_TOC16 47 #define R_PPC64_TOC16_LO 48 #define R_PPC64_TOC16_HI 49 #define R_PPC64_TOC16_HA 50 #define R_PPC64_TOC 51 #define R_PPC64_DTPMOD64 68 #define R_PPC64_TPREL64 73 #define R_PPC64_DTPREL64 78 /* * TLS relocations */ #define R_PPC_TLS 67 #define R_PPC_DTPMOD32 68 #define R_PPC_TPREL16 69 #define R_PPC_TPREL16_LO 70 #define R_PPC_TPREL16_HI 71 #define R_PPC_TPREL16_HA 72 #define R_PPC_TPREL32 73 #define R_PPC_DTPREL16 74 #define R_PPC_DTPREL16_LO 75 #define R_PPC_DTPREL16_HI 76 #define R_PPC_DTPREL16_HA 77 #define R_PPC_DTPREL32 78 #define R_PPC_GOT_TLSGD16 79 #define R_PPC_GOT_TLSGD16_LO 80 #define R_PPC_GOT_TLSGD16_HI 81 #define R_PPC_GOT_TLSGD16_HA 82 #define R_PPC_GOT_TLSLD16 83 #define R_PPC_GOT_TLSLD16_LO 84 #define R_PPC_GOT_TLSLD16_HI 85 #define R_PPC_GOT_TLSLD16_HA 86 #define R_PPC_GOT_TPREL16 87 #define R_PPC_GOT_TPREL16_LO 88 #define R_PPC_GOT_TPREL16_HI 89 #define R_PPC_GOT_TPREL16_HA 90 /* * The remaining relocs are from the Embedded ELF ABI, and are not in the * SVR4 ELF ABI. */ #define R_PPC_EMB_NADDR32 101 #define R_PPC_EMB_NADDR16 102 #define R_PPC_EMB_NADDR16_LO 103 #define R_PPC_EMB_NADDR16_HI 104 #define R_PPC_EMB_NADDR16_HA 105 #define R_PPC_EMB_SDAI16 106 #define R_PPC_EMB_SDA2I16 107 #define R_PPC_EMB_SDA2REL 108 #define R_PPC_EMB_SDA21 109 #define R_PPC_EMB_MRKREF 110 #define R_PPC_EMB_RELSEC16 111 #define R_PPC_EMB_RELST_LO 112 #define R_PPC_EMB_RELST_HI 113 #define R_PPC_EMB_RELST_HA 114 #define R_PPC_EMB_BIT_FLD 115 #define R_PPC_EMB_RELSDA 116 /* * RISC-V relocation types. */ /* Relocation types used by the dynamic linker. */ #define R_RISCV_NONE 0 #define R_RISCV_32 1 #define R_RISCV_64 2 #define R_RISCV_RELATIVE 3 #define R_RISCV_COPY 4 #define R_RISCV_JUMP_SLOT 5 #define R_RISCV_TLS_DTPMOD32 6 #define R_RISCV_TLS_DTPMOD64 7 #define R_RISCV_TLS_DTPREL32 8 #define R_RISCV_TLS_DTPREL64 9 #define R_RISCV_TLS_TPREL32 10 #define R_RISCV_TLS_TPREL64 11 /* Relocation types not used by the dynamic linker. */ #define R_RISCV_BRANCH 16 #define R_RISCV_JAL 17 #define R_RISCV_CALL 18 #define R_RISCV_CALL_PLT 19 #define R_RISCV_GOT_HI20 20 #define R_RISCV_TLS_GOT_HI20 21 #define R_RISCV_TLS_GD_HI20 22 #define R_RISCV_PCREL_HI20 23 #define R_RISCV_PCREL_LO12_I 24 #define R_RISCV_PCREL_LO12_S 25 #define R_RISCV_HI20 26 #define R_RISCV_LO12_I 27 #define R_RISCV_LO12_S 28 #define R_RISCV_TPREL_HI20 29 #define R_RISCV_TPREL_LO12_I 30 #define R_RISCV_TPREL_LO12_S 31 #define R_RISCV_TPREL_ADD 32 #define R_RISCV_ADD8 33 #define R_RISCV_ADD16 34 #define R_RISCV_ADD32 35 #define R_RISCV_ADD64 36 #define R_RISCV_SUB8 37 #define R_RISCV_SUB16 38 #define R_RISCV_SUB32 39 #define R_RISCV_SUB64 40 #define R_RISCV_GNU_VTINHERIT 41 #define R_RISCV_GNU_VTENTRY 42 #define R_RISCV_ALIGN 43 #define R_RISCV_RVC_BRANCH 44 #define R_RISCV_RVC_JUMP 45 #define R_SPARC_NONE 0 #define R_SPARC_8 1 #define R_SPARC_16 2 #define R_SPARC_32 3 #define R_SPARC_DISP8 4 #define R_SPARC_DISP16 5 #define R_SPARC_DISP32 6 #define R_SPARC_WDISP30 7 #define R_SPARC_WDISP22 8 #define R_SPARC_HI22 9 #define R_SPARC_22 10 #define R_SPARC_13 11 #define R_SPARC_LO10 12 #define R_SPARC_GOT10 13 #define R_SPARC_GOT13 14 #define R_SPARC_GOT22 15 #define R_SPARC_PC10 16 #define R_SPARC_PC22 17 #define R_SPARC_WPLT30 18 #define R_SPARC_COPY 19 #define R_SPARC_GLOB_DAT 20 #define R_SPARC_JMP_SLOT 21 #define R_SPARC_RELATIVE 22 #define R_SPARC_UA32 23 #define R_SPARC_PLT32 24 #define R_SPARC_HIPLT22 25 #define R_SPARC_LOPLT10 26 #define R_SPARC_PCPLT32 27 #define R_SPARC_PCPLT22 28 #define R_SPARC_PCPLT10 29 #define R_SPARC_10 30 #define R_SPARC_11 31 #define R_SPARC_64 32 #define R_SPARC_OLO10 33 #define R_SPARC_HH22 34 #define R_SPARC_HM10 35 #define R_SPARC_LM22 36 #define R_SPARC_PC_HH22 37 #define R_SPARC_PC_HM10 38 #define R_SPARC_PC_LM22 39 #define R_SPARC_WDISP16 40 #define R_SPARC_WDISP19 41 #define R_SPARC_GLOB_JMP 42 #define R_SPARC_7 43 #define R_SPARC_5 44 #define R_SPARC_6 45 #define R_SPARC_DISP64 46 #define R_SPARC_PLT64 47 #define R_SPARC_HIX22 48 #define R_SPARC_LOX10 49 #define R_SPARC_H44 50 #define R_SPARC_M44 51 #define R_SPARC_L44 52 #define R_SPARC_REGISTER 53 #define R_SPARC_UA64 54 #define R_SPARC_UA16 55 #define R_SPARC_TLS_GD_HI22 56 #define R_SPARC_TLS_GD_LO10 57 #define R_SPARC_TLS_GD_ADD 58 #define R_SPARC_TLS_GD_CALL 59 #define R_SPARC_TLS_LDM_HI22 60 #define R_SPARC_TLS_LDM_LO10 61 #define R_SPARC_TLS_LDM_ADD 62 #define R_SPARC_TLS_LDM_CALL 63 #define R_SPARC_TLS_LDO_HIX22 64 #define R_SPARC_TLS_LDO_LOX10 65 #define R_SPARC_TLS_LDO_ADD 66 #define R_SPARC_TLS_IE_HI22 67 #define R_SPARC_TLS_IE_LO10 68 #define R_SPARC_TLS_IE_LD 69 #define R_SPARC_TLS_IE_LDX 70 #define R_SPARC_TLS_IE_ADD 71 #define R_SPARC_TLS_LE_HIX22 72 #define R_SPARC_TLS_LE_LOX10 73 #define R_SPARC_TLS_DTPMOD32 74 #define R_SPARC_TLS_DTPMOD64 75 #define R_SPARC_TLS_DTPOFF32 76 #define R_SPARC_TLS_DTPOFF64 77 #define R_SPARC_TLS_TPOFF32 78 #define R_SPARC_TLS_TPOFF64 79 #define R_X86_64_NONE 0 /* No relocation. */ #define R_X86_64_64 1 /* Add 64 bit symbol value. */ #define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ #define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ #define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ #define R_X86_64_COPY 5 /* Copy data from shared object. */ #define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ #define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ #define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ #define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ #define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ #define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ #define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ #define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ #define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ #define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ #define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ #define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ #define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ #define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ #define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ #define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ #define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ #define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ #define R_X86_64_PC64 24 /* PC-relative 64 bit signed sym value. */ #define R_X86_64_GOTOFF64 25 #define R_X86_64_GOTPC32 26 #define R_X86_64_GOT64 27 #define R_X86_64_GOTPCREL64 28 #define R_X86_64_GOTPC64 29 #define R_X86_64_GOTPLT64 30 #define R_X86_64_PLTOFF64 31 #define R_X86_64_SIZE32 32 #define R_X86_64_SIZE64 33 #define R_X86_64_GOTPC32_TLSDESC 34 #define R_X86_64_TLSDESC_CALL 35 #define R_X86_64_TLSDESC 36 #define R_X86_64_IRELATIVE 37 #endif /* !_SYS_ELF_COMMON_H_ */ /*- * Copyright (c) 1998 John D. Polstra. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_ELF_GENERIC_H_ #define _SYS_ELF_GENERIC_H_ 1 #include /* * Definitions of generic ELF names which relieve applications from * needing to know the word size. */ #if __ELF_WORD_SIZE != 32 && __ELF_WORD_SIZE != 64 #error "__ELF_WORD_SIZE must be defined as 32 or 64" #endif #define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE) #if BYTE_ORDER == LITTLE_ENDIAN #define ELF_DATA ELFDATA2LSB #elif BYTE_ORDER == BIG_ENDIAN #define ELF_DATA ELFDATA2MSB #else #error "Unknown byte order" #endif #define __elfN(x) __CONCAT(__CONCAT(__CONCAT(elf,__ELF_WORD_SIZE),_),x) #define __ElfN(x) __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x) #define __ELFN(x) __CONCAT(__CONCAT(__CONCAT(ELF,__ELF_WORD_SIZE),_),x) #define __ElfType(x) typedef __ElfN(x) __CONCAT(Elf_,x) __ElfType(Addr); __ElfType(Half); __ElfType(Off); __ElfType(Sword); __ElfType(Word); __ElfType(Ehdr); __ElfType(Shdr); __ElfType(Phdr); __ElfType(Dyn); __ElfType(Rel); __ElfType(Rela); __ElfType(Sym); __ElfType(Verdef); __ElfType(Verdaux); __ElfType(Verneed); __ElfType(Vernaux); __ElfType(Versym); /* Non-standard ELF types. */ __ElfType(Hashelt); __ElfType(Size); __ElfType(Ssize); #define ELF_R_SYM __ELFN(R_SYM) #define ELF_R_TYPE __ELFN(R_TYPE) #define ELF_R_INFO __ELFN(R_INFO) #define ELF_ST_BIND __ELFN(ST_BIND) #define ELF_ST_TYPE __ELFN(ST_TYPE) #define ELF_ST_INFO __ELFN(ST_INFO) #endif /* !_SYS_ELF_GENERIC_H_ */ /*- * Copyright (c) 2002 Thomas Moestl * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_ENDIAN_H_ #define _SYS_ENDIAN_H_ #include #include #include #ifndef _UINT8_T_DECLARED typedef __uint8_t uint8_t; #define _UINT8_T_DECLARED #endif #ifndef _UINT16_T_DECLARED typedef __uint16_t uint16_t; #define _UINT16_T_DECLARED #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _UINT64_T_DECLARED typedef __uint64_t uint64_t; #define _UINT64_T_DECLARED #endif /* * General byte order swapping functions. */ #define bswap16(x) __bswap16(x) #define bswap32(x) __bswap32(x) #define bswap64(x) __bswap64(x) /* * Host to big endian, host to little endian, big endian to host, and little * endian to host byte order functions as detailed in byteorder(9). */ #if _BYTE_ORDER == _LITTLE_ENDIAN #define htobe16(x) bswap16((x)) #define htobe32(x) bswap32((x)) #define htobe64(x) bswap64((x)) #define htole16(x) ((uint16_t)(x)) #define htole32(x) ((uint32_t)(x)) #define htole64(x) ((uint64_t)(x)) #define be16toh(x) bswap16((x)) #define be32toh(x) bswap32((x)) #define be64toh(x) bswap64((x)) #define le16toh(x) ((uint16_t)(x)) #define le32toh(x) ((uint32_t)(x)) #define le64toh(x) ((uint64_t)(x)) #else /* _BYTE_ORDER != _LITTLE_ENDIAN */ #define htobe16(x) ((uint16_t)(x)) #define htobe32(x) ((uint32_t)(x)) #define htobe64(x) ((uint64_t)(x)) #define htole16(x) bswap16((x)) #define htole32(x) bswap32((x)) #define htole64(x) bswap64((x)) #define be16toh(x) ((uint16_t)(x)) #define be32toh(x) ((uint32_t)(x)) #define be64toh(x) ((uint64_t)(x)) #define le16toh(x) bswap16((x)) #define le32toh(x) bswap32((x)) #define le64toh(x) bswap64((x)) #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ static __inline uint16_t be16dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return ((p[0] << 8) | p[1]); } static __inline uint32_t be32dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); } static __inline uint64_t be64dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); } static __inline uint16_t le16dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return ((p[1] << 8) | p[0]); } static __inline uint32_t le32dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); } static __inline uint64_t le64dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); } static __inline void be16enc(void *pp, uint16_t u) { uint8_t *p = (uint8_t *)pp; p[0] = (u >> 8) & 0xff; p[1] = u & 0xff; } static __inline void be32enc(void *pp, uint32_t u) { uint8_t *p = (uint8_t *)pp; p[0] = (u >> 24) & 0xff; p[1] = (u >> 16) & 0xff; p[2] = (u >> 8) & 0xff; p[3] = u & 0xff; } static __inline void be64enc(void *pp, uint64_t u) { uint8_t *p = (uint8_t *)pp; be32enc(p, (uint32_t)(u >> 32)); be32enc(p + 4, (uint32_t)(u & 0xffffffffU)); } static __inline void le16enc(void *pp, uint16_t u) { uint8_t *p = (uint8_t *)pp; p[0] = u & 0xff; p[1] = (u >> 8) & 0xff; } static __inline void le32enc(void *pp, uint32_t u) { uint8_t *p = (uint8_t *)pp; p[0] = u & 0xff; p[1] = (u >> 8) & 0xff; p[2] = (u >> 16) & 0xff; p[3] = (u >> 24) & 0xff; } static __inline void le64enc(void *pp, uint64_t u) { uint8_t *p = (uint8_t *)pp; le32enc(p, (uint32_t)(u & 0xffffffffU)); le32enc(p + 4, (uint32_t)(u >> 32)); } #endif /* _SYS_ENDIAN_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)errno.h 8.5 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _SYS_ERRNO_H_ #define _SYS_ERRNO_H_ #if !defined(_KERNEL) && !defined(_STANDALONE) #include __BEGIN_DECLS int * __error(void); __END_DECLS #define errno (* __error()) #endif #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* Input/output error */ #define ENXIO 6 /* Device not configured */ #define E2BIG 7 /* Argument list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file descriptor */ #define ECHILD 10 /* No child processes */ #define EDEADLK 11 /* Resource deadlock avoided */ /* 11 was EAGAIN */ #define ENOMEM 12 /* Cannot allocate memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #ifndef _POSIX_SOURCE #define ENOTBLK 15 /* Block device required */ #endif #define EBUSY 16 /* Device busy */ #define EEXIST 17 /* File exists */ #define EXDEV 18 /* Cross-device link */ #define ENODEV 19 /* Operation not supported by device */ #define ENOTDIR 20 /* Not a directory */ #define EISDIR 21 /* Is a directory */ #define EINVAL 22 /* Invalid argument */ #define ENFILE 23 /* Too many open files in system */ #define EMFILE 24 /* Too many open files */ #define ENOTTY 25 /* Inappropriate ioctl for device */ #ifndef _POSIX_SOURCE #define ETXTBSY 26 /* Text file busy */ #endif #define EFBIG 27 /* File too large */ #define ENOSPC 28 /* No space left on device */ #define ESPIPE 29 /* Illegal seek */ #define EROFS 30 /* Read-only filesystem */ #define EMLINK 31 /* Too many links */ #define EPIPE 32 /* Broken pipe */ /* math software */ #define EDOM 33 /* Numerical argument out of domain */ #define ERANGE 34 /* Result too large */ /* non-blocking and interrupt i/o */ #define EAGAIN 35 /* Resource temporarily unavailable */ #ifndef _POSIX_SOURCE #define EWOULDBLOCK EAGAIN /* Operation would block */ #define EINPROGRESS 36 /* Operation now in progress */ #define EALREADY 37 /* Operation already in progress */ /* ipc/network software -- argument errors */ #define ENOTSOCK 38 /* Socket operation on non-socket */ #define EDESTADDRREQ 39 /* Destination address required */ #define EMSGSIZE 40 /* Message too long */ #define EPROTOTYPE 41 /* Protocol wrong type for socket */ #define ENOPROTOOPT 42 /* Protocol not available */ #define EPROTONOSUPPORT 43 /* Protocol not supported */ #define ESOCKTNOSUPPORT 44 /* Socket type not supported */ #define EOPNOTSUPP 45 /* Operation not supported */ #define ENOTSUP EOPNOTSUPP /* Operation not supported */ #define EPFNOSUPPORT 46 /* Protocol family not supported */ #define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ #define EADDRINUSE 48 /* Address already in use */ #define EADDRNOTAVAIL 49 /* Can't assign requested address */ /* ipc/network software -- operational errors */ #define ENETDOWN 50 /* Network is down */ #define ENETUNREACH 51 /* Network is unreachable */ #define ENETRESET 52 /* Network dropped connection on reset */ #define ECONNABORTED 53 /* Software caused connection abort */ #define ECONNRESET 54 /* Connection reset by peer */ #define ENOBUFS 55 /* No buffer space available */ #define EISCONN 56 /* Socket is already connected */ #define ENOTCONN 57 /* Socket is not connected */ #define ESHUTDOWN 58 /* Can't send after socket shutdown */ #define ETOOMANYREFS 59 /* Too many references: can't splice */ #define ETIMEDOUT 60 /* Operation timed out */ #define ECONNREFUSED 61 /* Connection refused */ #define ELOOP 62 /* Too many levels of symbolic links */ #endif /* _POSIX_SOURCE */ #define ENAMETOOLONG 63 /* File name too long */ /* should be rearranged */ #ifndef _POSIX_SOURCE #define EHOSTDOWN 64 /* Host is down */ #define EHOSTUNREACH 65 /* No route to host */ #endif /* _POSIX_SOURCE */ #define ENOTEMPTY 66 /* Directory not empty */ /* quotas & mush */ #ifndef _POSIX_SOURCE #define EPROCLIM 67 /* Too many processes */ #define EUSERS 68 /* Too many users */ #define EDQUOT 69 /* Disc quota exceeded */ /* Network File System */ #define ESTALE 70 /* Stale NFS file handle */ #define EREMOTE 71 /* Too many levels of remote in path */ #define EBADRPC 72 /* RPC struct is bad */ #define ERPCMISMATCH 73 /* RPC version wrong */ #define EPROGUNAVAIL 74 /* RPC prog. not avail */ #define EPROGMISMATCH 75 /* Program version wrong */ #define EPROCUNAVAIL 76 /* Bad procedure for program */ #endif /* _POSIX_SOURCE */ #define ENOLCK 77 /* No locks available */ #define ENOSYS 78 /* Function not implemented */ #ifndef _POSIX_SOURCE #define EFTYPE 79 /* Inappropriate file type or format */ #define EAUTH 80 /* Authentication error */ #define ENEEDAUTH 81 /* Need authenticator */ #define EIDRM 82 /* Identifier removed */ #define ENOMSG 83 /* No message of desired type */ #define EOVERFLOW 84 /* Value too large to be stored in data type */ #define ECANCELED 85 /* Operation canceled */ #define EILSEQ 86 /* Illegal byte sequence */ #define ENOATTR 87 /* Attribute not found */ #define EDOOFUS 88 /* Programming error */ #endif /* _POSIX_SOURCE */ #define EBADMSG 89 /* Bad message */ #define EMULTIHOP 90 /* Multihop attempted */ #define ENOLINK 91 /* Link has been severed */ #define EPROTO 92 /* Protocol error */ #ifndef _POSIX_SOURCE #define ENOTCAPABLE 93 /* Capabilities insufficient */ #define ECAPMODE 94 /* Not permitted in capability mode */ #define ENOTRECOVERABLE 95 /* State not recoverable */ #define EOWNERDEAD 96 /* Previous owner died */ #endif /* _POSIX_SOURCE */ #ifndef _POSIX_SOURCE #define ELAST 96 /* Must be equal largest errno */ #endif /* _POSIX_SOURCE */ #ifdef _KERNEL /* pseudo-errors returned inside kernel to modify return to process */ #define ERESTART (-1) /* restart syscall */ #define EJUSTRETURN (-2) /* don't modify regs, just return */ #define ENOIOCTL (-3) /* ioctl not handled by this layer */ #define EDIRIOCTL (-4) /* do direct ioctl in GEOM */ #endif #endif /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)exec.h 8.3 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _SYS_EXEC_H_ #define _SYS_EXEC_H_ /* * Before ps_args existed, the following structure, found at the top of * the user stack of each user process, was used by ps(1) to locate * environment and argv strings. Normally ps_argvstr points to the * argv vector, and ps_nargvstr is the same as the program's argc. The * fields ps_envstr and ps_nenvstr are the equivalent for the environment. * * Programs should now use setproctitle(3) to change ps output. * setproctitle() always informs the kernel with sysctl and sets the * pointers in ps_strings. The kern.proc.args sysctl first tries p_args. * If p_args is NULL, it then falls back to reading ps_strings and following * the pointers. */ struct ps_strings { char **ps_argvstr; /* first of 0 or more argument strings */ unsigned int ps_nargvstr; /* the number of argument strings */ char **ps_envstr; /* first of 0 or more environment strings */ unsigned int ps_nenvstr; /* the number of environment strings */ }; /* * Address of ps_strings structure (in user space). * Prefer the kern.ps_strings or kern.proc.ps_strings sysctls to this constant. */ #define PS_STRINGS (USRSTACK - sizeof(struct ps_strings)) #define SPARE_USRSPACE 4096 struct image_params; struct execsw { int (*ex_imgact)(struct image_params *); const char *ex_name; }; #include #ifdef _KERNEL #include int exec_map_first_page(struct image_params *); void exec_unmap_first_page(struct image_params *); int exec_register(const struct execsw *); int exec_unregister(const struct execsw *); extern int coredump_pack_fileinfo; extern int coredump_pack_vmmapinfo; /* * note: name##_mod cannot be const storage because the * linker_file_sysinit() function modifies _file in the * moduledata_t. */ #include #define EXEC_SET(name, execsw_arg) \ static int __CONCAT(name,_modevent)(module_t mod, int type, \ void *data) \ { \ struct execsw *exec = (struct execsw *)data; \ int error = 0; \ switch (type) { \ case MOD_LOAD: \ /* printf(#name " module loaded\n"); */ \ error = exec_register(exec); \ if (error) \ printf(__XSTRING(name) "register failed\n"); \ break; \ case MOD_UNLOAD: \ /* printf(#name " module unloaded\n"); */ \ error = exec_unregister(exec); \ if (error) \ printf(__XSTRING(name) " unregister failed\n");\ break; \ default: \ error = EOPNOTSUPP; \ break; \ } \ return error; \ } \ static moduledata_t __CONCAT(name,_mod) = { \ __XSTRING(name), \ __CONCAT(name,_modevent), \ (void *)& execsw_arg \ }; \ DECLARE_MODULE_TIED(name, __CONCAT(name,_mod), SI_SUB_EXEC, \ SI_ORDER_ANY) #endif #endif /*- * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)fcntl.h 8.3 (Berkeley) 1/21/94 * $FreeBSD$ */ #ifndef _SYS_FCNTL_H_ #define _SYS_FCNTL_H_ /* * This file includes the definitions for open and fcntl * described by POSIX for ; it also includes * related kernel definitions. */ #include #include #ifndef _MODE_T_DECLARED typedef __mode_t mode_t; #define _MODE_T_DECLARED #endif #ifndef _OFF_T_DECLARED typedef __off_t off_t; #define _OFF_T_DECLARED #endif #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif /* * File status flags: these are used by open(2), fcntl(2). * They are also used (indirectly) in the kernel file structure f_flags, * which is a superset of the open/fcntl flags. Open flags and f_flags * are inter-convertible using OFLAGS(fflags) and FFLAGS(oflags). * Open/fcntl flags begin with O_; kernel-internal flags begin with F. */ /* open-only flags */ #define O_RDONLY 0x0000 /* open for reading only */ #define O_WRONLY 0x0001 /* open for writing only */ #define O_RDWR 0x0002 /* open for reading and writing */ #define O_ACCMODE 0x0003 /* mask for above modes */ /* * Kernel encoding of open mode; separate read and write bits that are * independently testable: 1 greater than the above. * * XXX * FREAD and FWRITE are excluded from the #ifdef _KERNEL so that TIOCFLUSH, * which was documented to use FREAD/FWRITE, continues to work. */ #if __BSD_VISIBLE #define FREAD 0x0001 #define FWRITE 0x0002 #endif #define O_NONBLOCK 0x0004 /* no delay */ #define O_APPEND 0x0008 /* set append mode */ #if __BSD_VISIBLE #define O_SHLOCK 0x0010 /* open with shared file lock */ #define O_EXLOCK 0x0020 /* open with exclusive file lock */ #define O_ASYNC 0x0040 /* signal pgrp when data ready */ #define O_FSYNC 0x0080 /* synchronous writes */ #endif #define O_SYNC 0x0080 /* POSIX synonym for O_FSYNC */ #if __POSIX_VISIBLE >= 200809 #define O_NOFOLLOW 0x0100 /* don't follow symlinks */ #endif #define O_CREAT 0x0200 /* create if nonexistent */ #define O_TRUNC 0x0400 /* truncate to zero length */ #define O_EXCL 0x0800 /* error if already exists */ #ifdef _KERNEL #define FHASLOCK 0x4000 /* descriptor holds advisory lock */ #endif /* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */ #define O_NOCTTY 0x8000 /* don't assign controlling terminal */ #if __BSD_VISIBLE /* Attempt to bypass buffer cache */ #define O_DIRECT 0x00010000 #endif #if __POSIX_VISIBLE >= 200809 #define O_DIRECTORY 0x00020000 /* Fail if not directory */ #define O_EXEC 0x00040000 /* Open for execute only */ #endif #ifdef _KERNEL #define FEXEC O_EXEC #endif #if __POSIX_VISIBLE >= 200809 /* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. */ #define O_TTY_INIT 0x00080000 /* Restore default termios attributes */ #define O_CLOEXEC 0x00100000 #endif #if __BSD_VISIBLE #define O_VERIFY 0x00200000 /* open only after verification */ #endif /* * XXX missing O_DSYNC, O_RSYNC. */ #ifdef _KERNEL /* Only for devfs d_close() flags. */ #define FLASTCLOSE O_DIRECTORY #define FREVOKE O_VERIFY /* Only for fo_close() from half-succeeded open */ #define FOPENFAILED O_TTY_INIT /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */ #define FFLAGS(oflags) ((oflags) & O_EXEC ? (oflags) : (oflags) + 1) #define OFLAGS(fflags) ((fflags) & O_EXEC ? (fflags) : (fflags) - 1) /* bits to save after open */ #define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|O_DIRECT|FEXEC) /* bits settable by fcntl(F_SETFL, ...) */ #define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FRDAHEAD|O_DIRECT) #if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \ defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) /* * Set by shm_open(3) in older libc's to get automatic MAP_ASYNC * behavior for POSIX shared memory objects (which are otherwise * implemented as plain files). */ #define FPOSIXSHM O_NOFOLLOW #undef FCNTLFLAGS #define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|FRDAHEAD| \ O_DIRECT) #endif #endif /* * The O_* flags used to have only F* names, which were used in the kernel * and by fcntl. We retain the F* names for the kernel f_flag field * and for backward compatibility for fcntl. These flags are deprecated. */ #if __BSD_VISIBLE #define FAPPEND O_APPEND /* kernel/compat */ #define FASYNC O_ASYNC /* kernel/compat */ #define FFSYNC O_FSYNC /* kernel */ #define FNONBLOCK O_NONBLOCK /* kernel */ #define FNDELAY O_NONBLOCK /* compat */ #define O_NDELAY O_NONBLOCK /* compat */ #endif /* * We are out of bits in f_flag (which is a short). However, * the flag bits not set in FMASK are only meaningful in the * initial open syscall. Those bits can thus be given a * different meaning for fcntl(2). */ #if __BSD_VISIBLE /* Read ahead */ #define FRDAHEAD O_CREAT #endif #if __POSIX_VISIBLE >= 200809 /* * Magic value that specify the use of the current working directory * to determine the target of relative file paths in the openat() and * similar syscalls. */ #define AT_FDCWD -100 /* * Miscellaneous flags for the *at() syscalls. */ #define AT_EACCESS 0x100 /* Check access using effective user and group ID */ #define AT_SYMLINK_NOFOLLOW 0x200 /* Do not follow symbolic links */ #define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic link */ #define AT_REMOVEDIR 0x800 /* Remove directory instead of file */ #endif /* * Constants used for fcntl(2) */ /* command values */ #define F_DUPFD 0 /* duplicate file descriptor */ #define F_GETFD 1 /* get file descriptor flags */ #define F_SETFD 2 /* set file descriptor flags */ #define F_GETFL 3 /* get file status flags */ #define F_SETFL 4 /* set file status flags */ #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112 #define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */ #define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */ #endif #if __BSD_VISIBLE #define F_OGETLK 7 /* get record locking information */ #define F_OSETLK 8 /* set record locking information */ #define F_OSETLKW 9 /* F_SETLK; wait if blocked */ #define F_DUP2FD 10 /* duplicate file descriptor to arg */ #endif #define F_GETLK 11 /* get record locking information */ #define F_SETLK 12 /* set record locking information */ #define F_SETLKW 13 /* F_SETLK; wait if blocked */ #if __BSD_VISIBLE #define F_SETLK_REMOTE 14 /* debugging support for remote locks */ #define F_READAHEAD 15 /* read ahead */ #define F_RDAHEAD 16 /* Darwin compatible read ahead */ #endif #if __POSIX_VISIBLE >= 200809 #define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */ #endif #if __BSD_VISIBLE #define F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */ #endif /* file descriptor flags (F_GETFD, F_SETFD) */ #define FD_CLOEXEC 1 /* close-on-exec flag */ /* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */ #define F_RDLCK 1 /* shared or read lock */ #define F_UNLCK 2 /* unlock */ #define F_WRLCK 3 /* exclusive or write lock */ #if __BSD_VISIBLE #define F_UNLCKSYS 4 /* purge locks for a given system ID */ #define F_CANCEL 5 /* cancel an async lock request */ #endif #ifdef _KERNEL #define F_WAIT 0x010 /* Wait until lock is granted */ #define F_FLOCK 0x020 /* Use flock(2) semantics for lock */ #define F_POSIX 0x040 /* Use POSIX semantics for lock */ #define F_REMOTE 0x080 /* Lock owner is remote NFS client */ #define F_NOINTR 0x100 /* Ignore signals when waiting */ #endif /* * Advisory file segment locking data type - * information passed to system by user */ struct flock { off_t l_start; /* starting offset */ off_t l_len; /* len = 0 means until end of file */ pid_t l_pid; /* lock owner */ short l_type; /* lock type: read/write, etc. */ short l_whence; /* type of l_start */ int l_sysid; /* remote system id or zero for local */ }; #if __BSD_VISIBLE /* * Old advisory file segment locking data type, * before adding l_sysid. */ struct __oflock { off_t l_start; /* starting offset */ off_t l_len; /* len = 0 means until end of file */ pid_t l_pid; /* lock owner */ short l_type; /* lock type: read/write, etc. */ short l_whence; /* type of l_start */ }; #endif #if __BSD_VISIBLE /* lock operations for flock(2) */ #define LOCK_SH 0x01 /* shared file lock */ #define LOCK_EX 0x02 /* exclusive file lock */ #define LOCK_NB 0x04 /* don't block when locking */ #define LOCK_UN 0x08 /* unlock file */ #endif #if __POSIX_VISIBLE >= 200112 /* * Advice to posix_fadvise */ #define POSIX_FADV_NORMAL 0 /* no special treatment */ #define POSIX_FADV_RANDOM 1 /* expect random page references */ #define POSIX_FADV_SEQUENTIAL 2 /* expect sequential page references */ #define POSIX_FADV_WILLNEED 3 /* will need these pages */ #define POSIX_FADV_DONTNEED 4 /* dont need these pages */ #define POSIX_FADV_NOREUSE 5 /* access data only once */ #endif #ifndef _KERNEL __BEGIN_DECLS int open(const char *, int, ...); int creat(const char *, mode_t); int fcntl(int, int, ...); #if __BSD_VISIBLE int flock(int, int); #endif #if __POSIX_VISIBLE >= 200809 int openat(int, const char *, int, ...); #endif #if __POSIX_VISIBLE >= 200112 int posix_fadvise(int, off_t, off_t, int); int posix_fallocate(int, off_t, off_t); #endif __END_DECLS #endif #endif /* !_SYS_FCNTL_H_ */ /* * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _SYS_GPT_H_ #define _SYS_GPT_H_ #include struct gpt_hdr { char hdr_sig[8]; #define GPT_HDR_SIG "EFI PART" uint32_t hdr_revision; #define GPT_HDR_REVISION 0x00010000 uint32_t hdr_size; uint32_t hdr_crc_self; uint32_t __reserved; uint64_t hdr_lba_self; uint64_t hdr_lba_alt; uint64_t hdr_lba_start; uint64_t hdr_lba_end; struct uuid hdr_uuid; uint64_t hdr_lba_table; uint32_t hdr_entries; uint32_t hdr_entsz; uint32_t hdr_crc_table; /* * The header as defined in the EFI spec is not a multiple of 8 bytes * and given that the alignment requirement is on an 8 byte boundary, * padding will happen. We make the padding explicit so that we can * correct the value returned by sizeof() when we put the size of the * header in field hdr_size, or otherwise use offsetof(). */ uint32_t padding; }; struct gpt_ent { struct uuid ent_type; struct uuid ent_uuid; uint64_t ent_lba_start; uint64_t ent_lba_end; uint64_t ent_attr; #define GPT_ENT_ATTR_PLATFORM (1ULL << 0) #define GPT_ENT_ATTR_BOOTME (1ULL << 59) #define GPT_ENT_ATTR_BOOTONCE (1ULL << 58) #define GPT_ENT_ATTR_BOOTFAILED (1ULL << 57) uint16_t ent_name[36]; /* UTF-16. */ }; #define GPT_ENT_TYPE_UNUSED \ {0x00000000,0x0000,0x0000,0x00,0x00,{0x00,0x00,0x00,0x00,0x00,0x00}} #define GPT_ENT_TYPE_EFI \ {0xc12a7328,0xf81f,0x11d2,0xba,0x4b,{0x00,0xa0,0xc9,0x3e,0xc9,0x3b}} #define GPT_ENT_TYPE_MBR \ {0x024dee41,0x33e7,0x11d3,0x9d,0x69,{0x00,0x08,0xc7,0x81,0xf3,0x9f}} #define GPT_ENT_TYPE_FREEBSD \ {0x516e7cb4,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} #define GPT_ENT_TYPE_FREEBSD_BOOT \ {0x83bd6b9d,0x7f41,0x11dc,0xbe,0x0b,{0x00,0x15,0x60,0xb8,0x4f,0x0f}} #define GPT_ENT_TYPE_FREEBSD_SWAP \ {0x516e7cb5,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} #define GPT_ENT_TYPE_FREEBSD_UFS \ {0x516e7cb6,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} #define GPT_ENT_TYPE_FREEBSD_VINUM \ {0x516e7cb8,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} #define GPT_ENT_TYPE_FREEBSD_ZFS \ {0x516e7cba,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} #define GPT_ENT_TYPE_PREP_BOOT \ {0x9e1a2d38,0xc612,0x4316,0xaa,0x26,{0x8b,0x49,0x52,0x1e,0x5a,0x8b}} /* * The following are unused but documented here to avoid reuse. * * GPT_ENT_TYPE_FREEBSD_UFS2 \ * {0x516e7cb7,0x6ecf,0x11d6,0x8f,0xf8,{0x00,0x02,0x2d,0x09,0x71,0x2b}} */ /* * Foreign partition types that we're likely to encounter. Note that Linux * apparently choose to share data partitions with MS. I don't what the * advantage might be. I can see how sharing swap partitions is advantageous * though. */ #define GPT_ENT_TYPE_MS_BASIC_DATA \ {0xebd0a0a2,0xb9e5,0x4433,0x87,0xc0,{0x68,0xb6,0xb7,0x26,0x99,0xc7}} #define GPT_ENT_TYPE_MS_LDM_DATA \ {0xaf9b60a0,0x1431,0x4f62,0xbc,0x68,{0x33,0x11,0x71,0x4a,0x69,0xad}} #define GPT_ENT_TYPE_MS_LDM_METADATA \ {0x5808c8aa,0x7e8f,0x42e0,0x85,0xd2,{0xe1,0xe9,0x04,0x34,0xcf,0xb3}} #define GPT_ENT_TYPE_MS_RECOVERY \ {0xde94bba4,0x06d1,0x4d40,0xa1,0x6a,{0xbf,0xd5,0x01,0x79,0xd6,0xac}} #define GPT_ENT_TYPE_MS_RESERVED \ {0xe3c9e316,0x0b5c,0x4db8,0x81,0x7d,{0xf9,0x2d,0xf0,0x02,0x15,0xae}} #define GPT_ENT_TYPE_MS_SPACES \ {0xe75caf8f,0xf680,0x4cee,0xaf,0xa3,{0xb0,0x01,0xe5,0x6e,0xfc,0x2d}} #define GPT_ENT_TYPE_LINUX_DATA \ {0x0fc63daf,0x8483,0x4772,0x8e,0x79,{0x3d,0x69,0xd8,0x47,0x7d,0xe4}} #define GPT_ENT_TYPE_LINUX_RAID \ {0xa19d880f,0x05fc,0x4d3b,0xa0,0x06,{0x74,0x3f,0x0f,0x84,0x91,0x1e}} #define GPT_ENT_TYPE_LINUX_SWAP \ {0x0657fd6d,0xa4ab,0x43c4,0x84,0xe5,{0x09,0x33,0xc8,0x4b,0x4f,0x4f}} #define GPT_ENT_TYPE_LINUX_LVM \ {0xe6d6d379,0xf507,0x44c2,0xa2,0x3c,{0x23,0x8f,0x2a,0x3d,0xf9,0x28}} #define GPT_ENT_TYPE_VMFS \ {0xaa31e02a,0x400f,0x11db,0x95,0x90,{0x00,0x0c,0x29,0x11,0xd1,0xb8}} #define GPT_ENT_TYPE_VMKDIAG \ {0x9d275380,0x40ad,0x11db,0xbf,0x97,{0x00,0x0c,0x29,0x11,0xd1,0xb8}} #define GPT_ENT_TYPE_VMRESERVED \ {0x9198effc,0x31c0,0x11db,0x8f,0x78,{0x00,0x0c,0x29,0x11,0xd1,0xb8}} #define GPT_ENT_TYPE_VMVSANHDR \ {0x381cfccc,0x7288,0x11e0,0x92,0xee,{0x00,0x0c,0x29,0x11,0xd0,0xb2}} #define GPT_ENT_TYPE_APPLE_BOOT \ {0x426F6F74,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_HFS \ {0x48465300,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_UFS \ {0x55465300,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_ZFS \ {0x6a898cc3,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}} #define GPT_ENT_TYPE_APPLE_RAID \ {0x52414944,0x0000,0x11aa,0xaa,0x22,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_RAID_OFFLINE \ {0x52414944,0x5f4f,0x11aa,0xaa,0x22,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_LABEL \ {0x4C616265,0x6c00,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_TV_RECOVERY \ {0x5265636f,0x7665,0x11AA,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_CORE_STORAGE \ {0x53746f72,0x6167,0x11AA,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_APPLE_APFS \ {0x7C3457EF,0x0000,0x11aa,0xaa,0x11,{0x00,0x30,0x65,0x43,0xec,0xac}} #define GPT_ENT_TYPE_NETBSD_FFS \ {0x49f48d5a,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_NETBSD_LFS \ {0x49f48d82,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_NETBSD_SWAP \ {0x49f48d32,0xb10e,0x11dc,0xB9,0x9B,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_NETBSD_RAID \ {0x49f48daa,0xb10e,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_NETBSD_CCD \ {0x2db519c4,0xb10f,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_NETBSD_CGD \ {0x2db519ec,0xb10f,0x11dc,0xb9,0x9b,{0x00,0x19,0xd1,0x87,0x96,0x48}} #define GPT_ENT_TYPE_DRAGONFLY_LABEL32 \ {0x9d087404,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_SWAP \ {0x9d58fdbd,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_UFS1 \ {0x9d94ce7c,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_VINUM \ {0x9dd4478f,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_CCD \ {0xdbd5211b,0x1ca5,0x11dc,0x88,0x17,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_LABEL64 \ {0x3d48ce54,0x1d16,0x11dc,0x86,0x96,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_LEGACY \ {0xbd215ab2,0x1d16,0x11dc,0x86,0x96,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_HAMMER \ {0x61dc63ac,0x6e38,0x11dc,0x85,0x13,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_DRAGONFLY_HAMMER2 \ {0x5cbb9ad1,0x862d,0x11dc,0xa9,0x4d,{0x01,0x30,0x1b,0xb8,0xa9,0xf5}} #define GPT_ENT_TYPE_CHROMEOS_FIRMWARE \ {0xcab6e88e,0xabf3,0x4102,0xa0,0x7a,{0xd4,0xbb,0x9b,0xe3,0xc1,0xd3}} #define GPT_ENT_TYPE_CHROMEOS_KERNEL \ {0xfe3a2a5d,0x4f32,0x41a7,0xb7,0x25,{0xac,0xcc,0x32,0x85,0xa3,0x09}} #define GPT_ENT_TYPE_CHROMEOS_RESERVED \ {0x2e0a753d,0x9e48,0x43b0,0x83,0x37,{0xb1,0x51,0x92,0xcb,0x1b,0x5e}} #define GPT_ENT_TYPE_CHROMEOS_ROOT \ {0x3cb8e202,0x3b7e,0x47dd,0x8a,0x3c,{0x7f,0xf2,0xa1,0x3c,0xfc,0xec}} #define GPT_ENT_TYPE_OPENBSD_DATA \ {0x824cc7a0,0x36a8,0x11e3,0x89,0x0a,{0x95,0x25,0x19,0xad,0x3f,0x61}} #define GPT_ENT_TYPE_ILLUMOS_BOOT \ {0x6a82cb45,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}} #define GPT_ENT_TYPE_ILLUMOS_UFS \ {0x6a85cf4d,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}} #define GPT_ENT_TYPE_ILLUMOS_ZFS \ {0x6a898cc3,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}} #define GPT_ENT_TYPE_RESERVED \ {0x6a945a3b,0x1dd2,0x11b2,0x99,0xa6,{0x08,0x00,0x20,0x73,0x66,0x31}} /* * Boot partition used by GRUB 2. */ #define GPT_ENT_TYPE_BIOS_BOOT \ {0x21686148,0x6449,0x6e6f,0x74,0x4e,{0x65,0x65,0x64,0x45,0x46,0x49}} #endif /* _SYS_GPT_H_ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)exec.h 8.1 (Berkeley) 6/11/93 * $FreeBSD$ */ #ifndef _IMGACT_AOUT_H_ #define _IMGACT_AOUT_H_ #define N_GETMAGIC(ex) \ ( le32toh((ex).a_midmag) & 0xffff ) #define N_GETMID(ex) \ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \ ((ex).a_midmag >> 16) & 0x03ff ) #define N_GETFLAG(ex) \ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \ ((ex).a_midmag >> 26) & 0x3f ) #define N_SETMAGIC(ex,mag,mid,flag) \ ( (ex).a_midmag = htole32((((flag) & 0x3f) <<26) | \ (((mid) & 0x03ff) << 16) | \ ((mag) & 0xffff)) ) #define N_GETMAGIC_NET(ex) \ (ntohl((ex).a_midmag) & 0xffff) #define N_GETMID_NET(ex) \ ((ntohl((ex).a_midmag) >> 16) & 0x03ff) #define N_GETFLAG_NET(ex) \ ((ntohl((ex).a_midmag) >> 26) & 0x3f) #define N_SETMAGIC_NET(ex,mag,mid,flag) \ ( (ex).a_midmag = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) \ | (((mag)&0xffff)) ) ) #define N_ALIGN(ex,x) \ (N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC || \ N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \ ((x) + __LDPGSZ - 1) & ~(uint32_t)(__LDPGSZ - 1) : (x)) /* Valid magic number check. */ #define N_BADMAG(ex) \ (N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \ N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC && \ N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \ N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC) /* Address of the bottom of the text segment. */ /* * This can not be done right. Abuse a_entry in some cases to handle kernels. */ #define N_TXTADDR(ex) \ ((N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC || \ N_GETMAGIC(ex) == ZMAGIC) ? \ (le32toh((ex).a_entry) < le32toh((ex).a_text) ? 0 : \ le32toh((ex).a_entry) & ~__LDPGSZ) : __LDPGSZ) /* Address of the bottom of the data segment. */ #define N_DATADDR(ex) \ N_ALIGN(ex, N_TXTADDR(ex) + le32toh((ex).a_text)) /* Text segment offset. */ #define N_TXTOFF(ex) \ (N_GETMAGIC(ex) == ZMAGIC ? __LDPGSZ : (N_GETMAGIC(ex) == QMAGIC || \ N_GETMAGIC_NET(ex) == ZMAGIC) ? 0 : sizeof(struct exec)) /* Data segment offset. */ #define N_DATOFF(ex) \ N_ALIGN(ex, N_TXTOFF(ex) + le32toh((ex).a_text)) /* Relocation table offset. */ #define N_RELOFF(ex) \ N_ALIGN(ex, N_DATOFF(ex) + le32toh((ex).a_data)) /* Symbol table offset. */ #define N_SYMOFF(ex) \ (N_RELOFF(ex) + le32toh((ex).a_trsize) + le32toh((ex).a_drsize)) /* String table offset. */ #define N_STROFF(ex) (N_SYMOFF(ex) + le32toh((ex).a_syms)) /* * Header prepended to each a.out file. * Only manipulate the a_midmag field via the * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros. */ struct exec { uint32_t a_midmag; /* flags<<26 | mid<<16 | magic */ uint32_t a_text; /* text segment size */ uint32_t a_data; /* initialized data size */ uint32_t a_bss; /* uninitialized data size */ uint32_t a_syms; /* symbol table size */ uint32_t a_entry; /* entry point */ uint32_t a_trsize; /* text relocation size */ uint32_t a_drsize; /* data relocation size */ }; #define a_magic a_midmag /* Hack for emulators */ /* a_magic */ #define OMAGIC 0407 /* old impure format */ #define NMAGIC 0410 /* read-only text */ #define ZMAGIC 0413 /* demand load format */ #define QMAGIC 0314 /* "compact" demand load format */ /* a_mid */ #define MID_ZERO 0 /* unknown - implementation dependent */ #define MID_SUN010 1 /* sun 68010/68020 binary */ #define MID_SUN020 2 /* sun 68020-only binary */ #define MID_I386 134 /* i386 BSD binary */ #define MID_SPARC 138 /* sparc */ #define MID_ARM6 143 /* ARM6 */ #define MID_HP200 200 /* hp200 (68010) BSD binary */ #define MID_HP300 300 /* hp300 (68020+68881) BSD binary */ #define MID_HPUX 0x20C /* hp200/300 HP-UX binary */ #define MID_HPUX800 0x20B /* hp800 HP-UX binary */ /* * a_flags */ #define EX_PIC 0x10 /* contains position independent code */ #define EX_DYNAMIC 0x20 /* contains run-time link-edit info */ #define EX_DPMASK 0x30 /* mask for the above */ #ifdef _KERNEL struct thread; struct vnode; int aout_coredump(struct thread *td, struct vnode *vp, off_t limit, int flags); #endif #endif /* !_IMGACT_AOUT_H_ */ /*- * Copyright (c) 1982, 1986, 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ioccom.h 8.2 (Berkeley) 3/28/94 * $FreeBSD$ */ #ifndef _SYS_IOCCOM_H_ #define _SYS_IOCCOM_H_ /* * Ioctl's have the command encoded in the lower word, and the size of * any in or out parameters in the upper word. The high 3 bits of the * upper word are used to encode the in/out status of the parameter. */ #define IOCPARM_SHIFT 13 /* number of bits for ioctl size */ #define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */ #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) #define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) #define IOCGROUP(x) (((x) >> 8) & 0xff) #define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */ #define IOC_VOID 0x20000000 /* no parameters */ #define IOC_OUT 0x40000000 /* copy out parameters */ #define IOC_IN 0x80000000 /* copy in parameters */ #define IOC_INOUT (IOC_IN|IOC_OUT) #define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN) #define _IOC(inout,group,num,len) ((unsigned long) \ ((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num))) #define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) #define _IOWINT(g,n) _IOC(IOC_VOID, (g), (n), sizeof(int)) #define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) #define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) /* this should be _IORW, but stdio got there first */ #define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) #ifdef _KERNEL #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) #define IOCPARM_IVAL(x) ((int)(intptr_t)(void *)*(caddr_t *)(void *)(x)) #endif #else #include __BEGIN_DECLS int ioctl(int, unsigned long, ...); __END_DECLS #endif #endif /* !_SYS_IOCCOM_H_ */ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ #ifndef _SYS_LIMITS_H_ #define _SYS_LIMITS_H_ #include #include #define CHAR_BIT __CHAR_BIT /* number of bits in a char */ #define SCHAR_MAX __SCHAR_MAX /* max value for a signed char */ #define SCHAR_MIN __SCHAR_MIN /* min value for a signed char */ #define UCHAR_MAX __UCHAR_MAX /* max value for an unsigned char */ #ifdef __CHAR_UNSIGNED__ #define CHAR_MAX UCHAR_MAX /* max value for a char */ #define CHAR_MIN 0 /* min value for a char */ #else #define CHAR_MAX SCHAR_MAX #define CHAR_MIN SCHAR_MIN #endif #define USHRT_MAX __USHRT_MAX /* max value for an unsigned short */ #define SHRT_MAX __SHRT_MAX /* max value for a short */ #define SHRT_MIN __SHRT_MIN /* min value for a short */ #define UINT_MAX __UINT_MAX /* max value for an unsigned int */ #define INT_MAX __INT_MAX /* max value for an int */ #define INT_MIN __INT_MIN /* min value for an int */ #define ULONG_MAX __ULONG_MAX /* max for an unsigned long */ #define LONG_MAX __LONG_MAX /* max for a long */ #define LONG_MIN __LONG_MIN /* min for a long */ #ifdef __LONG_LONG_SUPPORTED #define ULLONG_MAX __ULLONG_MAX /* max for an unsigned long long */ #define LLONG_MAX __LLONG_MAX /* max for a long long */ #define LLONG_MIN __LLONG_MIN /* min for a long long */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SSIZE_MAX __SSIZE_MAX /* max value for an ssize_t */ #endif #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #define SIZE_T_MAX __SIZE_T_MAX /* max value for a size_t */ #define OFF_MAX __OFF_MAX /* max value for an off_t */ #define OFF_MIN __OFF_MIN /* min value for an off_t */ #endif #if __BSD_VISIBLE #define GID_MAX UINT_MAX /* max value for a gid_t */ #define UID_MAX UINT_MAX /* max value for a uid_t */ #define UQUAD_MAX (__UQUAD_MAX) /* max value for a uquad_t */ #define QUAD_MAX (__QUAD_MAX) /* max value for a quad_t */ #define QUAD_MIN (__QUAD_MIN) /* min value for a quad_t */ #endif #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 #define LONG_BIT __LONG_BIT #define WORD_BIT __WORD_BIT #endif #if __POSIX_VISIBLE #define MQ_PRIO_MAX 64 #endif #endif /* !_SYS_LIMITS_H_ */ /*- * Copyright (c) 1993 Paul Kranenburg * All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Paul Kranenburg. * 4. 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 ``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 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. * * $FreeBSD$ */ /* * RRS section definitions. * * The layout of some data structures defined in this header file is * such that we can provide compatibility with the SunOS 4.x shared * library scheme. */ #ifndef _SYS_LINK_ELF_H_ #define _SYS_LINK_ELF_H_ #include /* * Flags that describe the origin of the entries in Dl_serinfo. * SunOS has these in , we follow the suit. */ #define LA_SER_ORIG 0x01 /* original (needed) name */ #define LA_SER_LIBPATH 0x02 /* LD_LIBRARY_PATH entry prepended */ #define LA_SER_RUNPATH 0x04 /* runpath entry prepended */ #define LA_SER_CONFIG 0x08 /* configuration entry prepended */ #define LA_SER_DEFAULT 0x40 /* default path prepended */ #define LA_SER_SECURE 0x80 /* default (secure) path prepended */ typedef struct link_map { caddr_t l_addr; /* Base Address of library */ #ifdef __mips__ caddr_t l_offs; /* Load Offset of library */ #endif const char *l_name; /* Absolute Path to Library */ const void *l_ld; /* Pointer to .dynamic in memory */ struct link_map *l_next, *l_prev; /* linked list of of mapped libs */ } Link_map; struct r_debug { int r_version; /* not used */ struct link_map *r_map; /* list of loaded images */ void (*r_brk)(struct r_debug *, struct link_map *); /* pointer to break point */ enum { RT_CONSISTENT, /* things are stable */ RT_ADD, /* adding a shared library */ RT_DELETE /* removing a shared library */ } r_state; }; struct dl_phdr_info { Elf_Addr dlpi_addr; /* module relocation base */ const char *dlpi_name; /* module name */ const Elf_Phdr *dlpi_phdr; /* pointer to module's phdr */ Elf_Half dlpi_phnum; /* number of entries in phdr */ unsigned long long int dlpi_adds; /* total # of loads */ unsigned long long int dlpi_subs; /* total # of unloads */ size_t dlpi_tls_modid; void *dlpi_tls_data; }; __BEGIN_DECLS typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *); extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *); int _rtld_addr_phdr(const void *, struct dl_phdr_info *); int _rtld_get_stack_prot(void); int _rtld_is_dlopened(void *); #ifdef __ARM_EABI__ void * dl_unwind_find_exidx(const void *, int *); #endif __END_DECLS #endif /* _SYS_LINK_ELF_H_ */ /*- * Copyright (c) 1997-2000 Doug Rabson * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_LINKER_H_ #define _SYS_LINKER_H_ #ifdef _KERNEL #include #include #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_LINKER); #endif struct mod_depend; /* * Object representing a file which has been loaded by the linker. */ typedef struct linker_file* linker_file_t; typedef TAILQ_HEAD(, linker_file) linker_file_list_t; typedef caddr_t linker_sym_t; /* opaque symbol */ typedef c_caddr_t c_linker_sym_t; /* const opaque symbol */ typedef int (*linker_function_name_callback_t)(const char *, void *); /* * expanded out linker_sym_t */ typedef struct linker_symval { const char* name; caddr_t value; size_t size; } linker_symval_t; typedef int (*linker_function_nameval_callback_t)(linker_file_t, int, linker_symval_t *, void *); struct common_symbol { STAILQ_ENTRY(common_symbol) link; char* name; caddr_t address; }; struct linker_file { KOBJ_FIELDS; int refs; /* reference count */ int userrefs; /* kldload(2) count */ int flags; #define LINKER_FILE_LINKED 0x1 /* file has been fully linked */ TAILQ_ENTRY(linker_file) link; /* list of all loaded files */ char* filename; /* file which was loaded */ char* pathname; /* file name with full path */ int id; /* unique id */ caddr_t address; /* load address */ size_t size; /* size of file */ caddr_t ctors_addr; /* address of .ctors */ size_t ctors_size; /* size of .ctors */ int ndeps; /* number of dependencies */ linker_file_t* deps; /* list of dependencies */ STAILQ_HEAD(, common_symbol) common; /* list of common symbols */ TAILQ_HEAD(, module) modules; /* modules in this file */ TAILQ_ENTRY(linker_file) loaded; /* preload dependency support */ int loadcnt; /* load counter value */ /* * Function Boundary Tracing (FBT) or Statically Defined Tracing (SDT) * fields. */ int nenabled; /* number of enabled probes. */ int fbt_nentries; /* number of fbt entries created. */ }; /* * Object implementing a class of file (a.out, elf, etc.) */ typedef struct linker_class *linker_class_t; typedef TAILQ_HEAD(, linker_class) linker_class_list_t; struct linker_class { KOBJ_CLASS_FIELDS; TAILQ_ENTRY(linker_class) link; /* list of all file classes */ }; /* * Function type used when iterating over the list of linker files. */ typedef int linker_predicate_t(linker_file_t, void *); /* * The "file" for the kernel. */ extern linker_file_t linker_kernel_file; /* * Obtain a reference to a module, loading it if required. */ int linker_reference_module(const char* _modname, struct mod_depend *_verinfo, linker_file_t* _result); /* * Release a reference to a module, unloading it if there are no more * references. Note that one should either provide a module name and * optional version info or a linker file, but not both. */ int linker_release_module(const char *_modname, struct mod_depend *_verinfo, linker_file_t _file); /* * Iterate over all of the currently loaded linker files calling the * predicate function while the function returns 0. Returns the value * returned by the last predicate function. */ int linker_file_foreach(linker_predicate_t *_predicate, void *_context); /* * Lookup a symbol in a file. If deps is TRUE, look in dependencies * if not found in file. */ caddr_t linker_file_lookup_symbol(linker_file_t _file, const char* _name, int _deps); /* * Lookup a linker set in a file. Return pointers to the first entry, * last + 1, and count of entries. Use: for (p = start; p < stop; p++) {} * void *start is really: "struct yoursetmember ***start;" */ int linker_file_lookup_set(linker_file_t _file, const char *_name, void *_start, void *_stop, int *_count); /* * List all functions in a file. */ int linker_file_function_listall(linker_file_t, linker_function_nameval_callback_t, void *); /* * Functions soley for use by the linker class handlers. */ int linker_add_class(linker_class_t _cls); int linker_file_unload(linker_file_t _file, int flags); int linker_load_dependencies(linker_file_t _lf); linker_file_t linker_make_file(const char* _filename, linker_class_t _cls); /* * DDB Helpers, tuned specifically for ddb/db_kld.c */ int linker_ddb_lookup(const char *_symstr, c_linker_sym_t *_sym); int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym, long *_diffp); int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval); int linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen, long *offset); /* * stack(9) helper for situations where kernel locking is required. */ int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, long *offset); /* HWPMC helper */ void *linker_hwpmc_list_objects(void); #endif /* _KERNEL */ /* * Module information subtypes */ #define MODINFO_END 0x0000 /* End of list */ #define MODINFO_NAME 0x0001 /* Name of module (string) */ #define MODINFO_TYPE 0x0002 /* Type of module (string) */ #define MODINFO_ADDR 0x0003 /* Loaded address */ #define MODINFO_SIZE 0x0004 /* Size of module */ #define MODINFO_EMPTY 0x0005 /* Has been deleted */ #define MODINFO_ARGS 0x0006 /* Parameters string */ #define MODINFO_METADATA 0x8000 /* Module-specfic */ #define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ #define MODINFOMD_ELFHDR 0x0002 /* ELF header */ #define MODINFOMD_SSYM 0x0003 /* start of symbols */ #define MODINFOMD_ESYM 0x0004 /* end of symbols */ #define MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */ /* These values are MD on these two platforms */ #if !defined(__sparc64__) && !defined(__powerpc__) #define MODINFOMD_ENVP 0x0006 /* envp[] */ #define MODINFOMD_HOWTO 0x0007 /* boothowto */ #define MODINFOMD_KERNEND 0x0008 /* kernend */ #endif #define MODINFOMD_SHDR 0x0009 /* section header table */ #define MODINFOMD_CTORS_ADDR 0x000a /* address of .ctors */ #define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */ #define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */ #define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ #define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */ #ifdef _KERNEL #define MD_FETCH(mdp, info, type) ({ \ type *__p; \ __p = (type *)preload_search_info((mdp), MODINFO_METADATA | (info)); \ __p ? *__p : 0; \ }) #endif #define LINKER_HINTS_VERSION 1 /* linker.hints file version */ #define LINKER_HINTS_MAX (1 << 20) /* Allow at most 1MB for linker.hints */ #ifdef _KERNEL /* * Module lookup */ extern vm_offset_t preload_addr_relocate; extern caddr_t preload_metadata; extern void * preload_fetch_addr(caddr_t _mod); extern size_t preload_fetch_size(caddr_t _mod); extern caddr_t preload_search_by_name(const char *_name); extern caddr_t preload_search_by_type(const char *_type); extern caddr_t preload_search_next_name(caddr_t _base); extern caddr_t preload_search_info(caddr_t _mod, int _inf); extern void preload_delete_name(const char *_name); extern void preload_bootstrap_relocate(vm_offset_t _offset); #ifdef KLD_DEBUG extern int kld_debug; #define KLD_DEBUG_FILE 1 /* file load/unload */ #define KLD_DEBUG_SYM 2 /* symbol lookup */ #define KLD_DPF(cat, args) \ do { \ if (kld_debug & KLD_DEBUG_##cat) printf args; \ } while (0) #else #define KLD_DPF(cat, args) #endif typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *); /* Support functions */ int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu); int elf_reloc_local(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu); Elf_Addr elf_relocaddr(linker_file_t _lf, Elf_Addr addr); const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Size _symidx); const char *elf_get_symname(linker_file_t _lf, Elf_Size _symidx); typedef struct linker_ctf { const uint8_t *ctftab; /* Decompressed CTF data. */ int ctfcnt; /* Number of CTF data bytes. */ const Elf_Sym *symtab; /* Ptr to the symbol table. */ int nsym; /* Number of symbols. */ const char *strtab; /* Ptr to the string table. */ int strcnt; /* Number of string bytes. */ uint32_t **ctfoffp; /* Ptr to array of obj/fnc offsets. */ uint32_t **typoffp; /* Ptr to array of type offsets. */ long *typlenp; /* Ptr to number of type data entries. */ } linker_ctf_t; int linker_ctf_get(linker_file_t, linker_ctf_t *); int elf_cpu_load_file(linker_file_t); int elf_cpu_unload_file(linker_file_t); /* values for type */ #define ELF_RELOC_REL 1 #define ELF_RELOC_RELA 2 /* * This is version 1 of the KLD file status structure. It is identified * by its _size_ in the version field. */ struct kld_file_stat_1 { int version; /* set to sizeof(struct kld_file_stat_1) */ char name[MAXPATHLEN]; int refs; int id; caddr_t address; /* load address */ size_t size; /* size in bytes */ }; #endif /* _KERNEL */ struct kld_file_stat { int version; /* set to sizeof(struct kld_file_stat) */ char name[MAXPATHLEN]; int refs; int id; caddr_t address; /* load address */ size_t size; /* size in bytes */ char pathname[MAXPATHLEN]; }; struct kld_sym_lookup { int version; /* set to sizeof(struct kld_sym_lookup) */ char *symname; /* Symbol name we are looking up */ u_long symvalue; size_t symsize; }; #define KLDSYM_LOOKUP 1 /* * Flags for kldunloadf() and linker_file_unload() */ #define LINKER_UNLOAD_NORMAL 0 #define LINKER_UNLOAD_FORCE 1 #ifndef _KERNEL #include __BEGIN_DECLS int kldload(const char* _file); int kldunload(int _fileid); int kldunloadf(int _fileid, int flags); int kldfind(const char* _file); int kldnext(int _fileid); int kldstat(int _fileid, struct kld_file_stat* _stat); int kldfirstmod(int _fileid); int kldsym(int _fileid, int _cmd, void *_data); __END_DECLS #endif #endif /* !_SYS_LINKER_H_ */ /*- * Copyright (c) 1999 John D. Polstra * Copyright (c) 1999,2001 Peter Wemm * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_LINKER_SET_H_ #define _SYS_LINKER_SET_H_ #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif /* * The following macros are used to declare global sets of objects, which * are collected by the linker into a `linker_set' as defined below. * For ELF, this is done by constructing a separate segment for each set. */ #if defined(__powerpc64__) /* * Move the symbol pointer from ".text" to ".data" segment, to make * the GCC compiler happy: */ #define __MAKE_SET_CONST #else #define __MAKE_SET_CONST const #endif /* * Private macros, not to be used outside this header file. */ #ifdef __GNUCLIKE___SECTION #define __MAKE_SET(set, sym) \ __WEAK(__CONCAT(__start_set_,set)); \ __WEAK(__CONCAT(__stop_set_,set)); \ static void const * __MAKE_SET_CONST \ __set_##set##_sym_##sym __section("set_" #set) \ __used = &(sym) #else /* !__GNUCLIKE___SECTION */ #ifndef lint #error this file needs to be ported to your compiler #endif /* lint */ #define __MAKE_SET(set, sym) extern void const * const (__set_##set##_sym_##sym) #endif /* __GNUCLIKE___SECTION */ /* * Public macros. */ #define TEXT_SET(set, sym) __MAKE_SET(set, sym) #define DATA_SET(set, sym) __MAKE_SET(set, sym) #define BSS_SET(set, sym) __MAKE_SET(set, sym) #define ABS_SET(set, sym) __MAKE_SET(set, sym) #define SET_ENTRY(set, sym) __MAKE_SET(set, sym) /* * Initialize before referring to a given linker set. */ #define SET_DECLARE(set, ptype) \ extern ptype __weak_symbol *__CONCAT(__start_set_,set); \ extern ptype __weak_symbol *__CONCAT(__stop_set_,set) #define SET_BEGIN(set) \ (&__CONCAT(__start_set_,set)) #define SET_LIMIT(set) \ (&__CONCAT(__stop_set_,set)) /* * Iterate over all the elements of a set. * * Sets always contain addresses of things, and "pvar" points to words * containing those addresses. Thus is must be declared as "type **pvar", * and the address of each set item is obtained inside the loop by "*pvar". */ #define SET_FOREACH(pvar, set) \ for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) #define SET_ITEM(set, i) \ ((SET_BEGIN(set))[i]) /* * Provide a count of the items in a set. */ #define SET_COUNT(set) \ (SET_LIMIT(set) - SET_BEGIN(set)) #endif /* _SYS_LINKER_SET_H_ */ /*- * Copyright (c) 1997 Doug Rabson * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_MODULE_H_ #define _SYS_MODULE_H_ /* * Module metadata types */ #define MDT_DEPEND 1 /* argument is a module name */ #define MDT_MODULE 2 /* module declaration */ #define MDT_VERSION 3 /* module version(s) */ #define MDT_PNP_INFO 4 /* Plug and play hints record */ #define MDT_STRUCT_VERSION 1 /* version of metadata structure */ #define MDT_SETNAME "modmetadata_set" typedef enum modeventtype { MOD_LOAD, MOD_UNLOAD, MOD_SHUTDOWN, MOD_QUIESCE } modeventtype_t; typedef struct module *module_t; typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *); /* * Struct for registering modules statically via SYSINIT. */ typedef struct moduledata { const char *name; /* module name */ modeventhand_t evhand; /* event handler */ void *priv; /* extra data */ } moduledata_t; /* * A module can use this to report module specific data to the user via * kldstat(2). */ typedef union modspecific { int intval; u_int uintval; long longval; u_long ulongval; } modspecific_t; /* * Module dependency declaration */ struct mod_depend { int md_ver_minimum; int md_ver_preferred; int md_ver_maximum; }; /* * Module version declaration */ struct mod_version { int mv_version; }; struct mod_metadata { int md_version; /* structure version MDTV_* */ int md_type; /* type of entry MDT_* */ const void *md_data; /* specific data */ const char *md_cval; /* common string label */ }; struct mod_pnp_match_info { const char *descr; /* Description of the table */ const char *bus; /* Name of the bus for this table */ const void *table; /* Pointer to pnp table */ int entry_len; /* Length of each entry in the table (may be */ /* longer than descr describes). */ int num_entry; /* Number of entries in the table */ }; #ifdef _KERNEL #include #define MODULE_METADATA(uniquifier, type, data, cval) \ static struct mod_metadata _mod_metadata##uniquifier = { \ MDT_STRUCT_VERSION, \ type, \ data, \ cval \ }; \ DATA_SET(modmetadata_set, _mod_metadata##uniquifier) #define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) \ static struct mod_depend _##module##_depend_on_##mdepend \ __section(".data") = { \ vmin, \ vpref, \ vmax \ }; \ MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND, \ &_##module##_depend_on_##mdepend, #mdepend) /* * Every kernel has a 'kernel' module with the version set to * __FreeBSD_version. We embed a MODULE_DEPEND() inside every module * that depends on the 'kernel' module. It uses the current value of * __FreeBSD_version as the minimum and preferred versions. For the * maximum version it rounds the version up to the end of its branch * (i.e. M99999 for M.x). This allows a module built on M.x to work * on M.y systems where y >= x, but fail on M.z systems where z < x. */ #define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1) #define DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver) \ MODULE_DEPEND(name, kernel, __FreeBSD_version, \ __FreeBSD_version, maxver); \ MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name); \ SYSINIT(name##module, sub, order, module_register_init, &data); \ struct __hack #define DECLARE_MODULE(name, data, sub, order) \ DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER) /* * The module declared with DECLARE_MODULE_TIED can only be loaded * into the kernel with exactly the same __FreeBSD_version. * * Use it for modules that use kernel interfaces that are not stable * even on STABLE/X branches. */ #define DECLARE_MODULE_TIED(name, data, sub, order) \ DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version) #define MODULE_VERSION(module, version) \ static struct mod_version _##module##_version \ __section(".data") = { \ version \ }; \ MODULE_METADATA(_##module##_version, MDT_VERSION, \ &_##module##_version, #module) /** * Generic macros to create pnp info hints that modules may export * to allow external tools to parse their intenral device tables * to make an informed guess about what driver(s) to load. */ #define MODULE_PNP_INFO(d, b, unique, t, l, n) \ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \ .descr = d, \ .bus = #b, \ .table = t, \ .entry_len = l, \ .num_entry = n \ }; \ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \ &_module_pnp_##b##_##unique, #b); /** * descr is a string that describes each entry in the table. The general * form is (TYPE:pnp_name[/pnp_name];)* * where TYPE is one of the following: * U8 uint8_t element * V8 like U8 and 0xff means match any * G16 uint16_t element, any value >= matches * L16 uint16_t element, any value <= matches * M16 uint16_t element, mask of which of the following fields to use. * U16 uint16_t element * V16 like U16 and 0xffff means match any * U32 uint32_t element * V32 like U32 and 0xffffffff means match any * W32 Two 16-bit values with first pnp_name in LSW and second in MSW. * Z pointer to a string to match exactly * D like Z, but is the string passed to device_set_descr() * P A pointer that should be ignored * E EISA PNP Identifier (in binary, but bus publishes string) * K Key for whole table. pnp_name=value. must be last, if present. * * The pnp_name "#" is reserved for other fields that should be ignored. */ extern struct sx modules_sx; #define MOD_XLOCK sx_xlock(&modules_sx) #define MOD_SLOCK sx_slock(&modules_sx) #define MOD_XUNLOCK sx_xunlock(&modules_sx) #define MOD_SUNLOCK sx_sunlock(&modules_sx) #define MOD_LOCK_ASSERT sx_assert(&modules_sx, SX_LOCKED) #define MOD_XLOCK_ASSERT sx_assert(&modules_sx, SX_XLOCKED) struct linker_file; void module_register_init(const void *); int module_register(const struct moduledata *, struct linker_file *); module_t module_lookupbyname(const char *); module_t module_lookupbyid(int); int module_quiesce(module_t); void module_reference(module_t); void module_release(module_t); int module_unload(module_t); int module_getid(module_t); module_t module_getfnext(module_t); const char * module_getname(module_t); void module_setspecific(module_t, modspecific_t *); struct linker_file *module_file(module_t); #ifdef MOD_DEBUG extern int mod_debug; #define MOD_DEBUG_REFS 1 #define MOD_DPF(cat, args) do { \ if (mod_debug & MOD_DEBUG_##cat) \ printf(args); \ } while (0) #else /* !MOD_DEBUG */ #define MOD_DPF(cat, args) #endif #endif /* _KERNEL */ #define MAXMODNAME 32 struct module_stat { int version; /* set to sizeof(struct module_stat) */ char name[MAXMODNAME]; int refs; int id; modspecific_t data; }; #ifndef _KERNEL #include __BEGIN_DECLS int modnext(int _modid); int modfnext(int _modid); int modstat(int _modid, struct module_stat *_stat); int modfind(const char *_name); __END_DECLS #endif #endif /* !_SYS_MODULE_H_ */ /* multiboot.h - Multiboot header file. */ /* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * $FreeBSD$ */ #ifndef MULTIBOOT_HEADER #define MULTIBOOT_HEADER 1 /* How many bytes from the start of the file we search for the header. */ #define MULTIBOOT_SEARCH 8192 /* The magic field should contain this. */ #define MULTIBOOT_HEADER_MAGIC 0x1BADB002 /* This should be in %eax. */ #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 /* The bits in the required part of flags field we don't support. */ #define MULTIBOOT_UNSUPPORTED 0x0000fffc /* Alignment of multiboot modules. */ #define MULTIBOOT_MOD_ALIGN 0x00001000 /* Alignment of the multiboot info structure. */ #define MULTIBOOT_INFO_ALIGN 0x00000004 /* Flags set in the 'flags' member of the multiboot header. */ /* Align all boot modules on i386 page (4KB) boundaries. */ #define MULTIBOOT_PAGE_ALIGN 0x00000001 /* Must pass memory information to OS. */ #define MULTIBOOT_MEMORY_INFO 0x00000002 /* Must pass video information to OS. */ #define MULTIBOOT_VIDEO_MODE 0x00000004 /* This flag indicates the use of the address fields in the header. */ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 /* Flags to be set in the 'flags' member of the multiboot info structure. */ /* is there basic lower/upper memory information? */ #define MULTIBOOT_INFO_MEMORY 0x00000001 /* is there a boot device set? */ #define MULTIBOOT_INFO_BOOTDEV 0x00000002 /* is the command-line defined? */ #define MULTIBOOT_INFO_CMDLINE 0x00000004 /* are there modules to do something with? */ #define MULTIBOOT_INFO_MODS 0x00000008 /* These next two are mutually exclusive */ /* is there a symbol table loaded? */ #define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 /* is there an ELF section header table? */ #define MULTIBOOT_INFO_ELF_SHDR 0X00000020 /* is there a full memory map? */ #define MULTIBOOT_INFO_MEM_MAP 0x00000040 /* Is there drive info? */ #define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 /* Is there a config table? */ #define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 /* Is there a boot loader name? */ #define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 /* Is there a APM table? */ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ #define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 #ifndef ASM_FILE typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; struct multiboot_header { /* Must be MULTIBOOT_MAGIC - see above. */ multiboot_uint32_t magic; /* Feature flags. */ multiboot_uint32_t flags; /* The above fields plus this one must equal 0 mod 2^32. */ multiboot_uint32_t checksum; /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ multiboot_uint32_t header_addr; multiboot_uint32_t load_addr; multiboot_uint32_t load_end_addr; multiboot_uint32_t bss_end_addr; multiboot_uint32_t entry_addr; /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ multiboot_uint32_t mode_type; multiboot_uint32_t width; multiboot_uint32_t height; multiboot_uint32_t depth; }; /* The symbol table for a.out. */ struct multiboot_aout_symbol_table { multiboot_uint32_t tabsize; multiboot_uint32_t strsize; multiboot_uint32_t addr; multiboot_uint32_t reserved; }; typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; /* The section header table for ELF. */ struct multiboot_elf_section_header_table { multiboot_uint32_t num; multiboot_uint32_t size; multiboot_uint32_t addr; multiboot_uint32_t shndx; }; typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; struct multiboot_info { /* Multiboot info version number */ multiboot_uint32_t flags; /* Available memory from BIOS */ multiboot_uint32_t mem_lower; multiboot_uint32_t mem_upper; /* "root" partition */ multiboot_uint32_t boot_device; /* Kernel command line */ multiboot_uint32_t cmdline; /* Boot-Module list */ multiboot_uint32_t mods_count; multiboot_uint32_t mods_addr; union { multiboot_aout_symbol_table_t aout_sym; multiboot_elf_section_header_table_t elf_sec; } u; /* Memory Mapping buffer */ multiboot_uint32_t mmap_length; multiboot_uint32_t mmap_addr; /* Drive Info buffer */ multiboot_uint32_t drives_length; multiboot_uint32_t drives_addr; /* ROM configuration table */ multiboot_uint32_t config_table; /* Boot Loader Name */ multiboot_uint32_t boot_loader_name; /* APM table */ multiboot_uint32_t apm_table; /* Video */ multiboot_uint32_t vbe_control_info; multiboot_uint32_t vbe_mode_info; multiboot_uint16_t vbe_mode; multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; }; typedef struct multiboot_info multiboot_info_t; struct multiboot_mmap_entry { multiboot_uint32_t size; multiboot_uint64_t addr; multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 multiboot_uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; struct multiboot_mod_list { /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ multiboot_uint32_t mod_start; multiboot_uint32_t mod_end; /* Module command line */ multiboot_uint32_t cmdline; /* padding to take it to 16 bytes (must be zero) */ multiboot_uint32_t pad; }; typedef struct multiboot_mod_list multiboot_module_t; #endif /* ! ASM_FILE */ #endif /* ! MULTIBOOT_HEADER */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)nlist.h 8.2 (Berkeley) 1/21/94 * * $FreeBSD$ */ #ifndef _SYS_NLIST_AOUT_H_ #define _SYS_NLIST_AOUT_H_ /* * Symbol table entries in a.out files. */ /* * Layout of each symbol. The "#ifdef _AOUT_INCLUDE_" is so that * programs including nlist.h can initialize nlist structures * statically. */ struct nlist { #ifdef _AOUT_INCLUDE_ union { const char *n_name; /* symbol name (in memory) */ long n_strx; /* file string table offset (on disk) */ } n_un; #else const char *n_name; /* symbol name (in memory) */ #endif unsigned char n_type; /* type defines */ char n_other; /* ".type" and binding information */ short n_desc; /* used by stab entries */ unsigned long n_value; /* address/value of the symbol */ }; #define n_hash n_desc /* used internally by ld(1); XXX */ /* * Defines for n_type. */ #define N_UNDF 0x00 /* undefined */ #define N_ABS 0x02 /* absolute address */ #define N_TEXT 0x04 /* text segment */ #define N_DATA 0x06 /* data segment */ #define N_BSS 0x08 /* bss segment */ #define N_INDR 0x0a /* alias definition */ #define N_SIZE 0x0c /* pseudo type, defines a symbol's size */ #define N_COMM 0x12 /* common reference */ /* GNU extensions */ #define N_SETA 0x14 /* Absolute set element symbol */ #define N_SETT 0x16 /* Text set element symbol */ #define N_SETD 0x18 /* Data set element symbol */ #define N_SETB 0x1a /* Bss set element symbol */ #define N_SETV 0x1c /* Pointer to set vector in data area. */ /* end GNU extensions */ #define N_FN 0x1e /* file name (N_EXT on) */ #define N_WARN 0x1e /* warning message (N_EXT off) */ #define N_EXT 0x01 /* external (global) bit, OR'ed in */ #define N_TYPE 0x1e /* mask for all the type bits */ #define N_STAB 0xe0 /* mask for debugger symbols -- stab(5) */ /* * Defines for n_other. It contains the ".type" (AUX) field in the least * significant 4 bits, and the binding (for weak symbols) in the most * significant 4 bits. */ #define N_AUX(p) ((p)->n_other & 0xf) #define N_BIND(p) (((unsigned int)(p)->n_other >> 4) & 0xf) #define N_OTHER(r, v) (((unsigned int)(r) << 4) | ((v) & 0xf)) #define AUX_OBJECT 1 /* data object */ #define AUX_FUNC 2 /* function */ /*#define BIND_LOCAL 0 not used */ /*#define BIND_GLOBAL 1 not used */ #define BIND_WEAK 2 /* weak binding */ #define N_FORMAT "%08x" /* namelist value format; XXX */ #endif /* !_SYS_NLIST_AOUT_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD$ */ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ #include #define BSD 199506 /* System version (year & month). */ #define BSD4_3 1 #define BSD4_4 1 /* * __FreeBSD_version numbers are documented in the Porter's Handbook. * If you bump the version for any reason, you should update the documentation * there. * Currently this lives here in the doc/ repository: * * head/en_US.ISO8859-1/books/porters-handbook/versions/chapter.xml * * scheme is: Rxx * 'R' is in the range 0 to 4 if this is a release branch or * x.0-CURRENT before RELENG_*_0 is created, otherwise 'R' is * in the range 5 to 9. */ #undef __FreeBSD_version #define __FreeBSD_version 1100100 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * which by definition is always true on FreeBSD. This macro is also defined * on other systems that use the kernel of FreeBSD, such as GNU/kFreeBSD. * * It is tempting to use this macro in userland code when we want to enable * kernel-specific routines, and in fact it's fine to do this in code that * is part of FreeBSD itself. However, be aware that as presence of this * macro is still not widespread (e.g. older FreeBSD versions, 3rd party * compilers, etc), it is STRONGLY DISCOURAGED to check for this macro in * external applications without also checking for __FreeBSD__ as an * alternative. */ #undef __FreeBSD_kernel__ #define __FreeBSD_kernel__ #ifdef _KERNEL #define P_OSREL_SIGWAIT 700000 #define P_OSREL_SIGSEGV 700004 #define P_OSREL_MAP_ANON 800104 #define P_OSREL_MAP_FSTRICT 1100036 #define P_OSREL_SHUTDOWN_ENOTCONN 1100077 #define P_OSREL_MAJOR(x) ((x) / 100000) #endif #ifndef LOCORE #include #endif /* * Machine-independent constants (some used in following include files). * Redefined constants are from POSIX 1003.1 limits file. * * MAXCOMLEN should be >= sizeof(ac_comm) (see ) */ #include #define MAXCOMLEN 19 /* max command name remembered */ #define MAXINTERP PATH_MAX /* max interpreter file name length */ #define MAXLOGNAME 33 /* max login name length (incl. NUL) */ #define MAXUPRC CHILD_MAX /* max simultaneous processes */ #define NCARGS ARG_MAX /* max bytes for an exec function */ #define NGROUPS (NGROUPS_MAX+1) /* max number groups */ #define NOFILE OPEN_MAX /* max open files per process */ #define NOGROUP 65535 /* marker for empty group set member */ #define MAXHOSTNAMELEN 256 /* max hostname size */ #define SPECNAMELEN 63 /* max length of devicename */ /* More types and definitions used throughout the kernel. */ #ifdef _KERNEL #include #include #ifndef LOCORE #include #include #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif #ifndef _KERNEL /* Signals. */ #include #endif /* Machine type dependent parameters. */ #include #ifndef _KERNEL #include #endif #ifndef DEV_BSHIFT #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #endif #define DEV_BSIZE (1<>PAGE_SHIFT) #endif /* * btodb() is messy and perhaps slow because `bytes' may be an off_t. We * want to shift an unsigned type to avoid sign extension and we don't * want to widen `bytes' unnecessarily. Assume that the result fits in * a daddr_t. */ #ifndef btodb #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \ (sizeof (bytes) > sizeof(long) \ ? (daddr_t)((unsigned long long)(bytes) >> DEV_BSHIFT) \ : (daddr_t)((unsigned long)(bytes) >> DEV_BSHIFT)) #endif #ifndef dbtob #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \ ((off_t)(db) << DEV_BSHIFT) #endif #define PRIMASK 0x0ff #define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ #define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ #define NZERO 0 /* default "nice" */ #define NBBY 8 /* number of bits in a byte */ #define NBPW sizeof(int) /* number of bytes per word (integer) */ #define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */ #define NODEV (dev_t)(-1) /* non-existent device */ /* * File system parameters and macros. * * MAXBSIZE - Filesystems are made out of blocks of at most MAXBSIZE bytes * per block. MAXBSIZE may be made larger without effecting * any existing filesystems as long as it does not exceed MAXPHYS, * and may be made smaller at the risk of not being able to use * filesystems which require a block size exceeding MAXBSIZE. * * MAXBCACHEBUF - Maximum size of a buffer in the buffer cache. This must * be >= MAXBSIZE and can be set differently for different * architectures by defining it in . * Making this larger allows NFS to do larger reads/writes. * * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the * minimum KVM memory reservation the kernel is willing to make. * Filesystems can of course request smaller chunks. Actual * backing memory uses a chunk size of a page (PAGE_SIZE). * The default value here can be overridden on a per-architecture * basis by defining it in . This should * probably be done to increase its value, when MAXBCACHEBUF is * defined as a larger value in . * * If you make BKVASIZE too small you risk seriously fragmenting * the buffer KVM map which may slow things down a bit. If you * make it too big the kernel will not be able to optimally use * the KVM memory reserved for the buffer cache and will wind * up with too-few buffers. * * The default is 16384, roughly 2x the block size used by a * normal UFS filesystem. */ #define MAXBSIZE 65536 /* must be power of 2 */ #ifndef MAXBCACHEBUF #define MAXBCACHEBUF MAXBSIZE /* must be a power of 2 >= MAXBSIZE */ #endif #ifndef BKVASIZE #define BKVASIZE 16384 /* must be power of 2 */ #endif #define BKVAMASK (BKVASIZE-1) /* * MAXPATHLEN defines the longest permissible path length after expanding * symbolic links. It is used to allocate a temporary buffer from the buffer * pool in which to do the name expansion, hence should be a power of two, * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the * maximum number of symbolic links that may be expanded in a path name. * It should be set high enough to allow all legitimate uses, but halt * infinite loops reasonably quickly. */ #define MAXPATHLEN PATH_MAX #define MAXSYMLINKS 32 /* Bit map related macros. */ #define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a,i) \ (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a,i) \ ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0) /* Macros for counting and rounding. */ #ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) #endif #define nitems(x) (sizeof((x)) / sizeof((x)[0])) #define rounddown(x, y) (((x)/(y))*(y)) #define rounddown2(x, y) ((x)&(~((y)-1))) /* if y is power of two */ #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #define powerof2(x) ((((x)-1)&(x))==0) /* Macros for min/max. */ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #ifdef _KERNEL /* * Basic byte order function prototypes for non-inline functions. */ #ifndef LOCORE #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED __BEGIN_DECLS __uint32_t htonl(__uint32_t); __uint16_t htons(__uint16_t); __uint32_t ntohl(__uint32_t); __uint16_t ntohs(__uint16_t); __END_DECLS #endif #endif #ifndef lint #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif /* !_BYTEORDER_FUNC_DEFINED */ #endif /* lint */ #endif /* _KERNEL */ /* * Scale factor for scaled integers used to count %cpu time and load avgs. * * The number of CPU `tick's that map to a unique `%age' can be expressed * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that * can be calculated (assuming 32 bits) can be closely approximated using * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). * * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age', * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024. */ #define FSHIFT 11 /* bits to right of fixed binary point */ #define FSCALE (1<> (PAGE_SHIFT - DEV_BSHIFT)) #define ctodb(db) /* calculates pages to devblks */ \ ((db) << (PAGE_SHIFT - DEV_BSHIFT)) /* * Old spelling of __containerof(). */ #define member2struct(s, m, x) \ ((struct s *)(void *)((char *)(x) - offsetof(struct s, m))) /* * Access a variable length array that has been declared as a fixed * length array. */ #define __PAST_END(array, offset) (((__typeof__(*(array)) *)(array))[offset]) #endif /* _SYS_PARAM_H_ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 * $FreeBSD$ */ #ifndef _SYS_QUEUE_H_ #define _SYS_QUEUE_H_ #include /* * This file defines four types of data structures: singly-linked lists, * singly-linked tail queues, lists and tail queues. * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at * the expense of O(n) removal for arbitrary elements. New elements can be * added to the list after an existing element or at the head of the list. * Elements being removed from the head of the list should use the explicit * macro for this purpose for optimum efficiency. A singly-linked list may * only be traversed in the forward direction. Singly-linked lists are ideal * for applications with large datasets and few or no removals or for * implementing a LIFO queue. * * A singly-linked tail queue is headed by a pair of pointers, one to the * head of the list and the other to the tail of the list. The elements are * singly linked for minimum space and pointer manipulation overhead at the * expense of O(n) removal for arbitrary elements. New elements can be added * to the list after an existing element, at the head of the list, or at the * end of the list. Elements being removed from the head of the tail queue * should use the explicit macro for this purpose for optimum efficiency. * A singly-linked tail queue may only be traversed in the forward direction. * Singly-linked tail queues are ideal for applications with large datasets * and few or no removals or for implementing a FIFO queue. * * A list is headed by a single forward pointer (or an array of forward * pointers for a hash table header). The elements are doubly linked * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list * may be traversed in either direction. * * A tail queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * * For details on the use of these macros, see the queue(3) manual page. * * * SLIST LIST STAILQ TAILQ * _HEAD + + + + * _CLASS_HEAD + + + + * _HEAD_INITIALIZER + + + + * _ENTRY + + + + * _CLASS_ENTRY + + + + * _INIT + + + + * _EMPTY + + + + * _FIRST + + + + * _NEXT + + + + * _PREV - + - + * _LAST - - + + * _FOREACH + + + + * _FOREACH_FROM + + + + * _FOREACH_SAFE + + + + * _FOREACH_FROM_SAFE + + + + * _FOREACH_REVERSE - - - + * _FOREACH_REVERSE_FROM - - - + * _FOREACH_REVERSE_SAFE - - - + * _FOREACH_REVERSE_FROM_SAFE - - - + * _INSERT_HEAD + + + + * _INSERT_BEFORE - + - + * _INSERT_AFTER + + + + * _INSERT_TAIL - - + + * _CONCAT - - + + * _REMOVE_AFTER + - + - * _REMOVE_HEAD + - + - * _REMOVE + + + + * _SWAP + + + + * */ #ifdef QUEUE_MACRO_DEBUG /* Store the last 2 places the queue element or head was altered */ struct qm_trace { unsigned long lastline; unsigned long prevline; const char *lastfile; const char *prevfile; }; #define TRACEBUF struct qm_trace trace; #define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } , #define TRASHIT(x) do {(x) = (void *)-1;} while (0) #define QMD_SAVELINK(name, link) void **name = (void *)&(link) #define QMD_TRACE_HEAD(head) do { \ (head)->trace.prevline = (head)->trace.lastline; \ (head)->trace.prevfile = (head)->trace.lastfile; \ (head)->trace.lastline = __LINE__; \ (head)->trace.lastfile = __FILE__; \ } while (0) #define QMD_TRACE_ELEM(elem) do { \ (elem)->trace.prevline = (elem)->trace.lastline; \ (elem)->trace.prevfile = (elem)->trace.lastfile; \ (elem)->trace.lastline = __LINE__; \ (elem)->trace.lastfile = __FILE__; \ } while (0) #else #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) #define QMD_SAVELINK(name, link) #define TRACEBUF #define TRACEBUF_INITIALIZER #define TRASHIT(x) #endif /* QUEUE_MACRO_DEBUG */ #ifdef __cplusplus /* * In C++ there can be structure lists and class lists: */ #define QUEUE_TYPEOF(type) type #else #define QUEUE_TYPEOF(type) struct type #endif /* * Singly-linked List declarations. */ #define SLIST_HEAD(name, type) \ struct name { \ struct type *slh_first; /* first element */ \ } #define SLIST_CLASS_HEAD(name, type) \ struct name { \ class type *slh_first; /* first element */ \ } #define SLIST_HEAD_INITIALIZER(head) \ { NULL } #define SLIST_ENTRY(type) \ struct { \ struct type *sle_next; /* next element */ \ } #define SLIST_CLASS_ENTRY(type) \ struct { \ class type *sle_next; /* next element */ \ } /* * Singly-linked List functions. */ #define SLIST_EMPTY(head) ((head)->slh_first == NULL) #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_FOREACH(var, head, field) \ for ((var) = SLIST_FIRST((head)); \ (var); \ (var) = SLIST_NEXT((var), field)) #define SLIST_FOREACH_FROM(var, head, field) \ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ (var); \ (var) = SLIST_NEXT((var), field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST((head)); \ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ (var) = (tvar)) #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ (var) = (tvar)) #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ for ((varp) = &SLIST_FIRST((head)); \ ((var) = *(varp)) != NULL; \ (varp) = &SLIST_NEXT((var), field)) #define SLIST_INIT(head) do { \ SLIST_FIRST((head)) = NULL; \ } while (0) #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ SLIST_NEXT((slistelm), field) = (elm); \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ SLIST_FIRST((head)) = (elm); \ } while (0) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_REMOVE(head, elm, type, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ if (SLIST_FIRST((head)) == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \ while (SLIST_NEXT(curelm, field) != (elm)) \ curelm = SLIST_NEXT(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \ } \ TRASHIT(*oldnext); \ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \ SLIST_NEXT(elm, field) = \ SLIST_NEXT(SLIST_NEXT(elm, field), field); \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ } while (0) #define SLIST_SWAP(head1, head2, type) do { \ QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \ SLIST_FIRST(head1) = SLIST_FIRST(head2); \ SLIST_FIRST(head2) = swap_first; \ } while (0) /* * Singly-linked Tail queue declarations. */ #define STAILQ_HEAD(name, type) \ struct name { \ struct type *stqh_first;/* first element */ \ struct type **stqh_last;/* addr of last next element */ \ } #define STAILQ_CLASS_HEAD(name, type) \ struct name { \ class type *stqh_first; /* first element */ \ class type **stqh_last; /* addr of last next element */ \ } #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } #define STAILQ_ENTRY(type) \ struct { \ struct type *stqe_next; /* next element */ \ } #define STAILQ_CLASS_ENTRY(type) \ struct { \ class type *stqe_next; /* next element */ \ } /* * Singly-linked Tail queue functions. */ #define STAILQ_CONCAT(head1, head2) do { \ if (!STAILQ_EMPTY((head2))) { \ *(head1)->stqh_last = (head2)->stqh_first; \ (head1)->stqh_last = (head2)->stqh_last; \ STAILQ_INIT((head2)); \ } \ } while (0) #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) #define STAILQ_FIRST(head) ((head)->stqh_first) #define STAILQ_FOREACH(var, head, field) \ for((var) = STAILQ_FIRST((head)); \ (var); \ (var) = STAILQ_NEXT((var), field)) #define STAILQ_FOREACH_FROM(var, head, field) \ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ (var); \ (var) = STAILQ_NEXT((var), field)) #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = STAILQ_FIRST((head)); \ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ (var) = (tvar)) #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ (var) = (tvar)) #define STAILQ_INIT(head) do { \ STAILQ_FIRST((head)) = NULL; \ (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ STAILQ_NEXT((tqelm), field) = (elm); \ } while (0) #define STAILQ_INSERT_HEAD(head, elm, field) do { \ if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ STAILQ_FIRST((head)) = (elm); \ } while (0) #define STAILQ_INSERT_TAIL(head, elm, field) do { \ STAILQ_NEXT((elm), field) = NULL; \ *(head)->stqh_last = (elm); \ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ } while (0) #define STAILQ_LAST(head, type, field) \ (STAILQ_EMPTY((head)) ? NULL : \ __containerof((head)->stqh_last, \ QUEUE_TYPEOF(type), field.stqe_next)) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #define STAILQ_REMOVE(head, elm, type, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ if (STAILQ_FIRST((head)) == (elm)) { \ STAILQ_REMOVE_HEAD((head), field); \ } \ else { \ QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \ while (STAILQ_NEXT(curelm, field) != (elm)) \ curelm = STAILQ_NEXT(curelm, field); \ STAILQ_REMOVE_AFTER(head, curelm, field); \ } \ TRASHIT(*oldnext); \ } while (0) #define STAILQ_REMOVE_AFTER(head, elm, field) do { \ if ((STAILQ_NEXT(elm, field) = \ STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ } while (0) #define STAILQ_REMOVE_HEAD(head, field) do { \ if ((STAILQ_FIRST((head)) = \ STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) #define STAILQ_SWAP(head1, head2, type) do { \ QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \ QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \ STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ (head1)->stqh_last = (head2)->stqh_last; \ STAILQ_FIRST(head2) = swap_first; \ (head2)->stqh_last = swap_last; \ if (STAILQ_EMPTY(head1)) \ (head1)->stqh_last = &STAILQ_FIRST(head1); \ if (STAILQ_EMPTY(head2)) \ (head2)->stqh_last = &STAILQ_FIRST(head2); \ } while (0) /* * List declarations. */ #define LIST_HEAD(name, type) \ struct name { \ struct type *lh_first; /* first element */ \ } #define LIST_CLASS_HEAD(name, type) \ struct name { \ class type *lh_first; /* first element */ \ } #define LIST_HEAD_INITIALIZER(head) \ { NULL } #define LIST_ENTRY(type) \ struct { \ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } #define LIST_CLASS_ENTRY(type) \ struct { \ class type *le_next; /* next element */ \ class type **le_prev; /* address of previous next element */ \ } /* * List functions. */ #if (defined(_KERNEL) && defined(INVARIANTS)) #define QMD_LIST_CHECK_HEAD(head, field) do { \ if (LIST_FIRST((head)) != NULL && \ LIST_FIRST((head))->field.le_prev != \ &LIST_FIRST((head))) \ panic("Bad list head %p first->prev != head", (head)); \ } while (0) #define QMD_LIST_CHECK_NEXT(elm, field) do { \ if (LIST_NEXT((elm), field) != NULL && \ LIST_NEXT((elm), field)->field.le_prev != \ &((elm)->field.le_next)) \ panic("Bad link elm %p next->prev != elm", (elm)); \ } while (0) #define QMD_LIST_CHECK_PREV(elm, field) do { \ if (*(elm)->field.le_prev != (elm)) \ panic("Bad link elm %p prev->next != elm", (elm)); \ } while (0) #else #define QMD_LIST_CHECK_HEAD(head, field) #define QMD_LIST_CHECK_NEXT(elm, field) #define QMD_LIST_CHECK_PREV(elm, field) #endif /* (_KERNEL && INVARIANTS) */ #define LIST_EMPTY(head) ((head)->lh_first == NULL) #define LIST_FIRST(head) ((head)->lh_first) #define LIST_FOREACH(var, head, field) \ for ((var) = LIST_FIRST((head)); \ (var); \ (var) = LIST_NEXT((var), field)) #define LIST_FOREACH_FROM(var, head, field) \ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ (var); \ (var) = LIST_NEXT((var), field)) #define LIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = LIST_FIRST((head)); \ (var) && ((tvar) = LIST_NEXT((var), field), 1); \ (var) = (tvar)) #define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ (var) && ((tvar) = LIST_NEXT((var), field), 1); \ (var) = (tvar)) #define LIST_INIT(head) do { \ LIST_FIRST((head)) = NULL; \ } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \ QMD_LIST_CHECK_NEXT(listelm, field); \ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ LIST_NEXT((listelm), field)->field.le_prev = \ &LIST_NEXT((elm), field); \ LIST_NEXT((listelm), field) = (elm); \ (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ } while (0) #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ QMD_LIST_CHECK_PREV(listelm, field); \ (elm)->field.le_prev = (listelm)->field.le_prev; \ LIST_NEXT((elm), field) = (listelm); \ *(listelm)->field.le_prev = (elm); \ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ } while (0) #define LIST_INSERT_HEAD(head, elm, field) do { \ QMD_LIST_CHECK_HEAD((head), field); \ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ LIST_FIRST((head)) = (elm); \ (elm)->field.le_prev = &LIST_FIRST((head)); \ } while (0) #define LIST_NEXT(elm, field) ((elm)->field.le_next) #define LIST_PREV(elm, head, type, field) \ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ __containerof((elm)->field.le_prev, \ QUEUE_TYPEOF(type), field.le_next)) #define LIST_REMOVE(elm, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.le_next); \ QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ QMD_LIST_CHECK_NEXT(elm, field); \ QMD_LIST_CHECK_PREV(elm, field); \ if (LIST_NEXT((elm), field) != NULL) \ LIST_NEXT((elm), field)->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = LIST_NEXT((elm), field); \ TRASHIT(*oldnext); \ TRASHIT(*oldprev); \ } while (0) #define LIST_SWAP(head1, head2, type, field) do { \ QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \ LIST_FIRST((head1)) = LIST_FIRST((head2)); \ LIST_FIRST((head2)) = swap_tmp; \ if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ } while (0) /* * Tail queue declarations. */ #define TAILQ_HEAD(name, type) \ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ TRACEBUF \ } #define TAILQ_CLASS_HEAD(name, type) \ struct name { \ class type *tqh_first; /* first element */ \ class type **tqh_last; /* addr of last next element */ \ TRACEBUF \ } #define TAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ TRACEBUF \ } #define TAILQ_CLASS_ENTRY(type) \ struct { \ class type *tqe_next; /* next element */ \ class type **tqe_prev; /* address of previous next element */ \ TRACEBUF \ } /* * Tail queue functions. */ #if (defined(_KERNEL) && defined(INVARIANTS)) #define QMD_TAILQ_CHECK_HEAD(head, field) do { \ if (!TAILQ_EMPTY(head) && \ TAILQ_FIRST((head))->field.tqe_prev != \ &TAILQ_FIRST((head))) \ panic("Bad tailq head %p first->prev != head", (head)); \ } while (0) #define QMD_TAILQ_CHECK_TAIL(head, field) do { \ if (*(head)->tqh_last != NULL) \ panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ } while (0) #define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ if (TAILQ_NEXT((elm), field) != NULL && \ TAILQ_NEXT((elm), field)->field.tqe_prev != \ &((elm)->field.tqe_next)) \ panic("Bad link elm %p next->prev != elm", (elm)); \ } while (0) #define QMD_TAILQ_CHECK_PREV(elm, field) do { \ if (*(elm)->field.tqe_prev != (elm)) \ panic("Bad link elm %p prev->next != elm", (elm)); \ } while (0) #else #define QMD_TAILQ_CHECK_HEAD(head, field) #define QMD_TAILQ_CHECK_TAIL(head, headname) #define QMD_TAILQ_CHECK_NEXT(elm, field) #define QMD_TAILQ_CHECK_PREV(elm, field) #endif /* (_KERNEL && INVARIANTS) */ #define TAILQ_CONCAT(head1, head2, field) do { \ if (!TAILQ_EMPTY(head2)) { \ *(head1)->tqh_last = (head2)->tqh_first; \ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ (head1)->tqh_last = (head2)->tqh_last; \ TAILQ_INIT((head2)); \ QMD_TRACE_HEAD(head1); \ QMD_TRACE_HEAD(head2); \ } \ } while (0) #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_FOREACH(var, head, field) \ for ((var) = TAILQ_FIRST((head)); \ (var); \ (var) = TAILQ_NEXT((var), field)) #define TAILQ_FOREACH_FROM(var, head, field) \ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ (var); \ (var) = TAILQ_NEXT((var), field)) #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = TAILQ_FIRST((head)); \ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ (var) = (tvar)) #define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ (var) = (tvar)) #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for ((var) = TAILQ_LAST((head), headname); \ (var); \ (var) = TAILQ_PREV((var), headname, field)) #define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ (var); \ (var) = TAILQ_PREV((var), headname, field)) #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ for ((var) = TAILQ_LAST((head), headname); \ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ (var) = (tvar)) #define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ (var) = (tvar)) #define TAILQ_INIT(head) do { \ TAILQ_FIRST((head)) = NULL; \ (head)->tqh_last = &TAILQ_FIRST((head)); \ QMD_TRACE_HEAD(head); \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ QMD_TAILQ_CHECK_NEXT(listelm, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ TAILQ_NEXT((elm), field)->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ else { \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ QMD_TRACE_HEAD(head); \ } \ TAILQ_NEXT((listelm), field) = (elm); \ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ QMD_TAILQ_CHECK_PREV(listelm, field); \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ TAILQ_NEXT((elm), field) = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ QMD_TAILQ_CHECK_HEAD(head, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ TAILQ_FIRST((head))->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ else \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ TAILQ_FIRST((head)) = (elm); \ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ QMD_TRACE_HEAD(head); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ QMD_TAILQ_CHECK_TAIL(head, field); \ TAILQ_NEXT((elm), field) = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ QMD_TRACE_HEAD(head); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) #define TAILQ_LAST(head, headname) \ (*(((struct headname *)((head)->tqh_last))->tqh_last)) #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_REMOVE(head, elm, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ QMD_TAILQ_CHECK_NEXT(elm, field); \ QMD_TAILQ_CHECK_PREV(elm, field); \ if ((TAILQ_NEXT((elm), field)) != NULL) \ TAILQ_NEXT((elm), field)->field.tqe_prev = \ (elm)->field.tqe_prev; \ else { \ (head)->tqh_last = (elm)->field.tqe_prev; \ QMD_TRACE_HEAD(head); \ } \ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ TRASHIT(*oldnext); \ TRASHIT(*oldprev); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) #define TAILQ_SWAP(head1, head2, type, field) do { \ QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \ QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ (head1)->tqh_first = (head2)->tqh_first; \ (head1)->tqh_last = (head2)->tqh_last; \ (head2)->tqh_first = swap_first; \ (head2)->tqh_last = swap_last; \ if ((swap_first = (head1)->tqh_first) != NULL) \ swap_first->field.tqe_prev = &(head1)->tqh_first; \ else \ (head1)->tqh_last = &(head1)->tqh_first; \ if ((swap_first = (head2)->tqh_first) != NULL) \ swap_first->field.tqe_prev = &(head2)->tqh_first; \ else \ (head2)->tqh_last = &(head2)->tqh_first; \ } while (0) #endif /* !_SYS_QUEUE_H_ */ /*- * Copyright (c) 1982, 1986, 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)reboot.h 8.3 (Berkeley) 12/13/94 * $FreeBSD$ */ #ifndef _SYS_REBOOT_H_ #define _SYS_REBOOT_H_ /* * Arguments to reboot system call. These are passed to * the boot program and on to init. */ #define RB_AUTOBOOT 0 /* flags for system auto-booting itself */ #define RB_ASKNAME 0x001 /* ask for file name to reboot from */ #define RB_SINGLE 0x002 /* reboot to single user only */ #define RB_NOSYNC 0x004 /* dont sync before reboot */ #define RB_HALT 0x008 /* don't reboot, just halt */ #define RB_INITNAME 0x010 /* name given for /etc/init (unused) */ #define RB_DFLTROOT 0x020 /* use compiled-in rootdev */ #define RB_KDB 0x040 /* give control to kernel debugger */ #define RB_RDONLY 0x080 /* mount root fs read-only */ #define RB_DUMP 0x100 /* dump kernel memory before reboot */ #define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */ #define RB_VERBOSE 0x800 /* print all potentially useful info */ #define RB_SERIAL 0x1000 /* use serial port as console */ #define RB_CDROM 0x2000 /* use cdrom as root */ #define RB_POWEROFF 0x4000 /* turn the power off if possible */ #define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */ #define RB_MUTE 0x10000 /* start up with the console muted */ #define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */ #define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */ #define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */ #define RB_PAUSE 0x100000 /* pause after each output line during probe */ #define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */ #define RB_MULTIPLE 0x20000000 /* use multiple consoles */ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ #endif /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * $FreeBSD$ */ #ifndef _SYS_SELECT_H_ #define _SYS_SELECT_H_ #include #include #include #include #include typedef unsigned long __fd_mask; #if __BSD_VISIBLE typedef __fd_mask fd_mask; #endif #ifndef _SIGSET_T_DECLARED #define _SIGSET_T_DECLARED typedef __sigset_t sigset_t; #endif /* * Select uses bit masks of file descriptors in longs. These macros * manipulate such bit fields (the filesystem macros use chars). * FD_SETSIZE may be defined by the user, but the default here should * be enough for most uses. */ #ifndef FD_SETSIZE #define FD_SETSIZE 1024 #endif #define _NFDBITS (sizeof(__fd_mask) * 8) /* bits per mask */ #if __BSD_VISIBLE #define NFDBITS _NFDBITS #endif #ifndef _howmany #define _howmany(x, y) (((x) + ((y) - 1)) / (y)) #endif typedef struct fd_set { __fd_mask __fds_bits[_howmany(FD_SETSIZE, _NFDBITS)]; } fd_set; #if __BSD_VISIBLE #define fds_bits __fds_bits #endif #define __fdset_mask(n) ((__fd_mask)1 << ((n) % _NFDBITS)) #define FD_CLR(n, p) ((p)->__fds_bits[(n)/_NFDBITS] &= ~__fdset_mask(n)) #if __BSD_VISIBLE #define FD_COPY(f, t) (void)(*(t) = *(f)) #endif #define FD_ISSET(n, p) (((p)->__fds_bits[(n)/_NFDBITS] & __fdset_mask(n)) != 0) #define FD_SET(n, p) ((p)->__fds_bits[(n)/_NFDBITS] |= __fdset_mask(n)) #define FD_ZERO(p) do { \ fd_set *_p; \ __size_t _n; \ \ _p = (p); \ _n = _howmany(FD_SETSIZE, _NFDBITS); \ while (_n > 0) \ _p->__fds_bits[--_n] = 0; \ } while (0) #ifndef _KERNEL __BEGIN_DECLS int pselect(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, const struct timespec *__restrict, const sigset_t *__restrict); #ifndef _SELECT_DECLARED #define _SELECT_DECLARED /* XXX missing restrict type-qualifier */ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); #endif __END_DECLS #endif /* !_KERNEL */ #endif /* _SYS_SELECT_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)signal.h 8.4 (Berkeley) 5/4/95 * $FreeBSD$ */ #ifndef _SYS_SIGNAL_H_ #define _SYS_SIGNAL_H_ #include #include #include #include /* __MINSIGSTKSZ */ #include /* sig_atomic_t; trap codes; sigcontext */ /* * System defined signals. */ #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGHUP 1 /* hangup */ #endif #define SIGINT 2 /* interrupt */ #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGQUIT 3 /* quit */ #endif #define SIGILL 4 /* illegal instr. (not reset when caught) */ #if __XSI_VISIBLE #define SIGTRAP 5 /* trace trap (not reset when caught) */ #endif #define SIGABRT 6 /* abort() */ #if __BSD_VISIBLE #define SIGIOT SIGABRT /* compatibility */ #define SIGEMT 7 /* EMT instruction */ #endif #define SIGFPE 8 /* floating point exception */ #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #endif #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #define SIGBUS 10 /* bus error */ #endif #define SIGSEGV 11 /* segmentation violation */ #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #define SIGSYS 12 /* non-existent system call invoked */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #endif #define SIGTERM 15 /* software termination signal from kill */ #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #define SIGURG 16 /* urgent condition on IO channel */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGSTOP 17 /* sendable stop signal not from tty */ #define SIGTSTP 18 /* stop signal from tty */ #define SIGCONT 19 /* continue a stopped process */ #define SIGCHLD 20 /* to parent on child stop or exit */ #define SIGTTIN 21 /* to readers pgrp upon background tty read */ #define SIGTTOU 22 /* like TTIN if (tp->t_local<OSTOP) */ #endif #if __BSD_VISIBLE #define SIGIO 23 /* input/output possible signal */ #endif #if __XSI_VISIBLE #define SIGXCPU 24 /* exceeded CPU time limit */ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ #endif #if __BSD_VISIBLE #define SIGWINCH 28 /* window size changes */ #define SIGINFO 29 /* information request */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SIGUSR1 30 /* user defined signal 1 */ #define SIGUSR2 31 /* user defined signal 2 */ #endif #if __BSD_VISIBLE #define SIGTHR 32 /* reserved by thread library. */ #define SIGLWP SIGTHR #define SIGLIBRT 33 /* reserved by real-time library. */ #endif #define SIGRTMIN 65 #define SIGRTMAX 126 #define SIG_DFL ((__sighandler_t *)0) #define SIG_IGN ((__sighandler_t *)1) #define SIG_ERR ((__sighandler_t *)-1) /* #define SIG_CATCH ((__sighandler_t *)2) See signalvar.h */ #define SIG_HOLD ((__sighandler_t *)3) /* * Type of a signal handling function. * * Language spec sez signal handlers take exactly one arg, even though we * actually supply three. Ugh! * * We don't try to hide the difference by leaving out the args because * that would cause warnings about conformant programs. Nonconformant * programs can avoid the warnings by casting to (__sighandler_t *) or * sig_t before calling signal() or assigning to sa_handler or sv_handler. * * The kernel should reverse the cast before calling the function. It * has no way to do this, but on most machines 1-arg and 3-arg functions * have the same calling protocol so there is no problem in practice. * A bit in sa_flags could be used to specify the number of args. */ typedef void __sighandler_t(int); #if __POSIX_VISIBLE || __XSI_VISIBLE #ifndef _SIGSET_T_DECLARED #define _SIGSET_T_DECLARED typedef __sigset_t sigset_t; #endif #endif #if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE >= 500 union sigval { /* Members as suggested by Annex C of POSIX 1003.1b. */ int sival_int; void *sival_ptr; /* 6.0 compatibility */ int sigval_int; void *sigval_ptr; }; #endif #if __POSIX_VISIBLE >= 199309 struct sigevent { int sigev_notify; /* Notification type */ int sigev_signo; /* Signal number */ union sigval sigev_value; /* Signal value */ union { __lwpid_t _threadid; struct { void (*_function)(union sigval); void *_attribute; /* pthread_attr_t * */ } _sigev_thread; unsigned short _kevent_flags; long __spare__[8]; } _sigev_un; }; #if __BSD_VISIBLE #define sigev_notify_kqueue sigev_signo #define sigev_notify_kevent_flags _sigev_un._kevent_flags #define sigev_notify_thread_id _sigev_un._threadid #endif #define sigev_notify_function _sigev_un._sigev_thread._function #define sigev_notify_attributes _sigev_un._sigev_thread._attribute #define SIGEV_NONE 0 /* No async notification. */ #define SIGEV_SIGNAL 1 /* Generate a queued signal. */ #define SIGEV_THREAD 2 /* Call back from another pthread. */ #if __BSD_VISIBLE #define SIGEV_KEVENT 3 /* Generate a kevent. */ #define SIGEV_THREAD_ID 4 /* Send signal to a kernel thread. */ #endif #endif /* __POSIX_VISIBLE >= 199309 */ #if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE typedef struct __siginfo { int si_signo; /* signal number */ int si_errno; /* errno association */ /* * Cause of signal, one of the SI_ macros or signal-specific * values, i.e. one of the FPE_... values for SIGFPE. This * value is equivalent to the second argument to an old-style * FreeBSD signal handler. */ int si_code; /* signal code */ __pid_t si_pid; /* sending process */ __uid_t si_uid; /* sender's ruid */ int si_status; /* exit value */ void *si_addr; /* faulting instruction */ union sigval si_value; /* signal value */ union { struct { int _trapno;/* machine specific trap code */ } _fault; struct { int _timerid; int _overrun; } _timer; struct { int _mqd; } _mesgq; struct { long _band; /* band event for SIGPOLL */ } _poll; /* was this ever used ? */ struct { long __spare1__; int __spare2__[7]; } __spare__; } _reason; } siginfo_t; #define si_trapno _reason._fault._trapno #define si_timerid _reason._timer._timerid #define si_overrun _reason._timer._overrun #define si_mqd _reason._mesgq._mqd #define si_band _reason._poll._band /** si_code **/ /* codes for SIGILL */ #define ILL_ILLOPC 1 /* Illegal opcode. */ #define ILL_ILLOPN 2 /* Illegal operand. */ #define ILL_ILLADR 3 /* Illegal addressing mode. */ #define ILL_ILLTRP 4 /* Illegal trap. */ #define ILL_PRVOPC 5 /* Privileged opcode. */ #define ILL_PRVREG 6 /* Privileged register. */ #define ILL_COPROC 7 /* Coprocessor error. */ #define ILL_BADSTK 8 /* Internal stack error. */ /* codes for SIGBUS */ #define BUS_ADRALN 1 /* Invalid address alignment. */ #define BUS_ADRERR 2 /* Nonexistent physical address. */ #define BUS_OBJERR 3 /* Object-specific hardware error. */ /* codes for SIGSEGV */ #define SEGV_MAPERR 1 /* Address not mapped to object. */ #define SEGV_ACCERR 2 /* Invalid permissions for mapped */ /* object. */ /* codes for SIGFPE */ #define FPE_INTOVF 1 /* Integer overflow. */ #define FPE_INTDIV 2 /* Integer divide by zero. */ #define FPE_FLTDIV 3 /* Floating point divide by zero. */ #define FPE_FLTOVF 4 /* Floating point overflow. */ #define FPE_FLTUND 5 /* Floating point underflow. */ #define FPE_FLTRES 6 /* Floating point inexact result. */ #define FPE_FLTINV 7 /* Invalid floating point operation. */ #define FPE_FLTSUB 8 /* Subscript out of range. */ /* codes for SIGTRAP */ #define TRAP_BRKPT 1 /* Process breakpoint. */ #define TRAP_TRACE 2 /* Process trace trap. */ #define TRAP_DTRACE 3 /* DTrace induced trap. */ /* codes for SIGCHLD */ #define CLD_EXITED 1 /* Child has exited */ #define CLD_KILLED 2 /* Child has terminated abnormally but */ /* did not create a core file */ #define CLD_DUMPED 3 /* Child has terminated abnormally and */ /* created a core file */ #define CLD_TRAPPED 4 /* Traced child has trapped */ #define CLD_STOPPED 5 /* Child has stopped */ #define CLD_CONTINUED 6 /* Stopped child has continued */ /* codes for SIGPOLL */ #define POLL_IN 1 /* Data input available */ #define POLL_OUT 2 /* Output buffers available */ #define POLL_MSG 3 /* Input message available */ #define POLL_ERR 4 /* I/O Error */ #define POLL_PRI 5 /* High priority input available */ #define POLL_HUP 6 /* Device disconnected */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE struct __siginfo; /* * Signal vector "template" used in sigaction call. */ struct sigaction { union { void (*__sa_handler)(int); void (*__sa_sigaction)(int, struct __siginfo *, void *); } __sigaction_u; /* signal handler */ int sa_flags; /* see signal options below */ sigset_t sa_mask; /* signal mask to apply */ }; #define sa_handler __sigaction_u.__sa_handler #endif #if __XSI_VISIBLE /* If SA_SIGINFO is set, sa_sigaction must be used instead of sa_handler. */ #define sa_sigaction __sigaction_u.__sa_sigaction #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ #endif /* __POSIX_VISIBLE || __XSI_VISIBLE */ #if __XSI_VISIBLE #define SA_ONSTACK 0x0001 /* take signal on signal stack */ #define SA_RESTART 0x0002 /* restart system call on signal return */ #define SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */ #define SA_NODEFER 0x0010 /* don't mask the signal we're delivering */ #define SA_NOCLDWAIT 0x0020 /* don't keep zombies around */ #define SA_SIGINFO 0x0040 /* signal handler with SA_SIGINFO args */ #endif #if __BSD_VISIBLE #define NSIG 32 /* number of old signals (counting 0) */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE #define SI_NOINFO 0 /* No signal info besides si_signo. */ #define SI_USER 0x10001 /* Signal sent by kill(). */ #define SI_QUEUE 0x10002 /* Signal sent by the sigqueue(). */ #define SI_TIMER 0x10003 /* Signal generated by expiration of */ /* a timer set by timer_settime(). */ #define SI_ASYNCIO 0x10004 /* Signal generated by completion of */ /* an asynchronous I/O request.*/ #define SI_MESGQ 0x10005 /* Signal generated by arrival of a */ /* message on an empty message queue. */ #define SI_KERNEL 0x10006 #define SI_LWP 0x10007 /* Signal sent by thr_kill */ #endif #if __BSD_VISIBLE #define SI_UNDEFINED 0 #endif #if __BSD_VISIBLE typedef __sighandler_t *sig_t; /* type of pointer to a signal function */ typedef void __siginfohandler_t(int, struct __siginfo *, void *); #endif #if __XSI_VISIBLE /* * Structure used in sigaltstack call. */ #if __BSD_VISIBLE typedef struct sigaltstack { #else typedef struct { #endif void *ss_sp; /* signal stack base */ __size_t ss_size; /* signal stack length */ int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ } stack_t; #define SS_ONSTACK 0x0001 /* take signal on alternate stack */ #define SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ #define MINSIGSTKSZ __MINSIGSTKSZ /* minimum stack size */ #define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */ #endif #if __BSD_VISIBLE /* * 4.3 compatibility: * Signal vector "template" used in sigvec call. */ struct sigvec { __sighandler_t *sv_handler; /* signal handler */ int sv_mask; /* signal mask to apply */ int sv_flags; /* see signal options below */ }; #define SV_ONSTACK SA_ONSTACK #define SV_INTERRUPT SA_RESTART /* same bit, opposite sense */ #define SV_RESETHAND SA_RESETHAND #define SV_NODEFER SA_NODEFER #define SV_NOCLDSTOP SA_NOCLDSTOP #define SV_SIGINFO SA_SIGINFO #define sv_onstack sv_flags /* isn't compatibility wonderful! */ #endif /* Keep this in one place only */ #if defined(_KERNEL) && defined(COMPAT_43) && \ !defined(__i386__) struct osigcontext { int _not_used; }; #endif #if __XSI_VISIBLE /* * Structure used in sigstack call. */ struct sigstack { void *ss_sp; /* signal stack pointer */ int ss_onstack; /* current status */ }; #endif #if __BSD_VISIBLE || __POSIX_VISIBLE > 0 && __POSIX_VISIBLE <= 200112 /* * Macro for converting signal number to a mask suitable for * sigblock(). */ #define sigmask(m) (1 << ((m)-1)) #endif #if __BSD_VISIBLE #define BADSIG SIG_ERR #endif #if __POSIX_VISIBLE || __XSI_VISIBLE /* * Flags for sigprocmask: */ #define SIG_BLOCK 1 /* block specified signal set */ #define SIG_UNBLOCK 2 /* unblock specified signal set */ #define SIG_SETMASK 3 /* set specified signal set */ #endif /* * For historical reasons; programs expect signal's return value to be * defined by . */ __BEGIN_DECLS __sighandler_t *signal(int, __sighandler_t *); __END_DECLS #endif /* !_SYS_SIGNAL_H_ */ /*- * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)socket.h 8.4 (Berkeley) 2/21/94 * $FreeBSD$ */ #ifndef _SYS_SOCKET_H_ #define _SYS_SOCKET_H_ #include #include #include #include /* * Definitions related to sockets: types, address families, options. */ /* * Data types. */ #if __BSD_VISIBLE #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED #endif #ifndef _OFF_T_DECLARED typedef __off_t off_t; #define _OFF_T_DECLARED #endif #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif #endif #ifndef _SA_FAMILY_T_DECLARED typedef __sa_family_t sa_family_t; #define _SA_FAMILY_T_DECLARED #endif #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif #if __BSD_VISIBLE #ifndef _UID_T_DECLARED typedef __uid_t uid_t; #define _UID_T_DECLARED #endif #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _UINTPTR_T_DECLARED typedef __uintptr_t uintptr_t; #define _UINTPTR_T_DECLARED #endif /* * Types */ #define SOCK_STREAM 1 /* stream socket */ #define SOCK_DGRAM 2 /* datagram socket */ #define SOCK_RAW 3 /* raw-protocol interface */ #if __BSD_VISIBLE #define SOCK_RDM 4 /* reliably-delivered message */ #endif #define SOCK_SEQPACKET 5 /* sequenced packet stream */ #if __BSD_VISIBLE /* * Creation flags, OR'ed into socket() and socketpair() type argument. */ #define SOCK_CLOEXEC 0x10000000 #define SOCK_NONBLOCK 0x20000000 #endif /* * Option flags per-socket. */ #define SO_DEBUG 0x0001 /* turn on debugging info recording */ #define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ #define SO_REUSEADDR 0x0004 /* allow local address reuse */ #define SO_KEEPALIVE 0x0008 /* keep connections alive */ #define SO_DONTROUTE 0x0010 /* just use interface addresses */ #define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ #if __BSD_VISIBLE #define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ #endif #define SO_LINGER 0x0080 /* linger on close if data present */ #define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ #if __BSD_VISIBLE #define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ #define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ #define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */ #define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ #define SO_BINTIME 0x2000 /* timestamp received dgram traffic */ #endif #define SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */ #define SO_NO_DDP 0x8000 /* disable direct data placement */ /* * Additional options, not kept in so_options. */ #define SO_SNDBUF 0x1001 /* send buffer size */ #define SO_RCVBUF 0x1002 /* receive buffer size */ #define SO_SNDLOWAT 0x1003 /* send low-water mark */ #define SO_RCVLOWAT 0x1004 /* receive low-water mark */ #define SO_SNDTIMEO 0x1005 /* send timeout */ #define SO_RCVTIMEO 0x1006 /* receive timeout */ #define SO_ERROR 0x1007 /* get error status and clear */ #define SO_TYPE 0x1008 /* get socket type */ #if __BSD_VISIBLE #define SO_LABEL 0x1009 /* socket's MAC label */ #define SO_PEERLABEL 0x1010 /* socket's peer's MAC label */ #define SO_LISTENQLIMIT 0x1011 /* socket's backlog limit */ #define SO_LISTENQLEN 0x1012 /* socket's complete queue length */ #define SO_LISTENINCQLEN 0x1013 /* socket's incomplete queue length */ #define SO_SETFIB 0x1014 /* use this FIB to route */ #define SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */ #define SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */ #define SO_PROTOTYPE SO_PROTOCOL /* alias for SO_PROTOCOL (SunOS name) */ #endif /* * Space reserved for new socket options added by third-party vendors. * This range applies to all socket option levels. New socket options * in FreeBSD should always use an option value less than SO_VENDOR. */ #if __BSD_VISIBLE #define SO_VENDOR 0x80000000 #endif /* * Structure used for manipulating linger option. */ struct linger { int l_onoff; /* option on/off */ int l_linger; /* linger time */ }; #if __BSD_VISIBLE struct accept_filter_arg { char af_name[16]; char af_arg[256-16]; }; #endif /* * Level number for (get/set)sockopt() to apply to socket itself. */ #define SOL_SOCKET 0xffff /* options for socket level */ /* * Address families. */ #define AF_UNSPEC 0 /* unspecified */ #if __BSD_VISIBLE #define AF_LOCAL AF_UNIX /* local to host (pipes, portals) */ #endif #define AF_UNIX 1 /* standardized name for AF_LOCAL */ #define AF_INET 2 /* internetwork: UDP, TCP, etc. */ #if __BSD_VISIBLE #define AF_IMPLINK 3 /* arpanet imp addresses */ #define AF_PUP 4 /* pup protocols: e.g. BSP */ #define AF_CHAOS 5 /* mit CHAOS protocols */ #define AF_NETBIOS 6 /* SMB protocols */ #define AF_ISO 7 /* ISO protocols */ #define AF_OSI AF_ISO #define AF_ECMA 8 /* European computer manufacturers */ #define AF_DATAKIT 9 /* datakit protocols */ #define AF_CCITT 10 /* CCITT protocols, X.25 etc */ #define AF_SNA 11 /* IBM SNA */ #define AF_DECnet 12 /* DECnet */ #define AF_DLI 13 /* DEC Direct data link interface */ #define AF_LAT 14 /* LAT */ #define AF_HYLINK 15 /* NSC Hyperchannel */ #define AF_APPLETALK 16 /* Apple Talk */ #define AF_ROUTE 17 /* Internal Routing Protocol */ #define AF_LINK 18 /* Link layer interface */ #define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */ #define AF_COIP 20 /* connection-oriented IP, aka ST II */ #define AF_CNT 21 /* Computer Network Technology */ #define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */ #define AF_IPX 23 /* Novell Internet Protocol */ #define AF_SIP 24 /* Simple Internet Protocol */ #define pseudo_AF_PIP 25 /* Help Identify PIP packets */ #define AF_ISDN 26 /* Integrated Services Digital Network*/ #define AF_E164 AF_ISDN /* CCITT E.164 recommendation */ #define pseudo_AF_KEY 27 /* Internal key-management function */ #endif #define AF_INET6 28 /* IPv6 */ #if __BSD_VISIBLE #define AF_NATM 29 /* native ATM access */ #define AF_ATM 30 /* ATM */ #define pseudo_AF_HDRCMPLT 31 /* Used by BPF to not rewrite headers * in interface output routine */ #define AF_NETGRAPH 32 /* Netgraph sockets */ #define AF_SLOW 33 /* 802.3ad slow protocol */ #define AF_SCLUSTER 34 /* Sitara cluster protocol */ #define AF_ARP 35 #define AF_BLUETOOTH 36 /* Bluetooth sockets */ #define AF_IEEE80211 37 /* IEEE 802.11 protocol */ #define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */ #define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */ #define AF_MAX 42 /* * When allocating a new AF_ constant, please only allocate * even numbered constants for FreeBSD until 134 as odd numbered AF_ * constants 39-133 are now reserved for vendors. */ #define AF_VENDOR00 39 #define AF_VENDOR01 41 #define AF_VENDOR02 43 #define AF_VENDOR03 45 #define AF_VENDOR04 47 #define AF_VENDOR05 49 #define AF_VENDOR06 51 #define AF_VENDOR07 53 #define AF_VENDOR08 55 #define AF_VENDOR09 57 #define AF_VENDOR10 59 #define AF_VENDOR11 61 #define AF_VENDOR12 63 #define AF_VENDOR13 65 #define AF_VENDOR14 67 #define AF_VENDOR15 69 #define AF_VENDOR16 71 #define AF_VENDOR17 73 #define AF_VENDOR18 75 #define AF_VENDOR19 77 #define AF_VENDOR20 79 #define AF_VENDOR21 81 #define AF_VENDOR22 83 #define AF_VENDOR23 85 #define AF_VENDOR24 87 #define AF_VENDOR25 89 #define AF_VENDOR26 91 #define AF_VENDOR27 93 #define AF_VENDOR28 95 #define AF_VENDOR29 97 #define AF_VENDOR30 99 #define AF_VENDOR31 101 #define AF_VENDOR32 103 #define AF_VENDOR33 105 #define AF_VENDOR34 107 #define AF_VENDOR35 109 #define AF_VENDOR36 111 #define AF_VENDOR37 113 #define AF_VENDOR38 115 #define AF_VENDOR39 117 #define AF_VENDOR40 119 #define AF_VENDOR41 121 #define AF_VENDOR42 123 #define AF_VENDOR43 125 #define AF_VENDOR44 127 #define AF_VENDOR45 129 #define AF_VENDOR46 131 #define AF_VENDOR47 133 #endif /* * Structure used by kernel to store most * addresses. */ struct sockaddr { unsigned char sa_len; /* total length */ sa_family_t sa_family; /* address family */ char sa_data[14]; /* actually longer; address value */ }; #if __BSD_VISIBLE #define SOCK_MAXADDRLEN 255 /* longest possible addresses */ /* * Structure used by kernel to pass protocol * information in raw sockets. */ struct sockproto { unsigned short sp_family; /* address family */ unsigned short sp_protocol; /* protocol */ }; #endif #include #if __BSD_VISIBLE /* * Protocol families, same as address families for now. */ #define PF_UNSPEC AF_UNSPEC #define PF_LOCAL AF_LOCAL #define PF_UNIX PF_LOCAL /* backward compatibility */ #define PF_INET AF_INET #define PF_IMPLINK AF_IMPLINK #define PF_PUP AF_PUP #define PF_CHAOS AF_CHAOS #define PF_NETBIOS AF_NETBIOS #define PF_ISO AF_ISO #define PF_OSI AF_ISO #define PF_ECMA AF_ECMA #define PF_DATAKIT AF_DATAKIT #define PF_CCITT AF_CCITT #define PF_SNA AF_SNA #define PF_DECnet AF_DECnet #define PF_DLI AF_DLI #define PF_LAT AF_LAT #define PF_HYLINK AF_HYLINK #define PF_APPLETALK AF_APPLETALK #define PF_ROUTE AF_ROUTE #define PF_LINK AF_LINK #define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */ #define PF_COIP AF_COIP #define PF_CNT AF_CNT #define PF_SIP AF_SIP #define PF_IPX AF_IPX #define PF_RTIP pseudo_AF_RTIP /* same format as AF_INET */ #define PF_PIP pseudo_AF_PIP #define PF_ISDN AF_ISDN #define PF_KEY pseudo_AF_KEY #define PF_INET6 AF_INET6 #define PF_NATM AF_NATM #define PF_ATM AF_ATM #define PF_NETGRAPH AF_NETGRAPH #define PF_SLOW AF_SLOW #define PF_SCLUSTER AF_SCLUSTER #define PF_ARP AF_ARP #define PF_BLUETOOTH AF_BLUETOOTH #define PF_IEEE80211 AF_IEEE80211 #define PF_INET_SDP AF_INET_SDP #define PF_INET6_SDP AF_INET6_SDP #define PF_MAX AF_MAX /* * Definitions for network related sysctl, CTL_NET. * * Second level is protocol family. * Third level is protocol number. * * Further levels are defined by the individual families. */ /* * PF_ROUTE - Routing table * * Three additional levels are defined: * Fourth: address family, 0 is wildcard * Fifth: type of info, defined below * Sixth: flag(s) to mask with for NET_RT_FLAGS */ #define NET_RT_DUMP 1 /* dump; may limit to a.f. */ #define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */ #define NET_RT_IFLIST 3 /* survey interface list */ #define NET_RT_IFMALIST 4 /* return multicast address list */ #define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en * versions of msghdr structs. */ #endif /* __BSD_VISIBLE */ /* * Maximum queue length specifiable by listen. */ #define SOMAXCONN 128 /* * Message header for recvmsg and sendmsg calls. * Used value-result for recvmsg, value only for sendmsg. */ struct msghdr { void *msg_name; /* optional address */ socklen_t msg_namelen; /* size of address */ struct iovec *msg_iov; /* scatter/gather array */ int msg_iovlen; /* # elements in msg_iov */ void *msg_control; /* ancillary data, see below */ socklen_t msg_controllen; /* ancillary data buffer len */ int msg_flags; /* flags on received message */ }; #define MSG_OOB 0x1 /* process out-of-band data */ #define MSG_PEEK 0x2 /* peek at incoming message */ #define MSG_DONTROUTE 0x4 /* send without using routing tables */ #define MSG_EOR 0x8 /* data completes record */ #define MSG_TRUNC 0x10 /* data discarded before delivery */ #define MSG_CTRUNC 0x20 /* control data lost before delivery */ #define MSG_WAITALL 0x40 /* wait for full request or error */ #if __POSIX_VISIBLE >= 200809 #define MSG_NOSIGNAL 0x20000 /* do not generate SIGPIPE on EOF */ #endif #if __BSD_VISIBLE #define MSG_DONTWAIT 0x80 /* this message should be nonblocking */ #define MSG_EOF 0x100 /* data completes connection */ #define MSG_NOTIFICATION 0x2000 /* SCTP notification */ #define MSG_NBIO 0x4000 /* FIONBIO mode, used by fifofs */ #define MSG_COMPAT 0x8000 /* used in sendit() */ #define MSG_CMSG_CLOEXEC 0x40000 /* make received fds close-on-exec */ #define MSG_WAITFORONE 0x80000 /* for recvmmsg() */ #endif #ifdef _KERNEL #define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */ #endif /* * Header for ancillary data objects in msg_control buffer. * Used for additional information with/about a datagram * not expressible by flags. The format is a sequence * of message elements headed by cmsghdr structures. */ struct cmsghdr { socklen_t cmsg_len; /* data byte count, including hdr */ int cmsg_level; /* originating protocol */ int cmsg_type; /* protocol-specific type */ /* followed by u_char cmsg_data[]; */ }; #if __BSD_VISIBLE /* * While we may have more groups than this, the cmsgcred struct must * be able to fit in an mbuf and we have historically supported a * maximum of 16 groups. */ #define CMGROUP_MAX 16 /* * Credentials structure, used to verify the identity of a peer * process that has sent us a message. This is allocated by the * peer process but filled in by the kernel. This prevents the * peer from lying about its identity. (Note that cmcred_groups[0] * is the effective GID.) */ struct cmsgcred { pid_t cmcred_pid; /* PID of sending process */ uid_t cmcred_uid; /* real UID of sending process */ uid_t cmcred_euid; /* effective UID of sending process */ gid_t cmcred_gid; /* real GID of sending process */ short cmcred_ngroups; /* number or groups */ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */ }; /* * Socket credentials. */ struct sockcred { uid_t sc_uid; /* real user id */ uid_t sc_euid; /* effective user id */ gid_t sc_gid; /* real group id */ gid_t sc_egid; /* effective group id */ int sc_ngroups; /* number of supplemental groups */ gid_t sc_groups[1]; /* variable length */ }; /* * Compute size of a sockcred structure with groups. */ #define SOCKCREDSIZE(ngrps) \ (sizeof(struct sockcred) + (sizeof(gid_t) * ((ngrps) - 1))) #endif /* __BSD_VISIBLE */ /* given pointer to struct cmsghdr, return pointer to data */ #define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ _ALIGN(sizeof(struct cmsghdr))) /* given pointer to struct cmsghdr, return pointer to next cmsghdr */ #define CMSG_NXTHDR(mhdr, cmsg) \ ((char *)(cmsg) == NULL ? CMSG_FIRSTHDR(mhdr) : \ ((char *)(cmsg) + _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len) + \ _ALIGN(sizeof(struct cmsghdr)) > \ (char *)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \ (struct cmsghdr *)0 : \ (struct cmsghdr *)(void *)((char *)(cmsg) + \ _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len))) /* * RFC 2292 requires to check msg_controllen, in case that the kernel returns * an empty list for some reasons. */ #define CMSG_FIRSTHDR(mhdr) \ ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ (struct cmsghdr *)(mhdr)->msg_control : \ (struct cmsghdr *)NULL) #if __BSD_VISIBLE /* RFC 2292 additions */ #define CMSG_SPACE(l) (_ALIGN(sizeof(struct cmsghdr)) + _ALIGN(l)) #define CMSG_LEN(l) (_ALIGN(sizeof(struct cmsghdr)) + (l)) #endif #ifdef _KERNEL #define CMSG_ALIGN(n) _ALIGN(n) #endif /* "Socket"-level control message types: */ #define SCM_RIGHTS 0x01 /* access rights (array of int) */ #if __BSD_VISIBLE #define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */ #define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ #define SCM_BINTIME 0x04 /* timestamp (struct bintime) */ #endif #if __BSD_VISIBLE /* * 4.3 compat sockaddr, move to compat file later */ struct osockaddr { unsigned short sa_family; /* address family */ char sa_data[14]; /* up to 14 bytes of direct address */ }; /* * 4.3-compat message header (move to compat file later). */ struct omsghdr { char *msg_name; /* optional address */ int msg_namelen; /* size of address */ struct iovec *msg_iov; /* scatter/gather array */ int msg_iovlen; /* # elements in msg_iov */ char *msg_accrights; /* access rights sent/received */ int msg_accrightslen; }; #endif /* * howto arguments for shutdown(2), specified by Posix.1g. */ #define SHUT_RD 0 /* shut down the reading side */ #define SHUT_WR 1 /* shut down the writing side */ #define SHUT_RDWR 2 /* shut down both sides */ #if __BSD_VISIBLE /* for SCTP */ /* we cheat and use the SHUT_XX defines for these */ #define PRU_FLUSH_RD SHUT_RD #define PRU_FLUSH_WR SHUT_WR #define PRU_FLUSH_RDWR SHUT_RDWR #endif #if __BSD_VISIBLE /* * sendfile(2) header/trailer struct */ struct sf_hdtr { struct iovec *headers; /* pointer to an array of header struct iovec's */ int hdr_cnt; /* number of header iovec's */ struct iovec *trailers; /* pointer to an array of trailer struct iovec's */ int trl_cnt; /* number of trailer iovec's */ }; /* * Sendfile-specific flag(s) */ #define SF_NODISKIO 0x00000001 #define SF_MNOWAIT 0x00000002 /* obsolete */ #define SF_SYNC 0x00000004 #define SF_NOCACHE 0x00000010 #define SF_FLAGS(rh, flags) (((rh) << 16) | (flags)) #ifdef _KERNEL #define SFK_COMPAT 0x00000001 #define SF_READAHEAD(flags) ((flags) >> 16) #endif /* _KERNEL */ /* * Sendmmsg/recvmmsg specific structure(s) */ struct mmsghdr { struct msghdr msg_hdr; /* message header */ ssize_t msg_len; /* message length */ }; #endif /* __BSD_VISIBLE */ #ifndef _KERNEL #include __BEGIN_DECLS int accept(int, struct sockaddr * __restrict, socklen_t * __restrict); int bind(int, const struct sockaddr *, socklen_t); int connect(int, const struct sockaddr *, socklen_t); #if __BSD_VISIBLE int accept4(int, struct sockaddr * __restrict, socklen_t * __restrict, int); int bindat(int, int, const struct sockaddr *, socklen_t); int connectat(int, int, const struct sockaddr *, socklen_t); #endif int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict); int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict); int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict); int listen(int, int); ssize_t recv(int, void *, size_t, int); ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); ssize_t recvmsg(int, struct msghdr *, int); #if __BSD_VISIBLE struct timespec; ssize_t recvmmsg(int, struct mmsghdr * __restrict, size_t, int, const struct timespec * __restrict); #endif ssize_t send(int, const void *, size_t, int); ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); ssize_t sendmsg(int, const struct msghdr *, int); #if __BSD_VISIBLE int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); ssize_t sendmmsg(int, struct mmsghdr * __restrict, size_t, int); int setfib(int); #endif int setsockopt(int, int, int, const void *, socklen_t); int shutdown(int, int); int sockatmark(int); int socket(int, int, int); int socketpair(int, int, int, int *); __END_DECLS #endif /* !_KERNEL */ #ifdef _KERNEL struct socket; struct tcpcb *so_sototcpcb(struct socket *so); struct inpcb *so_sotoinpcb(struct socket *so); struct sockbuf *so_sockbuf_snd(struct socket *); struct sockbuf *so_sockbuf_rcv(struct socket *); int so_state_get(const struct socket *); void so_state_set(struct socket *, int); int so_options_get(const struct socket *); void so_options_set(struct socket *, int); int so_error_get(const struct socket *); void so_error_set(struct socket *, int); int so_linger_get(const struct socket *); void so_linger_set(struct socket *, int); struct protosw *so_protosw_get(const struct socket *); void so_protosw_set(struct socket *, struct protosw *); void so_sorwakeup_locked(struct socket *so); void so_sowwakeup_locked(struct socket *so); void so_sorwakeup(struct socket *so); void so_sowwakeup(struct socket *so); void so_lock(struct socket *so); void so_unlock(struct socket *so); void so_listeners_apply_all(struct socket *so, void (*func)(struct socket *, void *), void *arg); #endif #endif /* !_SYS_SOCKET_H_ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)stat.h 8.12 (Berkeley) 6/16/95 * $FreeBSD$ */ #ifndef _SYS_STAT_H_ #define _SYS_STAT_H_ #include #include #include #ifndef _BLKSIZE_T_DECLARED typedef __blksize_t blksize_t; #define _BLKSIZE_T_DECLARED #endif #ifndef _BLKCNT_T_DECLARED typedef __blkcnt_t blkcnt_t; #define _BLKCNT_T_DECLARED #endif #ifndef _DEV_T_DECLARED typedef __dev_t dev_t; #define _DEV_T_DECLARED #endif #ifndef _FFLAGS_T_DECLARED typedef __fflags_t fflags_t; #define _FFLAGS_T_DECLARED #endif #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED #endif #ifndef _INO_T_DECLARED typedef __ino_t ino_t; #define _INO_T_DECLARED #endif #ifndef _MODE_T_DECLARED typedef __mode_t mode_t; #define _MODE_T_DECLARED #endif #ifndef _NLINK_T_DECLARED typedef __nlink_t nlink_t; #define _NLINK_T_DECLARED #endif #ifndef _OFF_T_DECLARED typedef __off_t off_t; #define _OFF_T_DECLARED #endif #ifndef _UID_T_DECLARED typedef __uid_t uid_t; #define _UID_T_DECLARED #endif #if !defined(_KERNEL) && __BSD_VISIBLE /* * XXX We get miscellaneous namespace pollution with this. */ #include #endif #ifdef _KERNEL struct ostat { __uint16_t st_dev; /* inode's device */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number of hard links */ __uint16_t st_uid; /* user ID of the file's owner */ __uint16_t st_gid; /* group ID of the file's group */ __uint16_t st_rdev; /* device type */ __int32_t st_size; /* file size, in bytes */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ __int32_t st_blksize; /* optimal blocksize for I/O */ __int32_t st_blocks; /* blocks allocated for file */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ }; #endif struct stat { __dev_t st_dev; /* inode's device */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner */ gid_t st_gid; /* group ID of the file's group */ __dev_t st_rdev; /* device type */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ __int32_t st_lspare; struct timespec st_birthtim; /* time of file creation */ /* * Explicitly pad st_birthtim to 16 bytes so that the size of * struct stat is backwards compatible. We use bitfields instead * of an array of chars so that this doesn't require a C99 compiler * to compile if the size of the padding is 0. We use 2 bitfields * to cover up to 64 bits on 32-bit machines. We assume that * CHAR_BIT is 8... */ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); }; #ifdef _KERNEL struct nstat { __dev_t st_dev; /* inode's device */ ino_t st_ino; /* inode's number */ __uint32_t st_mode; /* inode protection mode */ __uint32_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner */ gid_t st_gid; /* group ID of the file's group */ __dev_t st_rdev; /* device type */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ struct timespec st_birthtim; /* time of file creation */ /* * See above about the following padding. */ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); }; #endif #ifndef _KERNEL #define st_atime st_atim.tv_sec #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec #if __BSD_VISIBLE #define st_birthtime st_birthtim.tv_sec #endif /* For compatibility. */ #if __BSD_VISIBLE #define st_atimespec st_atim #define st_mtimespec st_mtim #define st_ctimespec st_ctim #define st_birthtimespec st_birthtim #endif #endif /* !_KERNEL */ #define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ #if __BSD_VISIBLE #define S_ISTXT 0001000 /* sticky bit */ #endif #define S_IRWXU 0000700 /* RWX mask for owner */ #define S_IRUSR 0000400 /* R for owner */ #define S_IWUSR 0000200 /* W for owner */ #define S_IXUSR 0000100 /* X for owner */ #if __BSD_VISIBLE #define S_IREAD S_IRUSR #define S_IWRITE S_IWUSR #define S_IEXEC S_IXUSR #endif #define S_IRWXG 0000070 /* RWX mask for group */ #define S_IRGRP 0000040 /* R for group */ #define S_IWGRP 0000020 /* W for group */ #define S_IXGRP 0000010 /* X for group */ #define S_IRWXO 0000007 /* RWX mask for other */ #define S_IROTH 0000004 /* R for other */ #define S_IWOTH 0000002 /* W for other */ #define S_IXOTH 0000001 /* X for other */ #if __XSI_VISIBLE #define S_IFMT 0170000 /* type of file mask */ #define S_IFIFO 0010000 /* named pipe (fifo) */ #define S_IFCHR 0020000 /* character special */ #define S_IFDIR 0040000 /* directory */ #define S_IFBLK 0060000 /* block special */ #define S_IFREG 0100000 /* regular */ #define S_IFLNK 0120000 /* symbolic link */ #define S_IFSOCK 0140000 /* socket */ #define S_ISVTX 0001000 /* save swapped text even after use */ #endif #if __BSD_VISIBLE #define S_IFWHT 0160000 /* whiteout */ #endif #define S_ISDIR(m) (((m) & 0170000) == 0040000) /* directory */ #define S_ISCHR(m) (((m) & 0170000) == 0020000) /* char special */ #define S_ISBLK(m) (((m) & 0170000) == 0060000) /* block special */ #define S_ISREG(m) (((m) & 0170000) == 0100000) /* regular file */ #define S_ISFIFO(m) (((m) & 0170000) == 0010000) /* fifo or socket */ #if __POSIX_VISIBLE >= 200112 #define S_ISLNK(m) (((m) & 0170000) == 0120000) /* symbolic link */ #define S_ISSOCK(m) (((m) & 0170000) == 0140000) /* socket */ #endif #if __BSD_VISIBLE #define S_ISWHT(m) (((m) & 0170000) == 0160000) /* whiteout */ #endif #if __BSD_VISIBLE #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */ /* 7777 */ #define ALLPERMS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) /* 0666 */ #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) #define S_BLKSIZE 512 /* block size used in the stat struct */ /* * Definitions of flags stored in file flags word. * * Super-user and owner changeable flags. */ #define UF_SETTABLE 0x0000ffff /* mask of owner changeable flags */ #define UF_NODUMP 0x00000001 /* do not dump file */ #define UF_IMMUTABLE 0x00000002 /* file may not be changed */ #define UF_APPEND 0x00000004 /* writes to file may only append */ #define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */ #define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */ /* * These two bits are defined in MacOS X. They are not currently used in * FreeBSD. */ #if 0 #define UF_COMPRESSED 0x00000020 /* file is compressed */ #define UF_TRACKED 0x00000040 /* renames and deletes are tracked */ #endif #define UF_SYSTEM 0x00000080 /* Windows system file bit */ #define UF_SPARSE 0x00000100 /* sparse file */ #define UF_OFFLINE 0x00000200 /* file is offline */ #define UF_REPARSE 0x00000400 /* Windows reparse point file bit */ #define UF_ARCHIVE 0x00000800 /* file needs to be archived */ #define UF_READONLY 0x00001000 /* Windows readonly file bit */ /* This is the same as the MacOS X definition of UF_HIDDEN. */ #define UF_HIDDEN 0x00008000 /* file is hidden */ /* * Super-user changeable flags. */ #define SF_SETTABLE 0xffff0000 /* mask of superuser changeable flags */ #define SF_ARCHIVED 0x00010000 /* file is archived */ #define SF_IMMUTABLE 0x00020000 /* file may not be changed */ #define SF_APPEND 0x00040000 /* writes to file may only append */ #define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */ #define SF_SNAPSHOT 0x00200000 /* snapshot inode */ #ifdef _KERNEL /* * Shorthand abbreviations of above. */ #define OPAQUE (UF_OPAQUE) #define APPEND (UF_APPEND | SF_APPEND) #define IMMUTABLE (UF_IMMUTABLE | SF_IMMUTABLE) #define NOUNLINK (UF_NOUNLINK | SF_NOUNLINK) #endif #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 200809 #define UTIME_NOW -1 #define UTIME_OMIT -2 #endif #ifndef _KERNEL __BEGIN_DECLS #if __BSD_VISIBLE int chflags(const char *, unsigned long); int chflagsat(int, const char *, unsigned long, int); #endif int chmod(const char *, mode_t); #if __BSD_VISIBLE int fchflags(int, unsigned long); #endif #if __POSIX_VISIBLE >= 200112 int fchmod(int, mode_t); #endif #if __POSIX_VISIBLE >= 200809 int fchmodat(int, const char *, mode_t, int); int futimens(int fd, const struct timespec times[2]); int utimensat(int fd, const char *path, const struct timespec times[2], int flag); #endif int fstat(int, struct stat *); #if __BSD_VISIBLE int lchflags(const char *, unsigned long); int lchmod(const char *, mode_t); #endif #if __POSIX_VISIBLE >= 200112 int lstat(const char * __restrict, struct stat * __restrict); #endif int mkdir(const char *, mode_t); int mkfifo(const char *, mode_t); #if !defined(_MKNOD_DECLARED) && __XSI_VISIBLE int mknod(const char *, mode_t, dev_t); #define _MKNOD_DECLARED #endif int stat(const char * __restrict, struct stat * __restrict); mode_t umask(mode_t); #if __POSIX_VISIBLE >= 200809 int fstatat(int, const char *, struct stat *, int); int mkdirat(int, const char *, mode_t); int mkfifoat(int, const char *, mode_t); #endif #if __XSI_VISIBLE >= 700 int mknodat(int, const char *, mode_t, dev_t); #endif __END_DECLS #endif /* !_KERNEL */ #endif /* !_SYS_STAT_H_ */ /*- * Copyright (c) 2002 Maxime Henrion * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_STDDEF_H_ #define _SYS_STDDEF_H_ #include #include #include #ifndef _PTRDIFF_T_DECLARED typedef __ptrdiff_t ptrdiff_t; #define _PTRDIFF_T_DECLARED #endif #define offsetof(type, field) __offsetof(type, field) #endif /* !_SYS_STDDEF_H_ */ /*- * Copyright (c) 2001 Mike Barcroft * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _SYS_STDINT_H_ #define _SYS_STDINT_H_ #include #include #include #include typedef __int_least8_t int_least8_t; typedef __int_least16_t int_least16_t; typedef __int_least32_t int_least32_t; typedef __int_least64_t int_least64_t; typedef __uint_least8_t uint_least8_t; typedef __uint_least16_t uint_least16_t; typedef __uint_least32_t uint_least32_t; typedef __uint_least64_t uint_least64_t; typedef __int_fast8_t int_fast8_t; typedef __int_fast16_t int_fast16_t; typedef __int_fast32_t int_fast32_t; typedef __int_fast64_t int_fast64_t; typedef __uint_fast8_t uint_fast8_t; typedef __uint_fast16_t uint_fast16_t; typedef __uint_fast32_t uint_fast32_t; typedef __uint_fast64_t uint_fast64_t; /* GNU and Darwin define this and people seem to think it's portable */ #if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX) #define __WORDSIZE 64 #else #define __WORDSIZE 32 #endif /* Limits of wchar_t. */ #define WCHAR_MIN __WCHAR_MIN #define WCHAR_MAX __WCHAR_MAX #endif /* !_SYS_STDINT_H_ */ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)syslimits.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _SYS_SYSLIMITS_H_ #define _SYS_SYSLIMITS_H_ #if !defined(_KERNEL) && !defined(_LIMITS_H_) && !defined(_SYS_PARAM_H_) #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif #ifdef __CC_SUPPORTS_WARNING #warning "No user-serviceable parts inside." #endif #endif /* * Do not add any new variables here. (See the comment at the end of * the file for why.) */ #define ARG_MAX 262144 /* max bytes for an exec function */ #ifndef CHILD_MAX #define CHILD_MAX 40 /* max simultaneous processes */ #endif #define LINK_MAX 32767 /* max file link count */ #define MAX_CANON 255 /* max bytes in term canon input line */ #define MAX_INPUT 255 /* max bytes in terminal input */ #define NAME_MAX 255 /* max bytes in a file name */ #ifndef NGROUPS_MAX #define NGROUPS_MAX 1023 /* max supplemental group id's */ #endif #ifndef OPEN_MAX #define OPEN_MAX 64 /* max open files per process */ #endif #define PATH_MAX 1024 /* max bytes in pathname */ #define PIPE_BUF 512 /* max bytes for atomic pipe writes */ #define IOV_MAX 1024 /* max elements in i/o vector */ /* * We leave the following values undefined to force applications to either * assume conservative values or call sysconf() to get the current value. * * HOST_NAME_MAX * * (We should do this for most of the values currently defined here, * but many programs are not prepared to deal with this yet.) */ #endif /* * Compatibility header for illumos. */ #include #include /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ /* All Rights Reserved */ #ifndef _SYS_TEM_H #define _SYS_TEM_H #ifdef __cplusplus extern "C" { #endif #include #include #include typedef uint8_t text_color_t; typedef struct __tem_modechg_cb_arg *tem_modechg_cb_arg_t; typedef void (*tem_modechg_cb_t) (tem_modechg_cb_arg_t arg); typedef struct __tem_vt_state *tem_vt_state_t; /* * tems_* fuctions mean that they just operate on the common soft state * (tem_state_t), and tem_* functions mean that they operate on the * per-tem structure (tem_vt_state). */ int tems_cls(struct vis_consclear *); void tems_display(struct vis_consdisplay *); void tems_copy(struct vis_conscopy *); void tems_cursor(struct vis_conscursor *); int tem_initialized(tem_vt_state_t); tem_vt_state_t tem_init(void); int tem_info_init(struct console *); void tem_write(tem_vt_state_t, uint8_t *, ssize_t); void tem_get_size(uint16_t *, uint16_t *, uint16_t *, uint16_t *); void tem_save_state(void); void tem_register_modechg_cb(tem_modechg_cb_t, tem_modechg_cb_arg_t); void tem_activate(tem_vt_state_t, bool); void tem_switch(tem_vt_state_t, tem_vt_state_t); void tem_get_colors(tem_vt_state_t, text_color_t *, text_color_t *); #ifdef __cplusplus } #endif #endif /* _SYS_TEM_H */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ /* All Rights Reserved */ #ifndef _SYS_TEM_H #define _SYS_TEM_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include /* * Definitions for ANSI x3.64 terminal control language parser. * With UTF-8 support we use 32-bit value for Unicode codepoints. * * However, as we only need 21 bits for unicode char, we will use the * rest of the bits for attributes, so we can save memory and * have combined attribute+char in screen buffer. This will also allow us * to keep better track about attributes and apply other optimizations. * * Bits Meaning * 0-20 char * 21-31 attributes */ #define TEM_ATTR_MASK 0x7FF #define TEM_CHAR(c) ((c) & 0x1fffff) #define TEM_CHAR_ATTR(c) (((c) >> 21) & TEM_ATTR_MASK) #define TEM_ATTR(c) (((c) & TEM_ATTR_MASK) << 21) #define TEM_ATTR_ISSET(c, a) ((TEM_CHAR_ATTR(c) & (a)) == (a)) #define TEM_MAXPARAMS 32 /* maximum number of ANSI paramters */ #define TEM_MAXFKEY 30 /* max length of function key with Q */ #define MAX_TEM 2 /* max number of loadable terminal emulators */ #define TEM_SCROLL_UP 0 #define TEM_SCROLL_DOWN 1 #define TEM_SHIFT_LEFT 0 #define TEM_SHIFT_RIGHT 1 /* Attributes 0-0x7ff */ #define TEM_ATTR_NORMAL 0x0000 #define TEM_ATTR_REVERSE 0x0001 #define TEM_ATTR_BOLD 0x0002 #define TEM_ATTR_BLINK 0x0004 #define TEM_ATTR_UNDERLINE 0x0008 #define TEM_ATTR_SCREEN_REVERSE 0x0010 #define TEM_ATTR_BRIGHT_FG 0x0020 #define TEM_ATTR_BRIGHT_BG 0x0040 #define TEM_ATTR_TRANSPARENT 0x0080 #define TEM_ATTR_IMAGE 0x0100 #define TEM_ATTR_RGB_FG 0x0200 #define TEM_ATTR_RGB_BG 0x0400 #define ANSI_COLOR_BLACK 0 #define ANSI_COLOR_RED 1 #define ANSI_COLOR_GREEN 2 #define ANSI_COLOR_YELLOW 3 #define ANSI_COLOR_BLUE 4 #define ANSI_COLOR_MAGENTA 5 #define ANSI_COLOR_CYAN 6 #define ANSI_COLOR_WHITE 7 #define TEM_TEXT_WHITE 0 #define TEM_TEXT_BLACK 1 #define TEM_TEXT_BLACK24_RED 0x00 #define TEM_TEXT_BLACK24_GREEN 0x00 #define TEM_TEXT_BLACK24_BLUE 0x00 #define TEM_TEXT_WHITE24_RED 0xff #define TEM_TEXT_WHITE24_GREEN 0xff #define TEM_TEXT_WHITE24_BLUE 0xff #define A_STATE_START 0 #define A_STATE_ESC 1 #define A_STATE_CSI 2 #define A_STATE_CSI_QMARK 3 #define A_STATE_CSI_EQUAL 4 /* * Default number of rows and columns */ #define TEM_DEFAULT_ROWS 25 #define TEM_DEFAULT_COLS 80 /* * Default foreground/background color */ #if !defined(DEFAULT_ANSI_FOREGROUND) && !defined(DEFAULT_ANSI_BACKGROUND) #define DEFAULT_ANSI_FOREGROUND ANSI_COLOR_BLACK #define DEFAULT_ANSI_BACKGROUND ANSI_COLOR_WHITE #endif #define BUF_LEN 160 /* Two lines of data can be processed at a time */ typedef uint32_t tem_char_t; /* 32bit char to support UTF-8 */ typedef union { uint32_t n; struct bgra { uint8_t b; uint8_t g; uint8_t r; uint8_t a; } rgb; } text_color_t; typedef uint16_t text_attr_t; typedef struct tem_color { text_color_t fg_color; text_color_t bg_color; text_attr_t a_flags; } tem_color_t; struct tem_pix_pos { screen_pos_t x; screen_pos_t y; }; struct tem_char_pos { screen_pos_t col; screen_pos_t row; }; struct tem_size { screen_size_t width; screen_size_t height; }; /* Combined color and 32bit tem char */ typedef struct term_char { text_color_t tc_fg_color; text_color_t tc_bg_color; tem_char_t tc_char; } term_char_t; /* * Values for tvs_stateflags. */ #define TVS_AUTOWRAP 0x00000001 /* autowrap is on by default */ #define TVS_WRAPPED 0x00000002 /* line wrap in progress */ /* * State structure for each virtual terminal emulator */ struct tem_vt_state { uint8_t tvs_fbmode; /* framebuffer mode */ uint8_t tvs_alpha; /* rgb alpha channel */ text_attr_t tvs_flags; /* flags for this x3.64 terminal */ int tvs_state; /* state in output esc seq processing */ uint_t tvs_stateflags; /* state of some features */ bool tvs_gotparam; /* does output esc seq have a param */ int tvs_curparam; /* current param # of output esc seq */ int tvs_paramval; /* value of current param */ int tvs_params[TEM_MAXPARAMS]; /* parameters of output esc seq */ screen_pos_t *tvs_tabs; /* tab stops */ size_t tvs_maxtab; /* maximum number of tab stops */ size_t tvs_ntabs; /* number of tabs used */ int tvs_nscroll; /* number of lines to scroll */ struct tem_char_pos tvs_s_cursor; /* start cursor position */ struct tem_char_pos tvs_c_cursor; /* current cursor position */ struct tem_char_pos tvs_r_cursor; /* remembered cursor position */ term_char_t *tvs_outbuf; /* place to keep incomplete lines */ int tvs_outindex; /* index into a_outbuf */ void *tvs_pix_data; /* pointer to tmp bitmap area */ unsigned tvs_pix_data_size; text_color_t tvs_fg_color; /* console foreground */ text_color_t tvs_bg_color; /* console background */ int tvs_first_line; /* kernel console output begins */ term_char_t *tvs_screen_buf; /* whole screen buffer */ unsigned tvs_utf8_left; /* UTF-8 code points */ tem_char_t tvs_utf8_partial; /* UTF-8 char being completed */ bool tvs_isactive; bool tvs_initialized; /* initialization flag */ bool tvs_cursor_hidden; list_node_t tvs_list_node; }; typedef struct tem_callbacks { void (*tsc_display)(struct tem_vt_state *, term_char_t *, int, screen_pos_t, screen_pos_t); void (*tsc_copy)(struct tem_vt_state *, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t); void (*tsc_cursor)(struct tem_vt_state *, short); void (*tsc_bit2pix)(struct tem_vt_state *, term_char_t *); void (*tsc_cls)(struct tem_vt_state *, int, screen_pos_t, screen_pos_t); } tem_callbacks_t; typedef struct __tem_modechg_cb_arg *tem_modechg_cb_arg_t; typedef void (*tem_modechg_cb_t) (tem_modechg_cb_arg_t arg); typedef struct __tem_vt_state *tem_vt_state_t; /* * common term soft state structure shared by all virtual terminal emulators */ typedef struct tem_state { struct console *ts_hdl; /* Framework handle for dev */ screen_size_t ts_linebytes; /* Layered on bytes per scan line */ int ts_display_mode; /* What mode we are in */ struct tem_size ts_c_dimension; /* window dimensions in characters */ struct tem_size ts_p_dimension; /* screen dimensions in pixels */ struct tem_pix_pos ts_p_offset; /* pix offset to center the display */ unsigned ts_pix_data_size; /* size of bitmap data areas */ int ts_pdepth; /* pixel depth */ struct font ts_font; /* font table */ bool update_font; /* flag the font change */ tem_callbacks_t *ts_callbacks; /* internal output functions */ int ts_initialized; /* initialization flag */ tem_modechg_cb_t ts_modechg_cb; tem_modechg_cb_arg_t ts_modechg_arg; color_map_fn_t ts_color_map; tem_color_t ts_init_color; /* initial color and attributes */ struct tem_vt_state *ts_active; list_t ts_list; /* chain of all tems */ } tem_state_t; extern tem_state_t tems; /* * tems_* fuctions mean that they just operate on the common soft state * (tem_state_t), and tem_* functions mean that they operate on the * per-tem structure (tem_vt_state). All "safe" interfaces are in tem_safe.c. */ int tems_cls(struct vis_consclear *); void tems_display(struct vis_consdisplay *); void tems_copy(struct vis_conscopy *); void tems_cursor(struct vis_conscursor *); int tem_initialized(tem_vt_state_t); tem_vt_state_t tem_init(void); int tem_info_init(struct console *); void tem_write(tem_vt_state_t, uint8_t *, ssize_t); void tem_get_size(uint16_t *, uint16_t *, uint16_t *, uint16_t *); void tem_save_state(void); void tem_register_modechg_cb(tem_modechg_cb_t, tem_modechg_cb_arg_t); void tem_activate(tem_vt_state_t, bool); void tem_get_colors(tem_vt_state_t, text_color_t *, text_color_t *); void tem_image_display(struct tem_vt_state *, screen_pos_t, screen_pos_t, screen_pos_t, screen_pos_t); #ifdef __cplusplus } #endif #endif /* _SYS_TEM_H */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)time.h 8.5 (Berkeley) 5/4/95 * $FreeBSD$ */ #ifndef _SYS_TIME_H_ #define _SYS_TIME_H_ #include #include #include struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of dst correction */ }; #define DST_NONE 0 /* not on dst */ #define DST_USA 1 /* USA style dst */ #define DST_AUST 2 /* Australian style dst */ #define DST_WET 3 /* Western European dst */ #define DST_MET 4 /* Middle European dst */ #define DST_EET 5 /* Eastern European dst */ #define DST_CAN 6 /* Canada */ #if __BSD_VISIBLE struct bintime { time_t sec; uint64_t frac; }; static __inline void bintime_addx(struct bintime *_bt, uint64_t _x) { uint64_t _u; _u = _bt->frac; _bt->frac += _x; if (_u > _bt->frac) _bt->sec++; } static __inline void bintime_add(struct bintime *_bt, const struct bintime *_bt2) { uint64_t _u; _u = _bt->frac; _bt->frac += _bt2->frac; if (_u > _bt->frac) _bt->sec++; _bt->sec += _bt2->sec; } static __inline void bintime_sub(struct bintime *_bt, const struct bintime *_bt2) { uint64_t _u; _u = _bt->frac; _bt->frac -= _bt2->frac; if (_u < _bt->frac) _bt->sec--; _bt->sec -= _bt2->sec; } static __inline void bintime_mul(struct bintime *_bt, u_int _x) { uint64_t _p1, _p2; _p1 = (_bt->frac & 0xffffffffull) * _x; _p2 = (_bt->frac >> 32) * _x + (_p1 >> 32); _bt->sec *= _x; _bt->sec += (_p2 >> 32); _bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull); } static __inline void bintime_shift(struct bintime *_bt, int _exp) { if (_exp > 0) { _bt->sec <<= _exp; _bt->sec |= _bt->frac >> (64 - _exp); _bt->frac <<= _exp; } else if (_exp < 0) { _bt->frac >>= -_exp; _bt->frac |= (uint64_t)_bt->sec << (64 + _exp); _bt->sec >>= -_exp; } } #define bintime_clear(a) ((a)->sec = (a)->frac = 0) #define bintime_isset(a) ((a)->sec || (a)->frac) #define bintime_cmp(a, b, cmp) \ (((a)->sec == (b)->sec) ? \ ((a)->frac cmp (b)->frac) : \ ((a)->sec cmp (b)->sec)) #define SBT_1S ((sbintime_t)1 << 32) #define SBT_1M (SBT_1S * 60) #define SBT_1MS (SBT_1S / 1000) #define SBT_1US (SBT_1S / 1000000) #define SBT_1NS (SBT_1S / 1000000000) #define SBT_MAX 0x7fffffffffffffffLL static __inline int sbintime_getsec(sbintime_t _sbt) { return (_sbt >> 32); } static __inline sbintime_t bttosbt(const struct bintime _bt) { return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32)); } static __inline struct bintime sbttobt(sbintime_t _sbt) { struct bintime _bt; _bt.sec = _sbt >> 32; _bt.frac = _sbt << 32; return (_bt); } /*- * Background information: * * When converting between timestamps on parallel timescales of differing * resolutions it is historical and scientific practice to round down rather * than doing 4/5 rounding. * * The date changes at midnight, not at noon. * * Even at 15:59:59.999999999 it's not four'o'clock. * * time_second ticks after N.999999999 not after N.4999999999 */ static __inline void bintime2timespec(const struct bintime *_bt, struct timespec *_ts) { _ts->tv_sec = _bt->sec; _ts->tv_nsec = ((uint64_t)1000000000 * (uint32_t)(_bt->frac >> 32)) >> 32; } static __inline void timespec2bintime(const struct timespec *_ts, struct bintime *_bt) { _bt->sec = _ts->tv_sec; /* 18446744073 = int(2^64 / 1000000000) */ _bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL; } static __inline void bintime2timeval(const struct bintime *_bt, struct timeval *_tv) { _tv->tv_sec = _bt->sec; _tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32; } static __inline void timeval2bintime(const struct timeval *_tv, struct bintime *_bt) { _bt->sec = _tv->tv_sec; /* 18446744073709 = int(2^64 / 1000000) */ _bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL; } static __inline struct timespec sbttots(sbintime_t _sbt) { struct timespec _ts; _ts.tv_sec = _sbt >> 32; _ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32; return (_ts); } static __inline sbintime_t tstosbt(struct timespec _ts) { return (((sbintime_t)_ts.tv_sec << 32) + (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32)); } static __inline struct timeval sbttotv(sbintime_t _sbt) { struct timeval _tv; _tv.tv_sec = _sbt >> 32; _tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32; return (_tv); } static __inline sbintime_t tvtosbt(struct timeval _tv) { return (((sbintime_t)_tv.tv_sec << 32) + (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32)); } #endif /* __BSD_VISIBLE */ #ifdef _KERNEL /* Operations on timespecs */ #define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) #define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) #define timespeccmp(tvp, uvp, cmp) \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \ ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ ((tvp)->tv_sec cmp (uvp)->tv_sec)) #define timespecadd(vvp, uvp) \ do { \ (vvp)->tv_sec += (uvp)->tv_sec; \ (vvp)->tv_nsec += (uvp)->tv_nsec; \ if ((vvp)->tv_nsec >= 1000000000) { \ (vvp)->tv_sec++; \ (vvp)->tv_nsec -= 1000000000; \ } \ } while (0) #define timespecsub(vvp, uvp) \ do { \ (vvp)->tv_sec -= (uvp)->tv_sec; \ (vvp)->tv_nsec -= (uvp)->tv_nsec; \ if ((vvp)->tv_nsec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_nsec += 1000000000; \ } \ } while (0) /* Operations on timevals. */ #define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #define timevalcmp(tvp, uvp, cmp) \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_sec cmp (uvp)->tv_sec)) /* timevaladd and timevalsub are not inlined */ #endif /* _KERNEL */ #ifndef _KERNEL /* NetBSD/OpenBSD compatible interfaces */ #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #define timercmp(tvp, uvp, cmp) \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_sec cmp (uvp)->tv_sec)) #define timeradd(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ if ((vvp)->tv_usec >= 1000000) { \ (vvp)->tv_sec++; \ (vvp)->tv_usec -= 1000000; \ } \ } while (0) #define timersub(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ if ((vvp)->tv_usec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_usec += 1000000; \ } \ } while (0) #endif /* * Names of the interval timers, and structure * defining a timer setting. */ #define ITIMER_REAL 0 #define ITIMER_VIRTUAL 1 #define ITIMER_PROF 2 struct itimerval { struct timeval it_interval; /* timer interval */ struct timeval it_value; /* current value */ }; /* * Getkerninfo clock information structure */ struct clockinfo { int hz; /* clock frequency */ int tick; /* micro-seconds per hz tick */ int spare; int stathz; /* statistics clock frequency */ int profhz; /* profiling clock frequency */ }; /* These macros are also in time.h. */ #ifndef CLOCK_REALTIME #define CLOCK_REALTIME 0 #define CLOCK_VIRTUAL 1 #define CLOCK_PROF 2 #define CLOCK_MONOTONIC 4 #define CLOCK_UPTIME 5 /* FreeBSD-specific. */ #define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */ #define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */ #define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */ #define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */ #define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */ #define CLOCK_SECOND 13 /* FreeBSD-specific. */ #define CLOCK_THREAD_CPUTIME_ID 14 #define CLOCK_PROCESS_CPUTIME_ID 15 #endif #ifndef TIMER_ABSTIME #define TIMER_RELTIME 0x0 /* relative timer */ #define TIMER_ABSTIME 0x1 /* absolute timer */ #endif #if __BSD_VISIBLE #define CPUCLOCK_WHICH_PID 0 #define CPUCLOCK_WHICH_TID 1 #endif #ifdef _KERNEL /* * Kernel to clock driver interface. */ void inittodr(time_t base); void resettodr(void); extern volatile time_t time_second; extern volatile time_t time_uptime; extern struct bintime boottimebin; extern struct timeval boottime; extern struct bintime tc_tick_bt; extern sbintime_t tc_tick_sbt; extern struct bintime tick_bt; extern sbintime_t tick_sbt; extern int tc_precexp; extern int tc_timepercentage; extern struct bintime bt_timethreshold; extern struct bintime bt_tickthreshold; extern sbintime_t sbt_timethreshold; extern sbintime_t sbt_tickthreshold; /* * Functions for looking at our clock: [get]{bin,nano,micro}[up]time() * * Functions without the "get" prefix returns the best timestamp * we can produce in the given format. * * "bin" == struct bintime == seconds + 64 bit fraction of seconds. * "nano" == struct timespec == seconds + nanoseconds. * "micro" == struct timeval == seconds + microseconds. * * Functions containing "up" returns time relative to boot and * should be used for calculating time intervals. * * Functions without "up" returns UTC time. * * Functions with the "get" prefix returns a less precise result * much faster than the functions without "get" prefix and should * be used where a precision of 1/hz seconds is acceptable or where * performance is priority. (NB: "precision", _not_ "resolution" !) */ void binuptime(struct bintime *bt); void nanouptime(struct timespec *tsp); void microuptime(struct timeval *tvp); static __inline sbintime_t sbinuptime(void) { struct bintime _bt; binuptime(&_bt); return (bttosbt(_bt)); } void bintime(struct bintime *bt); void nanotime(struct timespec *tsp); void microtime(struct timeval *tvp); void getbinuptime(struct bintime *bt); void getnanouptime(struct timespec *tsp); void getmicrouptime(struct timeval *tvp); static __inline sbintime_t getsbinuptime(void) { struct bintime _bt; getbinuptime(&_bt); return (bttosbt(_bt)); } void getbintime(struct bintime *bt); void getnanotime(struct timespec *tsp); void getmicrotime(struct timeval *tvp); /* Other functions */ int itimerdecr(struct itimerval *itp, int usec); int itimerfix(struct timeval *tv); int ppsratecheck(struct timeval *, int *, int); int ratecheck(struct timeval *, const struct timeval *); void timevaladd(struct timeval *t1, const struct timeval *t2); void timevalsub(struct timeval *t1, const struct timeval *t2); int tvtohz(struct timeval *tv); #define TC_DEFAULTPERC 5 #define BT2FREQ(bt) \ (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \ ((bt)->frac >> 1)) #define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt)) #define FREQ2BT(freq, bt) \ { \ (bt)->sec = 0; \ (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \ } #define TIMESEL(sbt, sbt2) \ (((sbt2) >= sbt_timethreshold) ? \ ((*(sbt) = getsbinuptime()), 1) : ((*(sbt) = sbinuptime()), 0)) #else /* !_KERNEL */ #include #include #include __BEGIN_DECLS int setitimer(int, const struct itimerval *, struct itimerval *); int utimes(const char *, const struct timeval *); #if __BSD_VISIBLE int adjtime(const struct timeval *, struct timeval *); int clock_getcpuclockid2(id_t, int, clockid_t *); int futimes(int, const struct timeval *); int futimesat(int, const char *, const struct timeval [2]); int lutimes(const char *, const struct timeval *); int settimeofday(const struct timeval *, const struct timezone *); #endif #if __XSI_VISIBLE int getitimer(int, struct itimerval *); int gettimeofday(struct timeval *, struct timezone *); #endif __END_DECLS #endif /* !_KERNEL */ #endif /* !_SYS_TIME_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)time.h 8.5 (Berkeley) 5/4/95 * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp * $FreeBSD$ */ #ifndef _SYS_TIMESPEC_H_ #define _SYS_TIMESPEC_H_ #include #include #if __BSD_VISIBLE #define TIMEVAL_TO_TIMESPEC(tv, ts) \ do { \ (ts)->tv_sec = (tv)->tv_sec; \ (ts)->tv_nsec = (tv)->tv_usec * 1000; \ } while (0) #define TIMESPEC_TO_TIMEVAL(tv, ts) \ do { \ (tv)->tv_sec = (ts)->tv_sec; \ (tv)->tv_usec = (ts)->tv_nsec / 1000; \ } while (0) #endif /* __BSD_VISIBLE */ /* * Structure defined by POSIX.1b to be like a itimerval, but with * timespecs. Used in the timer_*() system calls. */ struct itimerspec { struct timespec it_interval; struct timespec it_value; }; #endif /* _SYS_TIMESPEC_H_ */ /*- * Copyright (c) 1982, 1986, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)types.h 8.6 (Berkeley) 2/19/95 * $FreeBSD$ */ #ifndef _SYS_TYPES_H_ #define _SYS_TYPES_H_ #include /* Machine type dependent parameters. */ #include #include #include #if __BSD_VISIBLE typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; #ifndef _KERNEL typedef unsigned short ushort; /* Sys V compatibility */ typedef unsigned int uint; /* Sys V compatibility */ #endif #endif /* * POSIX Extensions */ typedef unsigned char uchar_t; typedef unsigned short ushort_t; typedef unsigned int uint_t; typedef unsigned long ulong_t; /* * XXX POSIX sized integrals that should appear only in . */ #include typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */ typedef __uint16_t u_int16_t; typedef __uint32_t u_int32_t; typedef __uint64_t u_int64_t; typedef __uint64_t u_quad_t; /* quads (deprecated) */ typedef __int64_t quad_t; typedef quad_t * qaddr_t; typedef char * caddr_t; /* core address */ typedef const char * c_caddr_t; /* core address, pointer to const */ #ifndef _BLKSIZE_T_DECLARED typedef __blksize_t blksize_t; #define _BLKSIZE_T_DECLARED #endif typedef __cpuwhich_t cpuwhich_t; typedef __cpulevel_t cpulevel_t; typedef __cpusetid_t cpusetid_t; #ifndef _BLKCNT_T_DECLARED typedef __blkcnt_t blkcnt_t; #define _BLKCNT_T_DECLARED #endif #ifndef _CLOCK_T_DECLARED typedef __clock_t clock_t; #define _CLOCK_T_DECLARED #endif #ifndef _CLOCKID_T_DECLARED typedef __clockid_t clockid_t; #define _CLOCKID_T_DECLARED #endif typedef __critical_t critical_t; /* Critical section value */ typedef __int64_t daddr_t; /* disk address */ #ifndef _DEV_T_DECLARED typedef __dev_t dev_t; /* device number or struct cdev */ #define _DEV_T_DECLARED #endif #ifndef _FFLAGS_T_DECLARED typedef __fflags_t fflags_t; /* file flags */ #define _FFLAGS_T_DECLARED #endif typedef __fixpt_t fixpt_t; /* fixed point number */ #ifndef _FSBLKCNT_T_DECLARED /* for statvfs() */ typedef __fsblkcnt_t fsblkcnt_t; typedef __fsfilcnt_t fsfilcnt_t; #define _FSBLKCNT_T_DECLARED #endif #ifndef _GID_T_DECLARED typedef __gid_t gid_t; /* group id */ #define _GID_T_DECLARED #endif #ifndef _IN_ADDR_T_DECLARED typedef __uint32_t in_addr_t; /* base type for internet address */ #define _IN_ADDR_T_DECLARED #endif #ifndef _IN_PORT_T_DECLARED typedef __uint16_t in_port_t; #define _IN_PORT_T_DECLARED #endif #ifndef _ID_T_DECLARED typedef __id_t id_t; /* can hold a uid_t or pid_t */ #define _ID_T_DECLARED #endif #ifndef _INO_T_DECLARED typedef __ino_t ino_t; /* inode number */ #define _INO_T_DECLARED #endif #ifndef _KEY_T_DECLARED typedef __key_t key_t; /* IPC key (for Sys V IPC) */ #define _KEY_T_DECLARED #endif #ifndef _LWPID_T_DECLARED typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */ #define _LWPID_T_DECLARED #endif #ifndef _MODE_T_DECLARED typedef __mode_t mode_t; /* permissions */ #define _MODE_T_DECLARED #endif #ifndef _ACCMODE_T_DECLARED typedef __accmode_t accmode_t; /* access permissions */ #define _ACCMODE_T_DECLARED #endif #ifndef _NLINK_T_DECLARED typedef __nlink_t nlink_t; /* link count */ #define _NLINK_T_DECLARED #endif #ifndef _OFF_T_DECLARED typedef __off_t off_t; /* file offset */ #define _OFF_T_DECLARED #endif #ifndef _PID_T_DECLARED typedef __pid_t pid_t; /* process id */ #define _PID_T_DECLARED #endif typedef __register_t register_t; #ifndef _RLIM_T_DECLARED typedef __rlim_t rlim_t; /* resource limit */ #define _RLIM_T_DECLARED #endif typedef __int64_t sbintime_t; typedef __segsz_t segsz_t; /* segment size (in pages) */ #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif #ifndef _SUSECONDS_T_DECLARED typedef __suseconds_t suseconds_t; /* microseconds (signed) */ #define _SUSECONDS_T_DECLARED #endif #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif #ifndef _TIMER_T_DECLARED typedef __timer_t timer_t; #define _TIMER_T_DECLARED #endif #ifndef _MQD_T_DECLARED typedef __mqd_t mqd_t; #define _MQD_T_DECLARED #endif typedef __u_register_t u_register_t; #ifndef _UID_T_DECLARED typedef __uid_t uid_t; /* user id */ #define _UID_T_DECLARED #endif #ifndef _USECONDS_T_DECLARED typedef __useconds_t useconds_t; /* microseconds (unsigned) */ #define _USECONDS_T_DECLARED #endif #ifndef _CAP_IOCTL_T_DECLARED #define _CAP_IOCTL_T_DECLARED typedef unsigned long cap_ioctl_t; #endif #ifndef _CAP_RIGHTS_T_DECLARED #define _CAP_RIGHTS_T_DECLARED struct cap_rights; typedef struct cap_rights cap_rights_t; #endif typedef __vm_offset_t vm_offset_t; typedef __vm_ooffset_t vm_ooffset_t; typedef __vm_paddr_t vm_paddr_t; typedef __vm_pindex_t vm_pindex_t; typedef __vm_size_t vm_size_t; typedef __rman_res_t rman_res_t; #ifdef _KERNEL typedef int boolean_t; typedef struct device *device_t; typedef __intfptr_t intfptr_t; /* * XXX this is fixed width for historical reasons. It should have had type * __int_fast32_t. Fixed-width types should not be used unless binary * compatibility is essential. Least-width types should be used even less * since they provide smaller benefits. * * XXX should be MD. * * XXX this is bogus in -current, but still used for spl*(). */ typedef __uint32_t intrmask_t; /* Interrupt mask (spl, xxx_imask...) */ typedef __uintfptr_t uintfptr_t; typedef __uint64_t uoff_t; typedef char vm_memattr_t; /* memory attribute codes */ typedef struct vm_page *vm_page_t; #if !defined(__bool_true_false_are_defined) && !defined(__cplusplus) #define __bool_true_false_are_defined 1 #define false 0 #define true 1 #if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER) typedef int _Bool; #endif typedef _Bool bool; #endif /* !__bool_true_false_are_defined && !__cplusplus */ #define offsetof(type, field) __offsetof(type, field) #else /* for illumos compatibility */ typedef enum boolean { B_FALSE, B_TRUE } boolean_t; #endif /* !_KERNEL */ /* * The following are all things that really shouldn't exist in this header, * since its purpose is to provide typedefs, not miscellaneous doodads. */ #ifdef __POPCNT__ #define __bitcount64(x) __builtin_popcountll((__uint64_t)(x)) #define __bitcount32(x) __builtin_popcount((__uint32_t)(x)) #define __bitcount16(x) __builtin_popcount((__uint16_t)(x)) #define __bitcountl(x) __builtin_popcountl((unsigned long)(x)) #define __bitcount(x) __builtin_popcount((unsigned int)(x)) #else /* * Population count algorithm using SWAR approach * - "SIMD Within A Register". */ static __inline __uint16_t __bitcount16(__uint16_t _x) { _x = (_x & 0x5555) + ((_x & 0xaaaa) >> 1); _x = (_x & 0x3333) + ((_x & 0xcccc) >> 2); _x = (_x + (_x >> 4)) & 0x0f0f; _x = (_x + (_x >> 8)) & 0x00ff; return (_x); } static __inline __uint32_t __bitcount32(__uint32_t _x) { _x = (_x & 0x55555555) + ((_x & 0xaaaaaaaa) >> 1); _x = (_x & 0x33333333) + ((_x & 0xcccccccc) >> 2); _x = (_x + (_x >> 4)) & 0x0f0f0f0f; _x = (_x + (_x >> 8)); _x = (_x + (_x >> 16)) & 0x000000ff; return (_x); } #ifdef __LP64__ static __inline __uint64_t __bitcount64(__uint64_t _x) { _x = (_x & 0x5555555555555555) + ((_x & 0xaaaaaaaaaaaaaaaa) >> 1); _x = (_x & 0x3333333333333333) + ((_x & 0xcccccccccccccccc) >> 2); _x = (_x + (_x >> 4)) & 0x0f0f0f0f0f0f0f0f; _x = (_x + (_x >> 8)); _x = (_x + (_x >> 16)); _x = (_x + (_x >> 32)) & 0x000000ff; return (_x); } #define __bitcountl(x) __bitcount64((unsigned long)(x)) #else static __inline __uint64_t __bitcount64(__uint64_t _x) { return (__bitcount32(_x >> 32) + __bitcount32(_x)); } #define __bitcountl(x) __bitcount32((unsigned long)(x)) #endif #define __bitcount(x) __bitcount32((unsigned int)(x)) #endif #if __BSD_VISIBLE #include /* * minor() gives a cookie instead of an index since we don't want to * change the meanings of bits 0-15 or waste time and space shifting * bits 16-31 for devices that don't use them. */ #define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */ #define minor(x) ((int)((x)&0xffff00ff)) /* minor number */ #define makedev(x,y) ((dev_t)(((x) << 8) | (y))) /* create dev_t */ /* * These declarations belong elsewhere, but are repeated here and in * to give broken programs a better chance of working with * 64-bit off_t's. */ #ifndef _KERNEL __BEGIN_DECLS #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate(int, off_t); #endif #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED off_t lseek(int, off_t, int); #endif #ifndef _MMAP_DECLARED #define _MMAP_DECLARED void * mmap(void *, size_t, int, int, int, off_t); #endif #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate(const char *, off_t); #endif __END_DECLS #endif /* !_KERNEL */ #endif /* __BSD_VISIBLE */ #endif /* !_SYS_TYPES_H_ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)unistd.h 8.2 (Berkeley) 1/7/94 * $FreeBSD$ */ #ifndef _SYS_UNISTD_H_ #define _SYS_UNISTD_H_ #include /* * POSIX options and option groups we unconditionally do or don't * implement. Those options which are implemented (or not) entirely * in user mode are defined in . Please keep this list in * alphabetical order. * * Anything which is defined as zero below **must** have an * implementation for the corresponding sysconf() which is able to * determine conclusively whether or not the feature is supported. * Anything which is defined as other than -1 below **must** have * complete headers, types, and function declarations as specified by * the POSIX standard; however, if the relevant sysconf() function * returns -1, the functions may be stubbed out. */ #define _POSIX_ADVISORY_INFO 200112L #define _POSIX_ASYNCHRONOUS_IO 0 #define _POSIX_CHOWN_RESTRICTED 1 #define _POSIX_CLOCK_SELECTION (-1) #define _POSIX_CPUTIME 200112L #define _POSIX_FSYNC 200112L #define _POSIX_IPV6 0 #define _POSIX_JOB_CONTROL 1 #define _POSIX_MAPPED_FILES 200112L #define _POSIX_MEMLOCK (-1) #define _POSIX_MEMLOCK_RANGE 200112L #define _POSIX_MEMORY_PROTECTION 200112L #define _POSIX_MESSAGE_PASSING 200112L #define _POSIX_MONOTONIC_CLOCK 200112L #define _POSIX_NO_TRUNC 1 #define _POSIX_PRIORITIZED_IO (-1) #define _POSIX_PRIORITY_SCHEDULING 200112L #define _POSIX_RAW_SOCKETS 200112L #define _POSIX_REALTIME_SIGNALS 200112L #define _POSIX_SEMAPHORES 200112L #define _POSIX_SHARED_MEMORY_OBJECTS 200112L #define _POSIX_SPORADIC_SERVER (-1) #define _POSIX_SYNCHRONIZED_IO (-1) #define _POSIX_TIMEOUTS 200112L #define _POSIX_TIMERS 200112L #define _POSIX_TYPED_MEMORY_OBJECTS (-1) #define _POSIX_VDISABLE 0xff #if __XSI_VISIBLE #define _XOPEN_SHM 1 #define _XOPEN_STREAMS (-1) #endif /* * Although we have saved user/group IDs, we do not use them in setuid * as described in POSIX 1003.1, because the feature does not work for * root. We use the saved IDs in seteuid/setegid, which are not currently * part of the POSIX 1003.1 specification. XXX revisit for 1003.1-2001 * as this is now mandatory. */ #ifdef _NOT_AVAILABLE #define _POSIX_SAVED_IDS 1 /* saved set-user-ID and set-group-ID */ #endif /* Define the POSIX.1 version we target for compliance. */ #define _POSIX_VERSION 200112L /* access function */ #define F_OK 0 /* test for existence of file */ #define X_OK 0x01 /* test for execute or search permission */ #define W_OK 0x02 /* test for write permission */ #define R_OK 0x04 /* test for read permission */ /* whence values for lseek(2) */ #ifndef SEEK_SET #define SEEK_SET 0 /* set file offset to offset */ #define SEEK_CUR 1 /* set file offset to current plus offset */ #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif #if __BSD_VISIBLE #define SEEK_DATA 3 /* set file offset to next data past offset */ #define SEEK_HOLE 4 /* set file offset to next hole past offset */ #endif #ifndef _POSIX_SOURCE /* whence values for lseek(2); renamed by POSIX 1003.1 */ #define L_SET SEEK_SET #define L_INCR SEEK_CUR #define L_XTND SEEK_END #endif /* configurable pathname variables */ #define _PC_LINK_MAX 1 #define _PC_MAX_CANON 2 #define _PC_MAX_INPUT 3 #define _PC_NAME_MAX 4 #define _PC_PATH_MAX 5 #define _PC_PIPE_BUF 6 #define _PC_CHOWN_RESTRICTED 7 #define _PC_NO_TRUNC 8 #define _PC_VDISABLE 9 #if __POSIX_VISIBLE >= 199309 #define _PC_ASYNC_IO 53 #define _PC_PRIO_IO 54 #define _PC_SYNC_IO 55 #endif #if __POSIX_VISIBLE >= 200112 #define _PC_ALLOC_SIZE_MIN 10 #define _PC_FILESIZEBITS 12 #define _PC_REC_INCR_XFER_SIZE 14 #define _PC_REC_MAX_XFER_SIZE 15 #define _PC_REC_MIN_XFER_SIZE 16 #define _PC_REC_XFER_ALIGN 17 #define _PC_SYMLINK_MAX 18 #endif #if __BSD_VISIBLE #define _PC_ACL_EXTENDED 59 #define _PC_ACL_PATH_MAX 60 #define _PC_CAP_PRESENT 61 #define _PC_INF_PRESENT 62 #define _PC_MAC_PRESENT 63 #define _PC_ACL_NFS4 64 #endif /* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */ #define _PC_MIN_HOLE_SIZE 21 #if __BSD_VISIBLE /* * rfork() options. * * XXX currently, some operations without RFPROC set are not supported. */ #define RFNAMEG (1<<0) /* UNIMPL new plan9 `name space' */ #define RFENVG (1<<1) /* UNIMPL copy plan9 `env space' */ #define RFFDG (1<<2) /* copy fd table */ #define RFNOTEG (1<<3) /* UNIMPL create new plan9 `note group' */ #define RFPROC (1<<4) /* change child (else changes curproc) */ #define RFMEM (1<<5) /* share `address space' */ #define RFNOWAIT (1<<6) /* give child to init */ #define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */ #define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */ #define RFCFDG (1<<12) /* close all fds, zero fd table */ #define RFTHREAD (1<<13) /* enable kernel thread support */ #define RFSIGSHARE (1<<14) /* share signal handlers */ #define RFLINUXTHPN (1<<16) /* do linux clone exit parent notification */ #define RFSTOPPED (1<<17) /* leave child in a stopped state */ #define RFHIGHPID (1<<18) /* use a pid higher than 10 (idleproc) */ #define RFTSIGZMB (1<<19) /* select signal for exit parent notification */ #define RFTSIGSHIFT 20 /* selected signal number is in bits 20-27 */ #define RFTSIGMASK 0xFF #define RFTSIGNUM(flags) (((flags) >> RFTSIGSHIFT) & RFTSIGMASK) #define RFTSIGFLAGS(signum) ((signum) << RFTSIGSHIFT) #define RFPROCDESC (1<<28) /* return a process descriptor */ #define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */ #define RFFLAGS (RFFDG | RFPROC | RFMEM | RFNOWAIT | RFCFDG | \ RFTHREAD | RFSIGSHARE | RFLINUXTHPN | RFSTOPPED | RFHIGHPID | RFTSIGZMB | \ RFPROCDESC | RFPPWAIT) #define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPPWAIT | RFPROCDESC) #endif /* __BSD_VISIBLE */ #endif /* !_SYS_UNISTD_H_ */ /*- * Copyright (c) 2002 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * * $FreeBSD$ */ #ifndef _SYS_UUID_H_ #define _SYS_UUID_H_ #include /* Length of a node address (an IEEE 802 address). */ #define _UUID_NODE_LEN 6 /* * See also: * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm * * A DCE 1.1 compatible source representation of UUIDs. */ struct uuid { uint32_t time_low; uint16_t time_mid; uint16_t time_hi_and_version; uint8_t clock_seq_hi_and_reserved; uint8_t clock_seq_low; uint8_t node[_UUID_NODE_LEN]; }; #ifdef _KERNEL #define UUID_NODE_LEN _UUID_NODE_LEN struct sbuf; struct uuid *kern_uuidgen(struct uuid *, size_t); int uuid_ether_add(const uint8_t *); int uuid_ether_del(const uint8_t *); int snprintf_uuid(char *, size_t, struct uuid *); int printf_uuid(struct uuid *); int sbuf_printf_uuid(struct sbuf *, struct uuid *); int parse_uuid(const char *, struct uuid *); void be_uuid_dec(void const *buf, struct uuid *uuid); void be_uuid_enc(void *buf, struct uuid const *uuid); void le_uuid_dec(void const *buf, struct uuid *uuid); void le_uuid_enc(void *buf, struct uuid const *uuid); #else /* _KERNEL */ /* XXX namespace pollution? */ typedef struct uuid uuid_t; __BEGIN_DECLS int uuidgen(struct uuid *, int); __END_DECLS #endif /* _KERNEL */ #endif /* _SYS_UUID_H_ */ /*- * Copyright (c) 2008 Marcel Moolenaar * All rights reserved. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. * * $FreeBSD$ */ #ifndef _SYS_VTOC_H_ #define _SYS_VTOC_H_ #define VTOC_TAG_UNASSIGNED 0x00 #define VTOC_TAG_BOOT 0x01 #define VTOC_TAG_ROOT 0x02 #define VTOC_TAG_SWAP 0x03 #define VTOC_TAG_USR 0x04 #define VTOC_TAG_BACKUP 0x05 /* "c" partition */ #define VTOC_TAG_STAND 0x06 #define VTOC_TAG_VAR 0x07 #define VTOC_TAG_HOME 0x08 #define VTOC_TAG_ALTSCTR 0x09 /* alternate sector partition */ #define VTOC_TAG_CACHE 0x0a /* Solaris cachefs partition */ #define VTOC_TAG_VXVM_PUB 0x0e /* VxVM public region */ #define VTOC_TAG_VXVM_PRIV 0x0f /* VxVM private region */ /* NetBSD/mips defines this */ #define VTOC_TAG_NETBSD_FFS 0xff /* FreeBSD tags: the high byte equals ELFOSABI_FREEBSD */ #define VTOC_TAG_FREEBSD_SWAP 0x0901 #define VTOC_TAG_FREEBSD_UFS 0x0902 #define VTOC_TAG_FREEBSD_VINUM 0x0903 #define VTOC_TAG_FREEBSD_ZFS 0x0904 #define VTOC_FLAG_UNMNT 0x01 /* unmountable partition */ #define VTOC_FLAG_RDONLY 0x10 /* partition is read/only */ #define VTOC_ASCII_LEN 128 #define VTOC_BOOTSIZE 8192 /* 16 sectors */ #define VTOC_MAGIC 0xdabe #define VTOC_RAW_PART 2 #define VTOC_SANITY 0x600ddeee #define VTOC_VERSION 1 #define VTOC_VOLUME_LEN 8 #define VTOC8_NPARTS 8 struct vtoc8 { char ascii[VTOC_ASCII_LEN]; uint32_t version; char volume[VTOC_VOLUME_LEN]; uint16_t nparts; struct { uint16_t tag; uint16_t flag; } part[VTOC8_NPARTS] __packed; uint16_t __alignment; uint32_t bootinfo[3]; uint32_t sanity; uint32_t reserved[10]; uint32_t timestamp[VTOC8_NPARTS]; uint16_t wskip; uint16_t rskip; char padding[152]; uint16_t rpm; uint16_t physcyls; uint16_t sparesecs; uint16_t spare1[2]; uint16_t interleave; uint16_t ncyls; uint16_t altcyls; uint16_t nheads; uint16_t nsecs; uint16_t spare2[2]; struct { uint32_t cyl; uint32_t nblks; } map[VTOC8_NPARTS]; uint16_t magic; uint16_t cksum; } __packed; #ifdef CTASSERT CTASSERT(sizeof(struct vtoc8) == 512); #endif #define NDKMAP 16 /* # of logical partitions */ #define DK_LABEL_LOC 1 /* location of disk label */ #define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */ #define LEN_DKL_VVOL 8 /* length of v_volume */ #define DK_LABEL_SIZE 512 /* size of disk label */ #define DK_MAX_BLOCKS 0x7fffffff /* max # of blocks handled */ struct dk_vtoc { uint32_t v_bootinfo[3]; /* info needed by mboot (unsupported) */ uint32_t v_sanity; /* to verify vtoc sanity */ uint32_t v_version; /* layout version */ char v_volume[LEN_DKL_VVOL]; /* volume name */ uint16_t v_sectorsz; /* sector size in bytes */ uint16_t v_nparts; /* number of partitions */ uint32_t v_reserved[10]; /* free space */ struct { uint16_t p_tag; /* ID tag of partition */ uint16_t p_flag; /* permission flags */ uint32_t p_start;/* start sector no of partition */ int32_t p_size; /* # of blocks in partition */ } v_part[NDKMAP]; /* partition headers */ uint32_t timestamp[NDKMAP]; /* partition timestamp (unsupported) */ char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ }; #define LEN_DKL_PAD (DK_LABEL_SIZE - \ ((sizeof (struct dk_vtoc) + \ (4 * sizeof (uint32_t)) + \ (12 * sizeof (uint16_t)) + \ (2 * (sizeof (uint16_t)))))) struct dk_label { struct dk_vtoc dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ uint32_t dkl_pcyl; /* # of physical cylinders */ uint32_t dkl_ncyl; /* # of data cylinders */ uint16_t dkl_acyl; /* # of alternate cylinders */ uint16_t dkl_bcyl; /* cyl offset (for fixed head area) */ uint32_t dkl_nhead; /* # of heads */ uint32_t dkl_nsect; /* # of data sectors per track */ uint16_t dkl_intrlv; /* interleave factor */ uint16_t dkl_skew; /* skew factor */ uint16_t dkl_apc; /* alternates per cyl (SCSI only) */ uint16_t dkl_rpm; /* revolutions per minute */ uint16_t dkl_write_reinstruct; /* # sectors to skip, writes */ uint16_t dkl_read_reinstruct; /* # sectors to skip, reads */ uint16_t dkl_extra[4]; /* for compatible expansion */ char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ uint16_t dkl_magic; /* identifies this label format */ uint16_t dkl_cksum; /* xor checksum of sector */ }; #ifdef CTASSERT CTASSERT(sizeof(struct dk_label) == 512); #endif #endif /* _SYS_VTOC_H_ */ /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)fs.h 8.13 (Berkeley) 3/21/95 * $FreeBSD$ */ #ifndef _UFS_FFS_FS_H_ #define _UFS_FFS_FS_H_ #include #include /* * Each disk drive contains some number of filesystems. * A filesystem consists of a number of cylinder groups. * Each cylinder group has inodes and data. * * A filesystem is described by its super-block, which in turn * describes the cylinder groups. The super-block is critical * data and is replicated in each cylinder group to protect against * catastrophic loss. This is done at `newfs' time and the critical * super-block data does not change, so the copies need not be * referenced further unless disaster strikes. * * For filesystem fs, the offsets of the various blocks of interest * are given in the super block as: * [fs->fs_sblkno] Super-block * [fs->fs_cblkno] Cylinder group block * [fs->fs_iblkno] Inode blocks * [fs->fs_dblkno] Data blocks * The beginning of cylinder group cg in fs, is given by * the ``cgbase(fs, cg)'' macro. * * Depending on the architecture and the media, the superblock may * reside in any one of four places. For tiny media where every block * counts, it is placed at the very front of the partition. Historically, * UFS1 placed it 8K from the front to leave room for the disk label and * a small bootstrap. For UFS2 it got moved to 64K from the front to leave * room for the disk label and a bigger bootstrap, and for really piggy * systems we check at 256K from the front if the first three fail. In * all cases the size of the superblock will be SBLOCKSIZE. All values are * given in byte-offset form, so they do not imply a sector size. The * SBLOCKSEARCH specifies the order in which the locations should be searched. */ #define SBLOCK_FLOPPY 0 #define SBLOCK_UFS1 8192 #define SBLOCK_UFS2 65536 #define SBLOCK_PIGGY 262144 #define SBLOCKSIZE 8192 #define SBLOCKSEARCH \ { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 } /* * Max number of fragments per block. This value is NOT tweakable. */ #define MAXFRAG 8 /* * Addresses stored in inodes are capable of addressing fragments * of `blocks'. File system blocks of at most size MAXBSIZE can * be optionally broken into 2, 4, or 8 pieces, each of which is * addressable; these pieces may be DEV_BSIZE, or some multiple of * a DEV_BSIZE unit. * * Large files consist of exclusively large data blocks. To avoid * undue wasted disk space, the last data block of a small file may be * allocated as only as many fragments of a large block as are * necessary. The filesystem format retains only a single pointer * to such a fragment, which is a piece of a single large block that * has been divided. The size of such a fragment is determinable from * information in the inode, using the ``blksize(fs, ip, lbn)'' macro. * * The filesystem records space availability at the fragment level; * to determine block availability, aligned fragments are examined. */ /* * MINBSIZE is the smallest allowable block size. * In order to insure that it is possible to create files of size * 2^32 with only two levels of indirection, MINBSIZE is set to 4096. * MINBSIZE must be big enough to hold a cylinder group block, * thus changes to (struct cg) must keep its size within MINBSIZE. * Note that super blocks are always of size SBLOCKSIZE, * and that both SBLOCKSIZE and MAXBSIZE must be >= MINBSIZE. */ #define MINBSIZE 4096 /* * The path name on which the filesystem is mounted is maintained * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in * the super block for this name. */ #define MAXMNTLEN 468 /* * The volume name for this filesystem is maintained in fs_volname. * MAXVOLLEN defines the length of the buffer allocated. */ #define MAXVOLLEN 32 /* * There is a 128-byte region in the superblock reserved for in-core * pointers to summary information. Originally this included an array * of pointers to blocks of struct csum; now there are just a few * pointers and the remaining space is padded with fs_ocsp[]. * * NOCSPTRS determines the size of this padding. One pointer (fs_csp) * is taken away to point to a contiguous array of struct csum for * all cylinder groups; a second (fs_maxcluster) points to an array * of cluster sizes that is computed as cylinder groups are inspected, * and the third points to an array that tracks the creation of new * directories. A fourth pointer, fs_active, is used when creating * snapshots; it points to a bitmap of cylinder groups for which the * free-block bitmap has changed since the snapshot operation began. */ #define NOCSPTRS ((128 / sizeof(void *)) - 4) /* * A summary of contiguous blocks of various sizes is maintained * in each cylinder group. Normally this is set by the initial * value of fs_maxcontig. To conserve space, a maximum summary size * is set by FS_MAXCONTIG. */ #define FS_MAXCONTIG 16 /* * MINFREE gives the minimum acceptable percentage of filesystem * blocks which may be free. If the freelist drops below this level * only the superuser may continue to allocate blocks. This may * be set to 0 if no reserve of free blocks is deemed necessary, * however throughput drops by fifty percent if the filesystem * is run at between 95% and 100% full; thus the minimum default * value of fs_minfree is 5%. However, to get good clustering * performance, 10% is a better choice. hence we use 10% as our * default value. With 10% free space, fragmentation is not a * problem, so we choose to optimize for time. */ #define MINFREE 8 #define DEFAULTOPT FS_OPTTIME /* * Grigoriy Orlov has done some extensive work to fine * tune the layout preferences for directories within a filesystem. * His algorithm can be tuned by adjusting the following parameters * which tell the system the average file size and the average number * of files per directory. These defaults are well selected for typical * filesystems, but may need to be tuned for odd cases like filesystems * being used for squid caches or news spools. */ #define AVFILESIZ 16384 /* expected average file size */ #define AFPDIR 64 /* expected number of files per directory */ /* * The maximum number of snapshot nodes that can be associated * with each filesystem. This limit affects only the number of * snapshot files that can be recorded within the superblock so * that they can be found when the filesystem is mounted. However, * maintaining too many will slow the filesystem performance, so * having this limit is a good idea. */ #define FSMAXSNAP 20 /* * Used to identify special blocks in snapshots: * * BLK_NOCOPY - A block that was unallocated at the time the snapshot * was taken, hence does not need to be copied when written. * BLK_SNAP - A block held by another snapshot that is not needed by this * snapshot. When the other snapshot is freed, the BLK_SNAP entries * are converted to BLK_NOCOPY. These are needed to allow fsck to * identify blocks that are in use by other snapshots (which are * expunged from this snapshot). */ #define BLK_NOCOPY ((ufs2_daddr_t)(1)) #define BLK_SNAP ((ufs2_daddr_t)(2)) /* * Sysctl values for the fast filesystem. */ #define FFS_ADJ_REFCNT 1 /* adjust inode reference count */ #define FFS_ADJ_BLKCNT 2 /* adjust inode used block count */ #define FFS_BLK_FREE 3 /* free range of blocks in map */ #define FFS_DIR_FREE 4 /* free specified dir inodes in map */ #define FFS_FILE_FREE 5 /* free specified file inodes in map */ #define FFS_SET_FLAGS 6 /* set filesystem flags */ #define FFS_ADJ_NDIR 7 /* adjust number of directories */ #define FFS_ADJ_NBFREE 8 /* adjust number of free blocks */ #define FFS_ADJ_NIFREE 9 /* adjust number of free inodes */ #define FFS_ADJ_NFFREE 10 /* adjust number of free frags */ #define FFS_ADJ_NUMCLUSTERS 11 /* adjust number of free clusters */ #define FFS_SET_CWD 12 /* set current directory */ #define FFS_SET_DOTDOT 13 /* set inode number for ".." */ #define FFS_UNLINK 14 /* remove a name in the filesystem */ #define FFS_SET_INODE 15 /* update an on-disk inode */ #define FFS_SET_BUFOUTPUT 16 /* set buffered writing on descriptor */ #define FFS_MAXID 16 /* number of valid ffs ids */ /* * Command structure passed in to the filesystem to adjust filesystem values. */ #define FFS_CMD_VERSION 0x19790518 /* version ID */ struct fsck_cmd { int32_t version; /* version of command structure */ int32_t handle; /* reference to filesystem to be changed */ int64_t value; /* inode or block number to be affected */ int64_t size; /* amount or range to be adjusted */ int64_t spare; /* reserved for future use */ }; /* * Per cylinder group information; summarized in blocks allocated * from first cylinder group data blocks. These blocks have to be * read in from fs_csaddr (size fs_cssize) in addition to the * super block. */ struct csum { int32_t cs_ndir; /* number of directories */ int32_t cs_nbfree; /* number of free blocks */ int32_t cs_nifree; /* number of free inodes */ int32_t cs_nffree; /* number of free frags */ }; struct csum_total { int64_t cs_ndir; /* number of directories */ int64_t cs_nbfree; /* number of free blocks */ int64_t cs_nifree; /* number of free inodes */ int64_t cs_nffree; /* number of free frags */ int64_t cs_numclusters; /* number of free clusters */ int64_t cs_spare[3]; /* future expansion */ }; /* * Super block for an FFS filesystem. */ struct fs { int32_t fs_firstfield; /* historic filesystem linked list, */ int32_t fs_unused_1; /* used for incore super blocks */ int32_t fs_sblkno; /* offset of super-block in filesys */ int32_t fs_cblkno; /* offset of cyl-block in filesys */ int32_t fs_iblkno; /* offset of inode-blocks in filesys */ int32_t fs_dblkno; /* offset of first data after cg */ int32_t fs_old_cgoffset; /* cylinder group offset in cylinder */ int32_t fs_old_cgmask; /* used to calc mod fs_ntrak */ int32_t fs_old_time; /* last time written */ int32_t fs_old_size; /* number of blocks in fs */ int32_t fs_old_dsize; /* number of data blocks in fs */ u_int32_t fs_ncg; /* number of cylinder groups */ int32_t fs_bsize; /* size of basic blocks in fs */ int32_t fs_fsize; /* size of frag blocks in fs */ int32_t fs_frag; /* number of frags in a block in fs */ /* these are configuration parameters */ int32_t fs_minfree; /* minimum percentage of free blocks */ int32_t fs_old_rotdelay; /* num of ms for optimal next block */ int32_t fs_old_rps; /* disk revolutions per second */ /* these fields can be computed from the others */ int32_t fs_bmask; /* ``blkoff'' calc of blk offsets */ int32_t fs_fmask; /* ``fragoff'' calc of frag offsets */ int32_t fs_bshift; /* ``lblkno'' calc of logical blkno */ int32_t fs_fshift; /* ``numfrags'' calc number of frags */ /* these are configuration parameters */ int32_t fs_maxcontig; /* max number of contiguous blks */ int32_t fs_maxbpg; /* max number of blks per cyl group */ /* these fields can be computed from the others */ int32_t fs_fragshift; /* block to frag shift */ int32_t fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ int32_t fs_sbsize; /* actual size of super block */ int32_t fs_spare1[2]; /* old fs_csmask */ /* old fs_csshift */ int32_t fs_nindir; /* value of NINDIR */ u_int32_t fs_inopb; /* value of INOPB */ int32_t fs_old_nspf; /* value of NSPF */ /* yet another configuration parameter */ int32_t fs_optim; /* optimization preference, see below */ int32_t fs_old_npsect; /* # sectors/track including spares */ int32_t fs_old_interleave; /* hardware sector interleave */ int32_t fs_old_trackskew; /* sector 0 skew, per track */ int32_t fs_id[2]; /* unique filesystem id */ /* sizes determined by number of cylinder groups and their sizes */ int32_t fs_old_csaddr; /* blk addr of cyl grp summary area */ int32_t fs_cssize; /* size of cyl grp summary area */ int32_t fs_cgsize; /* cylinder group size */ int32_t fs_spare2; /* old fs_ntrak */ int32_t fs_old_nsect; /* sectors per track */ int32_t fs_old_spc; /* sectors per cylinder */ int32_t fs_old_ncyl; /* cylinders in filesystem */ int32_t fs_old_cpg; /* cylinders per group */ u_int32_t fs_ipg; /* inodes per group */ int32_t fs_fpg; /* blocks per group * fs_frag */ /* this data must be re-computed after crashes */ struct csum fs_old_cstotal; /* cylinder summary information */ /* these fields are cleared at mount time */ int8_t fs_fmod; /* super block modified flag */ int8_t fs_clean; /* filesystem is clean flag */ int8_t fs_ronly; /* mounted read-only flag */ int8_t fs_old_flags; /* old FS_ flags */ u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */ u_char fs_volname[MAXVOLLEN]; /* volume name */ u_int64_t fs_swuid; /* system-wide uid */ int32_t fs_pad; /* due to alignment of fs_swuid */ /* these fields retain the current block allocation info */ int32_t fs_cgrotor; /* last cg searched */ void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */ u_int8_t *fs_contigdirs; /* (u) # of contig. allocated dirs */ struct csum *fs_csp; /* (u) cg summary info buffer */ int32_t *fs_maxcluster; /* (u) max cluster in each cyl group */ u_int *fs_active; /* (u) used by snapshots to track fs */ int32_t fs_old_cpc; /* cyl per cycle in postbl */ int32_t fs_maxbsize; /* maximum blocking factor permitted */ int64_t fs_unrefs; /* number of unreferenced inodes */ int64_t fs_providersize; /* size of underlying GEOM provider */ int64_t fs_metaspace; /* size of area reserved for metadata */ int64_t fs_sparecon64[14]; /* old rotation block list head */ int64_t fs_sblockloc; /* byte offset of standard superblock */ struct csum_total fs_cstotal; /* (u) cylinder summary information */ ufs_time_t fs_time; /* last time written */ int64_t fs_size; /* number of blocks in fs */ int64_t fs_dsize; /* number of data blocks in fs */ ufs2_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */ int64_t fs_pendingblocks; /* (u) blocks being freed */ u_int32_t fs_pendinginodes; /* (u) inodes being freed */ uint32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ u_int32_t fs_avgfilesize; /* expected average file size */ u_int32_t fs_avgfpdir; /* expected # of files per directory */ int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */ ufs_time_t fs_mtime; /* Last mount or fsck time. */ int32_t fs_sujfree; /* SUJ free list */ int32_t fs_sparecon32[23]; /* reserved for future constants */ int32_t fs_flags; /* see FS_ flags below */ int32_t fs_contigsumsize; /* size of cluster summary array */ int32_t fs_maxsymlinklen; /* max length of an internal symlink */ int32_t fs_old_inodefmt; /* format of on-disk inodes */ u_int64_t fs_maxfilesize; /* maximum representable file size */ int64_t fs_qbmask; /* ~fs_bmask for use with 64-bit size */ int64_t fs_qfmask; /* ~fs_fmask for use with 64-bit size */ int32_t fs_state; /* validate fs_clean field */ int32_t fs_old_postblformat; /* format of positional layout tables */ int32_t fs_old_nrpos; /* number of rotational positions */ int32_t fs_spare5[2]; /* old fs_postbloff */ /* old fs_rotbloff */ int32_t fs_magic; /* magic number */ }; /* Sanity checking. */ #ifdef CTASSERT CTASSERT(sizeof(struct fs) == 1376); #endif /* * Filesystem identification */ #define FS_UFS1_MAGIC 0x011954 /* UFS1 fast filesystem magic number */ #define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast filesystem magic number */ #define FS_BAD_MAGIC 0x19960408 /* UFS incomplete newfs magic number */ #define FS_OKAY 0x7c269d38 /* superblock checksum */ #define FS_42INODEFMT -1 /* 4.2BSD inode format */ #define FS_44INODEFMT 2 /* 4.4BSD inode format */ /* * Preference for optimization. */ #define FS_OPTTIME 0 /* minimize allocation time */ #define FS_OPTSPACE 1 /* minimize disk fragmentation */ /* * Filesystem flags. * * The FS_UNCLEAN flag is set by the kernel when the filesystem was * mounted with fs_clean set to zero. The FS_DOSOFTDEP flag indicates * that the filesystem should be managed by the soft updates code. * Note that the FS_NEEDSFSCK flag is set and cleared only by the * fsck utility. It is set when background fsck finds an unexpected * inconsistency which requires a traditional foreground fsck to be * run. Such inconsistencies should only be found after an uncorrectable * disk error. A foreground fsck will clear the FS_NEEDSFSCK flag when * it has successfully cleaned up the filesystem. The kernel uses this * flag to enforce that inconsistent filesystems be mounted read-only. * The FS_INDEXDIRS flag when set indicates that the kernel maintains * on-disk auxiliary indexes (such as B-trees) for speeding directory * accesses. Kernels that do not support auxiliary indicies clear the * flag to indicate that the indicies need to be rebuilt (by fsck) before * they can be used. * * FS_ACLS indicates that POSIX.1e ACLs are administratively enabled * for the file system, so they should be loaded from extended attributes, * observed for access control purposes, and be administered by object * owners. FS_NFS4ACLS indicates that NFSv4 ACLs are administratively * enabled. This flag is mutually exclusive with FS_ACLS. FS_MULTILABEL * indicates that the TrustedBSD MAC Framework should attempt to back MAC * labels into extended attributes on the file system rather than maintain * a single mount label for all objects. */ #define FS_UNCLEAN 0x0001 /* filesystem not clean at mount */ #define FS_DOSOFTDEP 0x0002 /* filesystem using soft dependencies */ #define FS_NEEDSFSCK 0x0004 /* filesystem needs sync fsck before mount */ #define FS_SUJ 0x0008 /* Filesystem using softupdate journal */ #define FS_ACLS 0x0010 /* file system has POSIX.1e ACLs enabled */ #define FS_MULTILABEL 0x0020 /* file system is MAC multi-label */ #define FS_GJOURNAL 0x0040 /* gjournaled file system */ #define FS_FLAGS_UPDATED 0x0080 /* flags have been moved to new location */ #define FS_NFS4ACLS 0x0100 /* file system has NFSv4 ACLs enabled */ #define FS_INDEXDIRS 0x0200 /* kernel supports indexed directories */ #define FS_TRIM 0x0400 /* issue BIO_DELETE for deleted blocks */ /* * Macros to access bits in the fs_active array. */ #define ACTIVECGNUM(fs, cg) ((fs)->fs_active[(cg) / (NBBY * sizeof(int))]) #define ACTIVECGOFF(cg) (1 << ((cg) % (NBBY * sizeof(int)))) #define ACTIVESET(fs, cg) do { \ if ((fs)->fs_active) \ ACTIVECGNUM((fs), (cg)) |= ACTIVECGOFF((cg)); \ } while (0) #define ACTIVECLEAR(fs, cg) do { \ if ((fs)->fs_active) \ ACTIVECGNUM((fs), (cg)) &= ~ACTIVECGOFF((cg)); \ } while (0) /* * The size of a cylinder group is calculated by CGSIZE. The maximum size * is limited by the fact that cylinder groups are at most one block. * Its size is derived from the size of the maps maintained in the * cylinder group and the (struct cg) size. */ #define CGSIZE(fs) \ /* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \ /* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \ /* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \ /* inode map */ howmany((fs)->fs_ipg, NBBY) + \ /* block map */ howmany((fs)->fs_fpg, NBBY) +\ /* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \ /* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \ /* cluster map */ howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY))) /* * The minimal number of cylinder groups that should be created. */ #define MINCYLGRPS 4 /* * Convert cylinder group to base address of its global summary info. */ #define fs_cs(fs, indx) fs_csp[indx] /* * Cylinder group block for a filesystem. */ #define CG_MAGIC 0x090255 struct cg { int32_t cg_firstfield; /* historic cyl groups linked list */ int32_t cg_magic; /* magic number */ int32_t cg_old_time; /* time last written */ u_int32_t cg_cgx; /* we are the cgx'th cylinder group */ int16_t cg_old_ncyl; /* number of cyl's this cg */ int16_t cg_old_niblk; /* number of inode blocks this cg */ u_int32_t cg_ndblk; /* number of data blocks this cg */ struct csum cg_cs; /* cylinder summary information */ u_int32_t cg_rotor; /* position of last used block */ u_int32_t cg_frotor; /* position of last used frag */ u_int32_t cg_irotor; /* position of last used inode */ u_int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ int32_t cg_old_btotoff; /* (int32) block totals per cylinder */ int32_t cg_old_boff; /* (u_int16) free block positions */ u_int32_t cg_iusedoff; /* (u_int8) used inode map */ u_int32_t cg_freeoff; /* (u_int8) free block map */ u_int32_t cg_nextfreeoff; /* (u_int8) next available space */ u_int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ u_int32_t cg_clusteroff; /* (u_int8) free cluster map */ u_int32_t cg_nclusterblks; /* number of clusters this cg */ u_int32_t cg_niblk; /* number of inode blocks this cg */ u_int32_t cg_initediblk; /* last initialized inode */ u_int32_t cg_unrefs; /* number of unreferenced inodes */ int32_t cg_sparecon32[2]; /* reserved for future use */ ufs_time_t cg_time; /* time last written */ int64_t cg_sparecon64[3]; /* reserved for future use */ u_int8_t cg_space[1]; /* space for cylinder group maps */ /* actually longer */ }; /* * Macros for access to cylinder group array structures */ #define cg_chkmagic(cgp) ((cgp)->cg_magic == CG_MAGIC) #define cg_inosused(cgp) \ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff)) #define cg_blksfree(cgp) \ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff)) #define cg_clustersfree(cgp) \ ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff)) #define cg_clustersum(cgp) \ ((int32_t *)((uintptr_t)(cgp) + (cgp)->cg_clustersumoff)) /* * Turn filesystem block numbers into disk block addresses. * This maps filesystem blocks to device size blocks. */ #define fsbtodb(fs, b) ((daddr_t)(b) << (fs)->fs_fsbtodb) #define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb) /* * Cylinder group macros to locate things in cylinder groups. * They calc filesystem addresses of cylinder group data structures. */ #define cgbase(fs, c) (((ufs2_daddr_t)(fs)->fs_fpg) * (c)) #define cgdata(fs, c) (cgdmin(fs, c) + (fs)->fs_metaspace) /* data zone */ #define cgmeta(fs, c) (cgdmin(fs, c)) /* meta data */ #define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */ #define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */ #define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */ #define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */ #define cgstart(fs, c) \ ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) : \ (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask)))) /* * Macros for handling inode numbers: * inode number to filesystem block offset. * inode number to cylinder group number. * inode number to filesystem block address. */ #define ino_to_cg(fs, x) (((ino_t)(x)) / (fs)->fs_ipg) #define ino_to_fsba(fs, x) \ ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, (ino_t)(x))) + \ (blkstofrags((fs), ((((ino_t)(x)) % (fs)->fs_ipg) / INOPB(fs)))))) #define ino_to_fsbo(fs, x) (((ino_t)(x)) % INOPB(fs)) /* * Give cylinder group number for a filesystem block. * Give cylinder group block number for a filesystem block. */ #define dtog(fs, d) ((d) / (fs)->fs_fpg) #define dtogd(fs, d) ((d) % (fs)->fs_fpg) /* * Extract the bits for a block from a map. * Compute the cylinder and rotational position of a cyl block addr. */ #define blkmap(fs, map, loc) \ (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag))) /* * The following macros optimize certain frequently calculated * quantities by using shifts and masks in place of divisions * modulos and multiplications. */ #define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \ ((loc) & ~((fs)->fs_bmask)) #define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \ ((loc) & ~((fs)->fs_fmask)) #define lfragtosize(fs, frag) /* calculates ((off_t)frag * fs->fs_fsize) */ \ (((off_t)(frag)) << (fs)->fs_fshift) #define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \ (((off_t)(blk)) << (fs)->fs_bshift) /* Use this only when `blk' is known to be small, e.g., < NDADDR. */ #define smalllblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ ((blk) << (fs)->fs_bshift) #define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ ((loc) >> (fs)->fs_bshift) #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ ((loc) >> (fs)->fs_fshift) #define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \ (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask) #define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \ (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask) #define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \ ((frags) >> (fs)->fs_fragshift) #define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \ ((blks) << (fs)->fs_fragshift) #define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \ ((fsb) & ((fs)->fs_frag - 1)) #define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \ ((fsb) &~ ((fs)->fs_frag - 1)) /* * Determine the number of available frags given a * percentage to hold in reserve. */ #define freespace(fs, percentreserved) \ (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \ (fs)->fs_cstotal.cs_nffree - \ (((off_t)((fs)->fs_dsize)) * (percentreserved) / 100)) /* * Determining the size of a file block in the filesystem. */ #define blksize(fs, ip, lbn) \ (((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \ ? (fs)->fs_bsize \ : (fragroundup(fs, blkoff(fs, (ip)->i_size)))) #define sblksize(fs, size, lbn) \ (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \ ? (fs)->fs_bsize \ : (fragroundup(fs, blkoff(fs, (size))))) /* * Number of indirects in a filesystem block. */ #define NINDIR(fs) ((fs)->fs_nindir) /* * Indirect lbns are aligned on NDADDR addresses where single indirects * are the negated address of the lowest lbn reachable, double indirects * are this lbn - 1 and triple indirects are this lbn - 2. This yields * an unusual bit order to determine level. */ static inline int lbn_level(ufs_lbn_t lbn) { if (lbn >= 0) return 0; switch (lbn & 0x3) { case 0: return (0); case 1: break; case 2: return (2); case 3: return (1); default: break; } return (-1); } static inline ufs_lbn_t lbn_offset(struct fs *fs, int level) { ufs_lbn_t res; for (res = 1; level > 0; level--) res *= NINDIR(fs); return (res); } /* * Number of inodes in a secondary storage block/fragment. */ #define INOPB(fs) ((fs)->fs_inopb) #define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift) /* * Softdep journal record format. */ #define JOP_ADDREF 1 /* Add a reference to an inode. */ #define JOP_REMREF 2 /* Remove a reference from an inode. */ #define JOP_NEWBLK 3 /* Allocate a block. */ #define JOP_FREEBLK 4 /* Free a block or a tree of blocks. */ #define JOP_MVREF 5 /* Move a reference from one off to another. */ #define JOP_TRUNC 6 /* Partial truncation record. */ #define JOP_SYNC 7 /* fsync() complete record. */ #define JREC_SIZE 32 /* Record and segment header size. */ #define SUJ_MIN (4 * 1024 * 1024) /* Minimum journal size */ #define SUJ_MAX (32 * 1024 * 1024) /* Maximum journal size */ #define SUJ_FILE ".sujournal" /* Journal file name */ /* * Size of the segment record header. There is at most one for each disk * block in the journal. The segment header is followed by an array of * records. fsck depends on the first element in each record being 'op' * and the second being 'ino'. Segments may span multiple disk blocks but * the header is present on each. */ struct jsegrec { uint64_t jsr_seq; /* Our sequence number */ uint64_t jsr_oldest; /* Oldest valid sequence number */ uint16_t jsr_cnt; /* Count of valid records */ uint16_t jsr_blocks; /* Count of device bsize blocks. */ uint32_t jsr_crc; /* 32bit crc of the valid space */ ufs_time_t jsr_time; /* timestamp for mount instance */ }; /* * Reference record. Records a single link count modification. */ struct jrefrec { uint32_t jr_op; uint32_t jr_ino; uint32_t jr_parent; uint16_t jr_nlink; uint16_t jr_mode; int64_t jr_diroff; uint64_t jr_unused; }; /* * Move record. Records a reference moving within a directory block. The * nlink is unchanged but we must search both locations. */ struct jmvrec { uint32_t jm_op; uint32_t jm_ino; uint32_t jm_parent; uint16_t jm_unused; int64_t jm_oldoff; int64_t jm_newoff; }; /* * Block record. A set of frags or tree of blocks starting at an indirect are * freed or a set of frags are allocated. */ struct jblkrec { uint32_t jb_op; uint32_t jb_ino; ufs2_daddr_t jb_blkno; ufs_lbn_t jb_lbn; uint16_t jb_frags; uint16_t jb_oldfrags; uint32_t jb_unused; }; /* * Truncation record. Records a partial truncation so that it may be * completed at check time. Also used for sync records. */ struct jtrncrec { uint32_t jt_op; uint32_t jt_ino; int64_t jt_size; uint32_t jt_extsize; uint32_t jt_pad[3]; }; union jrec { struct jsegrec rec_jsegrec; struct jrefrec rec_jrefrec; struct jmvrec rec_jmvrec; struct jblkrec rec_jblkrec; struct jtrncrec rec_jtrncrec; }; #ifdef CTASSERT CTASSERT(sizeof(struct jsegrec) == JREC_SIZE); CTASSERT(sizeof(struct jrefrec) == JREC_SIZE); CTASSERT(sizeof(struct jmvrec) == JREC_SIZE); CTASSERT(sizeof(struct jblkrec) == JREC_SIZE); CTASSERT(sizeof(struct jtrncrec) == JREC_SIZE); CTASSERT(sizeof(union jrec) == JREC_SIZE); #endif extern int inside[], around[]; extern u_char *fragtbl[]; /* * IOCTLs used for filesystem write suspension. */ #define UFSSUSPEND _IOW('U', 1, fsid_t) #define UFSRESUME _IO('U', 2) #endif /*- * Copyright (c) 2001 David E. O'Brien * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)param.h 5.8 (Berkeley) 6/28/91 * $FreeBSD$ */ #ifndef _X86_INCLUDE__ALIGN_H_ #define _X86_INCLUDE__ALIGN_H_ /* * Round p (pointer or byte index) up to a correctly-aligned value * for all data types (int, long, ...). The result is unsigned int * and must be cast to any desired pointer type. */ #define _ALIGNBYTES (sizeof(register_t) - 1) #define _ALIGN(p) (((uintptr_t)(p) + _ALIGNBYTES) & ~_ALIGNBYTES) #endif /* !_X86_INCLUDE__ALIGN_H_ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Klaus Klein. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. * * From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $ * $FreeBSD$ */ #ifndef _MACHINE_INTTYPES_H_ #define _MACHINE_INTTYPES_H_ /* * Macros for format specifiers. */ #ifdef __LP64__ #define __PRI64 "l" #define __PRIptr "l" #else #define __PRI64 "ll" #define __PRIptr #endif /* fprintf(3) macros for signed integers. */ #define PRId8 "d" /* int8_t */ #define PRId16 "d" /* int16_t */ #define PRId32 "d" /* int32_t */ #define PRId64 __PRI64"d" /* int64_t */ #define PRIdLEAST8 "d" /* int_least8_t */ #define PRIdLEAST16 "d" /* int_least16_t */ #define PRIdLEAST32 "d" /* int_least32_t */ #define PRIdLEAST64 __PRI64"d" /* int_least64_t */ #define PRIdFAST8 "d" /* int_fast8_t */ #define PRIdFAST16 "d" /* int_fast16_t */ #define PRIdFAST32 "d" /* int_fast32_t */ #define PRIdFAST64 __PRI64"d" /* int_fast64_t */ #define PRIdMAX "jd" /* intmax_t */ #define PRIdPTR __PRIptr"d" /* intptr_t */ #define PRIi8 "i" /* int8_t */ #define PRIi16 "i" /* int16_t */ #define PRIi32 "i" /* int32_t */ #define PRIi64 __PRI64"i" /* int64_t */ #define PRIiLEAST8 "i" /* int_least8_t */ #define PRIiLEAST16 "i" /* int_least16_t */ #define PRIiLEAST32 "i" /* int_least32_t */ #define PRIiLEAST64 __PRI64"i" /* int_least64_t */ #define PRIiFAST8 "i" /* int_fast8_t */ #define PRIiFAST16 "i" /* int_fast16_t */ #define PRIiFAST32 "i" /* int_fast32_t */ #define PRIiFAST64 __PRI64"i" /* int_fast64_t */ #define PRIiMAX "ji" /* intmax_t */ #define PRIiPTR __PRIptr"i" /* intptr_t */ /* fprintf(3) macros for unsigned integers. */ #define PRIo8 "o" /* uint8_t */ #define PRIo16 "o" /* uint16_t */ #define PRIo32 "o" /* uint32_t */ #define PRIo64 __PRI64"o" /* uint64_t */ #define PRIoLEAST8 "o" /* uint_least8_t */ #define PRIoLEAST16 "o" /* uint_least16_t */ #define PRIoLEAST32 "o" /* uint_least32_t */ #define PRIoLEAST64 __PRI64"o" /* uint_least64_t */ #define PRIoFAST8 "o" /* uint_fast8_t */ #define PRIoFAST16 "o" /* uint_fast16_t */ #define PRIoFAST32 "o" /* uint_fast32_t */ #define PRIoFAST64 __PRI64"o" /* uint_fast64_t */ #define PRIoMAX "jo" /* uintmax_t */ #define PRIoPTR __PRIptr"o" /* uintptr_t */ #define PRIu8 "u" /* uint8_t */ #define PRIu16 "u" /* uint16_t */ #define PRIu32 "u" /* uint32_t */ #define PRIu64 __PRI64"u" /* uint64_t */ #define PRIuLEAST8 "u" /* uint_least8_t */ #define PRIuLEAST16 "u" /* uint_least16_t */ #define PRIuLEAST32 "u" /* uint_least32_t */ #define PRIuLEAST64 __PRI64"u" /* uint_least64_t */ #define PRIuFAST8 "u" /* uint_fast8_t */ #define PRIuFAST16 "u" /* uint_fast16_t */ #define PRIuFAST32 "u" /* uint_fast32_t */ #define PRIuFAST64 __PRI64"u" /* uint_fast64_t */ #define PRIuMAX "ju" /* uintmax_t */ #define PRIuPTR __PRIptr"u" /* uintptr_t */ #define PRIx8 "x" /* uint8_t */ #define PRIx16 "x" /* uint16_t */ #define PRIx32 "x" /* uint32_t */ #define PRIx64 __PRI64"x" /* uint64_t */ #define PRIxLEAST8 "x" /* uint_least8_t */ #define PRIxLEAST16 "x" /* uint_least16_t */ #define PRIxLEAST32 "x" /* uint_least32_t */ #define PRIxLEAST64 __PRI64"x" /* uint_least64_t */ #define PRIxFAST8 "x" /* uint_fast8_t */ #define PRIxFAST16 "x" /* uint_fast16_t */ #define PRIxFAST32 "x" /* uint_fast32_t */ #define PRIxFAST64 __PRI64"x" /* uint_fast64_t */ #define PRIxMAX "jx" /* uintmax_t */ #define PRIxPTR __PRIptr"x" /* uintptr_t */ #define PRIX8 "X" /* uint8_t */ #define PRIX16 "X" /* uint16_t */ #define PRIX32 "X" /* uint32_t */ #define PRIX64 __PRI64"X" /* uint64_t */ #define PRIXLEAST8 "X" /* uint_least8_t */ #define PRIXLEAST16 "X" /* uint_least16_t */ #define PRIXLEAST32 "X" /* uint_least32_t */ #define PRIXLEAST64 __PRI64"X" /* uint_least64_t */ #define PRIXFAST8 "X" /* uint_fast8_t */ #define PRIXFAST16 "X" /* uint_fast16_t */ #define PRIXFAST32 "X" /* uint_fast32_t */ #define PRIXFAST64 __PRI64"X" /* uint_fast64_t */ #define PRIXMAX "jX" /* uintmax_t */ #define PRIXPTR __PRIptr"X" /* uintptr_t */ /* fscanf(3) macros for signed integers. */ #define SCNd8 "hhd" /* int8_t */ #define SCNd16 "hd" /* int16_t */ #define SCNd32 "d" /* int32_t */ #define SCNd64 __PRI64"d" /* int64_t */ #define SCNdLEAST8 "hhd" /* int_least8_t */ #define SCNdLEAST16 "hd" /* int_least16_t */ #define SCNdLEAST32 "d" /* int_least32_t */ #define SCNdLEAST64 __PRI64"d" /* int_least64_t */ #define SCNdFAST8 "d" /* int_fast8_t */ #define SCNdFAST16 "d" /* int_fast16_t */ #define SCNdFAST32 "d" /* int_fast32_t */ #define SCNdFAST64 __PRI64"d" /* int_fast64_t */ #define SCNdMAX "jd" /* intmax_t */ #define SCNdPTR __PRIptr"d" /* intptr_t */ #define SCNi8 "hhi" /* int8_t */ #define SCNi16 "hi" /* int16_t */ #define SCNi32 "i" /* int32_t */ #define SCNi64 __PRI64"i" /* int64_t */ #define SCNiLEAST8 "hhi" /* int_least8_t */ #define SCNiLEAST16 "hi" /* int_least16_t */ #define SCNiLEAST32 "i" /* int_least32_t */ #define SCNiLEAST64 __PRI64"i" /* int_least64_t */ #define SCNiFAST8 "i" /* int_fast8_t */ #define SCNiFAST16 "i" /* int_fast16_t */ #define SCNiFAST32 "i" /* int_fast32_t */ #define SCNiFAST64 __PRI64"i" /* int_fast64_t */ #define SCNiMAX "ji" /* intmax_t */ #define SCNiPTR __PRIptr"i" /* intptr_t */ /* fscanf(3) macros for unsigned integers. */ #define SCNo8 "hho" /* uint8_t */ #define SCNo16 "ho" /* uint16_t */ #define SCNo32 "o" /* uint32_t */ #define SCNo64 __PRI64"o" /* uint64_t */ #define SCNoLEAST8 "hho" /* uint_least8_t */ #define SCNoLEAST16 "ho" /* uint_least16_t */ #define SCNoLEAST32 "o" /* uint_least32_t */ #define SCNoLEAST64 __PRI64"o" /* uint_least64_t */ #define SCNoFAST8 "o" /* uint_fast8_t */ #define SCNoFAST16 "o" /* uint_fast16_t */ #define SCNoFAST32 "o" /* uint_fast32_t */ #define SCNoFAST64 __PRI64"o" /* uint_fast64_t */ #define SCNoMAX "jo" /* uintmax_t */ #define SCNoPTR __PRIptr"o" /* uintptr_t */ #define SCNu8 "hhu" /* uint8_t */ #define SCNu16 "hu" /* uint16_t */ #define SCNu32 "u" /* uint32_t */ #define SCNu64 __PRI64"u" /* uint64_t */ #define SCNuLEAST8 "hhu" /* uint_least8_t */ #define SCNuLEAST16 "hu" /* uint_least16_t */ #define SCNuLEAST32 "u" /* uint_least32_t */ #define SCNuLEAST64 __PRI64"u" /* uint_least64_t */ #define SCNuFAST8 "u" /* uint_fast8_t */ #define SCNuFAST16 "u" /* uint_fast16_t */ #define SCNuFAST32 "u" /* uint_fast32_t */ #define SCNuFAST64 __PRI64"u" /* uint_fast64_t */ #define SCNuMAX "ju" /* uintmax_t */ #define SCNuPTR __PRIptr"u" /* uintptr_t */ #define SCNx8 "hhx" /* uint8_t */ #define SCNx16 "hx" /* uint16_t */ #define SCNx32 "x" /* uint32_t */ #define SCNx64 __PRI64"x" /* uint64_t */ #define SCNxLEAST8 "hhx" /* uint_least8_t */ #define SCNxLEAST16 "hx" /* uint_least16_t */ #define SCNxLEAST32 "x" /* uint_least32_t */ #define SCNxLEAST64 __PRI64"x" /* uint_least64_t */ #define SCNxFAST8 "x" /* uint_fast8_t */ #define SCNxFAST16 "x" /* uint_fast16_t */ #define SCNxFAST32 "x" /* uint_fast32_t */ #define SCNxFAST64 __PRI64"x" /* uint_fast64_t */ #define SCNxMAX "jx" /* uintmax_t */ #define SCNxPTR __PRIptr"x" /* uintptr_t */ #endif /* !_MACHINE_INTTYPES_H_ */ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)limits.h 8.3 (Berkeley) 1/4/94 * $FreeBSD$ */ #ifndef _MACHINE__LIMITS_H_ #define _MACHINE__LIMITS_H_ /* * According to ANSI (section 2.2.4.2), the values below must be usable by * #if preprocessing directives. Additionally, the expression must have the * same type as would an expression that is an object of the corresponding * type converted according to the integral promotions. The subtraction for * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2). */ #define __CHAR_BIT 8 /* number of bits in a char */ #define __SCHAR_MAX 0x7f /* max value for a signed char */ #define __SCHAR_MIN (-0x7f - 1) /* min value for a signed char */ #define __UCHAR_MAX 0xff /* max value for an unsigned char */ #define __USHRT_MAX 0xffff /* max value for an unsigned short */ #define __SHRT_MAX 0x7fff /* max value for a short */ #define __SHRT_MIN (-0x7fff - 1) /* min value for a short */ #define __UINT_MAX 0xffffffff /* max value for an unsigned int */ #define __INT_MAX 0x7fffffff /* max value for an int */ #define __INT_MIN (-0x7fffffff - 1) /* min value for an int */ #ifdef __LP64__ #define __ULONG_MAX 0xffffffffffffffff /* max for an unsigned long */ #define __LONG_MAX 0x7fffffffffffffff /* max for a long */ #define __LONG_MIN (-0x7fffffffffffffff - 1) /* min for a long */ #else #define __ULONG_MAX 0xffffffffUL #define __LONG_MAX 0x7fffffffL #define __LONG_MIN (-0x7fffffffL - 1) #endif /* max value for an unsigned long long */ #define __ULLONG_MAX 0xffffffffffffffffULL #define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */ #define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */ #ifdef __LP64__ #define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */ #define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */ #define __OFF_MAX __LONG_MAX /* max value for an off_t */ #define __OFF_MIN __LONG_MIN /* min value for an off_t */ /* Quads and longs are the same on the amd64. Ensure they stay in sync. */ #define __UQUAD_MAX __ULONG_MAX /* max value for a uquad_t */ #define __QUAD_MAX __LONG_MAX /* max value for a quad_t */ #define __QUAD_MIN __LONG_MIN /* min value for a quad_t */ #define __LONG_BIT 64 #else #define __SSIZE_MAX __INT_MAX #define __SIZE_T_MAX __UINT_MAX #define __OFF_MAX __LLONG_MAX #define __OFF_MIN __LLONG_MIN #define __UQUAD_MAX __ULLONG_MAX #define __QUAD_MAX __LLONG_MAX #define __QUAD_MIN __LLONG_MIN #define __LONG_BIT 32 #endif #define __WORD_BIT 32 /* Minimum signal stack size. */ #define __MINSIGSTKSZ (512 * 4) #endif /* !_MACHINE__LIMITS_H_ */ /*- * Copyright (c) 2001, 2002 Mike Barcroft * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Klaus Klein. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. * * $FreeBSD$ */ #ifndef _MACHINE__STDINT_H_ #define _MACHINE__STDINT_H_ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) #define INT8_C(c) (c) #define INT16_C(c) (c) #define INT32_C(c) (c) #define UINT8_C(c) (c) #define UINT16_C(c) (c) #define UINT32_C(c) (c ## U) #ifdef __LP64__ #define INT64_C(c) (c ## L) #define UINT64_C(c) (c ## UL) #else #define INT64_C(c) (c ## LL) #define UINT64_C(c) (c ## ULL) #endif #define INTMAX_C(c) INT64_C(c) #define UINTMAX_C(c) UINT64_C(c) #endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) /* * ISO/IEC 9899:1999 * 7.18.2.1 Limits of exact-width integer types */ #define INT8_MIN (-0x7f-1) #define INT16_MIN (-0x7fff-1) #define INT32_MIN (-0x7fffffff-1) #define INT8_MAX 0x7f #define INT16_MAX 0x7fff #define INT32_MAX 0x7fffffff #define UINT8_MAX 0xff #define UINT16_MAX 0xffff #define UINT32_MAX 0xffffffffU #ifdef __LP64__ #define INT64_MIN (-0x7fffffffffffffff-1) #define INT64_MAX 0x7fffffffffffffff #define UINT64_MAX 0xffffffffffffffff #else #define INT64_MIN (-0x7fffffffffffffffLL-1) #define INT64_MAX 0x7fffffffffffffffLL #define UINT64_MAX 0xffffffffffffffffULL #endif /* * ISO/IEC 9899:1999 * 7.18.2.2 Limits of minimum-width integer types */ /* Minimum values of minimum-width signed integer types. */ #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST64_MIN INT64_MIN /* Maximum values of minimum-width signed integer types. */ #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MAX INT64_MAX /* Maximum values of minimum-width unsigned integer types. */ #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX /* * ISO/IEC 9899:1999 * 7.18.2.3 Limits of fastest minimum-width integer types */ /* Minimum values of fastest minimum-width signed integer types. */ #define INT_FAST8_MIN INT32_MIN #define INT_FAST16_MIN INT32_MIN #define INT_FAST32_MIN INT32_MIN #define INT_FAST64_MIN INT64_MIN /* Maximum values of fastest minimum-width signed integer types. */ #define INT_FAST8_MAX INT32_MAX #define INT_FAST16_MAX INT32_MAX #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MAX INT64_MAX /* Maximum values of fastest minimum-width unsigned integer types. */ #define UINT_FAST8_MAX UINT32_MAX #define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX /* * ISO/IEC 9899:1999 * 7.18.2.4 Limits of integer types capable of holding object pointers */ #ifdef __LP64__ #define INTPTR_MIN INT64_MIN #define INTPTR_MAX INT64_MAX #define UINTPTR_MAX UINT64_MAX #else #define INTPTR_MIN INT32_MIN #define INTPTR_MAX INT32_MAX #define UINTPTR_MAX UINT32_MAX #endif /* * ISO/IEC 9899:1999 * 7.18.2.5 Limits of greatest-width integer types */ #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX /* * ISO/IEC 9899:1999 * 7.18.3 Limits of other integer types */ #ifdef __LP64__ /* Limits of ptrdiff_t. */ #define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MAX INT64_MAX /* Limits of sig_atomic_t. */ #define SIG_ATOMIC_MIN LONG_MIN #define SIG_ATOMIC_MAX LONG_MAX /* Limit of size_t. */ #define SIZE_MAX UINT64_MAX #else #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX #define SIZE_MAX UINT32_MAX #endif /* Limits of wint_t. */ #define WINT_MIN INT32_MIN #define WINT_MAX INT32_MAX #endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ #endif /* !_MACHINE__STDINT_H_ */ /*- * Copyright (c) 2002 Mike Barcroft * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94 * From: @(#)types.h 8.3 (Berkeley) 1/5/94 * $FreeBSD$ */ #ifndef _MACHINE__TYPES_H_ #define _MACHINE__TYPES_H_ #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif #define __NO_STRICT_ALIGNMENT /* * Basic types upon which most other types are built. */ typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef short __int16_t; typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; #ifdef __LP64__ typedef long __int64_t; typedef unsigned long __uint64_t; #else #ifndef lint __extension__ #endif /* LONGLONG */ typedef long long __int64_t; #ifndef lint __extension__ #endif /* LONGLONG */ typedef unsigned long long __uint64_t; #endif /* * Standard type definitions. */ #ifdef __LP64__ typedef __int32_t __clock_t; /* clock()... */ typedef __int64_t __critical_t; typedef double __double_t; typedef float __float_t; typedef __int64_t __intfptr_t; typedef __int64_t __intptr_t; #else typedef unsigned long __clock_t; typedef __int32_t __critical_t; typedef long double __double_t; typedef long double __float_t; typedef __int32_t __intfptr_t; typedef __int32_t __intptr_t; #endif typedef __int64_t __intmax_t; typedef __int32_t __int_fast8_t; typedef __int32_t __int_fast16_t; typedef __int32_t __int_fast32_t; typedef __int64_t __int_fast64_t; typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; #ifdef __LP64__ typedef __int64_t __ptrdiff_t; /* ptr1 - ptr2 */ typedef __int64_t __register_t; typedef __int64_t __segsz_t; /* segment size (in pages) */ typedef __uint64_t __size_t; /* sizeof() */ typedef __int64_t __ssize_t; /* byte count or error */ typedef __int64_t __time_t; /* time()... */ typedef __uint64_t __uintfptr_t; typedef __uint64_t __uintptr_t; #else typedef __int32_t __ptrdiff_t; typedef __int32_t __register_t; typedef __int32_t __segsz_t; typedef __uint32_t __size_t; typedef __int32_t __ssize_t; typedef __int32_t __time_t; typedef __uint32_t __uintfptr_t; typedef __uint32_t __uintptr_t; #endif typedef __uint64_t __uintmax_t; typedef __uint32_t __uint_fast8_t; typedef __uint32_t __uint_fast16_t; typedef __uint32_t __uint_fast32_t; typedef __uint64_t __uint_fast64_t; typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; #ifdef __LP64__ typedef __uint64_t __u_register_t; typedef __uint64_t __vm_offset_t; typedef __uint64_t __vm_paddr_t; typedef __uint64_t __vm_size_t; #else typedef __uint32_t __u_register_t; typedef __uint32_t __vm_offset_t; #ifdef PAE typedef __uint64_t __vm_paddr_t; #else typedef __uint32_t __vm_paddr_t; #endif typedef __uint32_t __vm_size_t; #endif typedef __int64_t __vm_ooffset_t; typedef __uint64_t __vm_pindex_t; typedef int ___wchar_t; #define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */ #define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */ /* * Unusual type definitions. */ #ifdef __GNUCLIKE_BUILTIN_VARARGS typedef __builtin_va_list __va_list; /* internally known to gcc */ #else #ifdef __LP64__ struct __s_va_list { __uint32_t _pad1[2]; /* gp_offset, fp_offset */ __uint64_t _pad2[2]; /* overflow_arg_area, reg_save_area */ }; typedef struct __s_va_list __va_list; #else typedef char * __va_list; #endif #endif #if defined(__GNUC_VA_LIST_COMPATIBILITY) && !defined(__GNUC_VA_LIST) \ && !defined(__NO_GNUC_VA_LIST) #define __GNUC_VA_LIST typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/ #endif #endif /* !_MACHINE__TYPES_H_ */ /*- * Copyright (c) 1996-1997 John D. Polstra. * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _MACHINE_ELF_H_ #define _MACHINE_ELF_H_ 1 #if defined(__i386__) || defined(_MACHINE_ELF_WANT_32BIT) /* * ELF definitions for the i386 architecture. */ #include /* Definitions common to all 32 bit architectures. */ #if defined(__ELF_WORD_SIZE) && __ELF_WORD_SIZE == 64 #include /* Definitions common to all 64 bit architectures. */ #endif #ifndef __ELF_WORD_SIZE #define __ELF_WORD_SIZE 32 /* Used by */ #endif #include #define ELF_ARCH EM_386 #define ELF_MACHINE_OK(x) ((x) == EM_386 || (x) == EM_486) /* * Auxiliary vector entries for passing information to the interpreter. * * The i386 supplement to the SVR4 ABI specification names this "auxv_t", * but POSIX lays claim to all symbols ending with "_t". */ typedef struct { /* Auxiliary vector entry on initial stack */ int a_type; /* Entry type. */ union { long a_val; /* Integer value. */ void *a_ptr; /* Address. */ void (*a_fcn)(void); /* Function pointer (not used). */ } a_un; } Elf32_Auxinfo; #if __ELF_WORD_SIZE == 64 /* Fake for amd64 loader support */ typedef struct { int fake; } Elf64_Auxinfo; #endif __ElfType(Auxinfo); /* Values for a_type. */ #define AT_NULL 0 /* Terminates the vector. */ #define AT_IGNORE 1 /* Ignored entry. */ #define AT_EXECFD 2 /* File descriptor of program to load. */ #define AT_PHDR 3 /* Program header of program already loaded. */ #define AT_PHENT 4 /* Size of each program header entry. */ #define AT_PHNUM 5 /* Number of program header entries. */ #define AT_PAGESZ 6 /* Page size in bytes. */ #define AT_BASE 7 /* Interpreter's base address. */ #define AT_FLAGS 8 /* Flags (unused for i386). */ #define AT_ENTRY 9 /* Where interpreter should transfer control. */ #define AT_NOTELF 10 /* Program is not ELF ?? */ #define AT_UID 11 /* Real uid. */ #define AT_EUID 12 /* Effective uid. */ #define AT_GID 13 /* Real gid. */ #define AT_EGID 14 /* Effective gid. */ #define AT_EXECPATH 15 /* Path to the executable. */ #define AT_CANARY 16 /* Canary for SSP. */ #define AT_CANARYLEN 17 /* Length of the canary. */ #define AT_OSRELDATE 18 /* OSRELDATE. */ #define AT_NCPUS 19 /* Number of CPUs. */ #define AT_PAGESIZES 20 /* Pagesizes. */ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ #define AT_COUNT 24 /* Count of defined aux entry types. */ /* * Relocation types. */ #define R_386_COUNT 38 /* Count of defined relocation types. */ /* Define "machine" characteristics */ #define ELF_TARG_CLASS ELFCLASS32 #define ELF_TARG_DATA ELFDATA2LSB #define ELF_TARG_MACH EM_386 #define ELF_TARG_VER 1 #define ET_DYN_LOAD_ADDR 0x01001000 #elif defined(__amd64__) /* * ELF definitions for the AMD64 architecture. */ #ifndef __ELF_WORD_SIZE #define __ELF_WORD_SIZE 64 /* Used by */ #endif #include /* Definitions common to all 32 bit architectures. */ #include /* Definitions common to all 64 bit architectures. */ #include #define ELF_ARCH EM_X86_64 #define ELF_ARCH32 EM_386 #define ELF_MACHINE_OK(x) ((x) == EM_X86_64) /* * Auxiliary vector entries for passing information to the interpreter. * * The i386 supplement to the SVR4 ABI specification names this "auxv_t", * but POSIX lays claim to all symbols ending with "_t". */ typedef struct { /* Auxiliary vector entry on initial stack */ int a_type; /* Entry type. */ union { int a_val; /* Integer value. */ } a_un; } Elf32_Auxinfo; typedef struct { /* Auxiliary vector entry on initial stack */ long a_type; /* Entry type. */ union { long a_val; /* Integer value. */ void *a_ptr; /* Address. */ void (*a_fcn)(void); /* Function pointer (not used). */ } a_un; } Elf64_Auxinfo; __ElfType(Auxinfo); /* Values for a_type. */ #define AT_NULL 0 /* Terminates the vector. */ #define AT_IGNORE 1 /* Ignored entry. */ #define AT_EXECFD 2 /* File descriptor of program to load. */ #define AT_PHDR 3 /* Program header of program already loaded. */ #define AT_PHENT 4 /* Size of each program header entry. */ #define AT_PHNUM 5 /* Number of program header entries. */ #define AT_PAGESZ 6 /* Page size in bytes. */ #define AT_BASE 7 /* Interpreter's base address. */ #define AT_FLAGS 8 /* Flags (unused for i386). */ #define AT_ENTRY 9 /* Where interpreter should transfer control. */ #define AT_NOTELF 10 /* Program is not ELF ?? */ #define AT_UID 11 /* Real uid. */ #define AT_EUID 12 /* Effective uid. */ #define AT_GID 13 /* Real gid. */ #define AT_EGID 14 /* Effective gid. */ #define AT_EXECPATH 15 /* Path to the executable. */ #define AT_CANARY 16 /* Canary for SSP */ #define AT_CANARYLEN 17 /* Length of the canary. */ #define AT_OSRELDATE 18 /* OSRELDATE. */ #define AT_NCPUS 19 /* Number of CPUs. */ #define AT_PAGESIZES 20 /* Pagesizes. */ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ #define AT_COUNT 24 /* Count of defined aux entry types. */ /* * Relocation types. */ #define R_X86_64_COUNT 24 /* Count of defined relocation types. */ /* Define "machine" characteristics */ #if __ELF_WORD_SIZE == 32 #define ELF_TARG_CLASS ELFCLASS32 #else #define ELF_TARG_CLASS ELFCLASS64 #endif #define ELF_TARG_DATA ELFDATA2LSB #define ELF_TARG_MACH EM_X86_64 #define ELF_TARG_VER 1 #if __ELF_WORD_SIZE == 32 #define ET_DYN_LOAD_ADDR 0x01001000 #else #define ET_DYN_LOAD_ADDR 0x01021000 #endif #endif /* __i386__, __amd64__ */ #endif /* !_MACHINE_ELF_H_ */ /*- * Copyright (c) 1987, 1991 Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)endian.h 7.8 (Berkeley) 4/3/91 * $FreeBSD$ */ #ifndef _MACHINE_ENDIAN_H_ #define _MACHINE_ENDIAN_H_ #include #include /* * Define the order of 32-bit words in 64-bit words. */ #define _QUAD_HIGHWORD 1 #define _QUAD_LOWWORD 0 /* * Definitions for byte order, according to byte significance from low * address to high. */ #define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ #define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */ #define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */ #define _BYTE_ORDER _LITTLE_ENDIAN /* * Deprecated variants that don't have enough underscores to be useful in more * strict namespaces. */ #if __BSD_VISIBLE #define LITTLE_ENDIAN _LITTLE_ENDIAN #define BIG_ENDIAN _BIG_ENDIAN #define PDP_ENDIAN _PDP_ENDIAN #define BYTE_ORDER _BYTE_ORDER #endif #define __bswap16_gen(x) (__uint16_t)((x) << 8 | (x) >> 8) #define __bswap32_gen(x) \ (((__uint32_t)__bswap16((x) & 0xffff) << 16) | __bswap16((x) >> 16)) #define __bswap64_gen(x) \ (((__uint64_t)__bswap32((x) & 0xffffffff) << 32) | __bswap32((x) >> 32)) #ifdef __GNUCLIKE_BUILTIN_CONSTANT_P #define __bswap16(x) \ ((__uint16_t)(__builtin_constant_p(x) ? \ __bswap16_gen((__uint16_t)(x)) : __bswap16_var(x))) #define __bswap32(x) \ (__builtin_constant_p(x) ? \ __bswap32_gen((__uint32_t)(x)) : __bswap32_var(x)) #define __bswap64(x) \ (__builtin_constant_p(x) ? \ __bswap64_gen((__uint64_t)(x)) : __bswap64_var(x)) #else /* XXX these are broken for use in static initializers. */ #define __bswap16(x) __bswap16_var(x) #define __bswap32(x) __bswap32_var(x) #define __bswap64(x) __bswap64_var(x) #endif /* These are defined as functions to avoid multiple evaluation of x. */ static __inline __uint16_t __bswap16_var(__uint16_t _x) { return (__bswap16_gen(_x)); } static __inline __uint32_t __bswap32_var(__uint32_t _x) { #ifdef __GNUCLIKE_ASM __asm("bswap %0" : "+r" (_x)); return (_x); #else return (__bswap32_gen(_x)); #endif } static __inline __uint64_t __bswap64_var(__uint64_t _x) { #if defined(__amd64__) && defined(__GNUCLIKE_ASM) __asm("bswap %0" : "+r" (_x)); return (_x); #else /* * It is important for the optimizations that the following is not * really generic, but expands to 2 __bswap32_var()'s. */ return (__bswap64_gen(_x)); #endif } #define __htonl(x) __bswap32(x) #define __htons(x) __bswap16(x) #define __ntohl(x) __bswap32(x) #define __ntohs(x) __bswap16(x) #endif /* !_MACHINE_ENDIAN_H_ */ /*- * Copyright (c) 2003 Peter Wemm. * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)frame.h 5.2 (Berkeley) 1/18/91 */ #ifndef _MACHINE_FRAME_H_ #define _MACHINE_FRAME_H_ 1 /* * System stack frames. */ #if defined(__i386__) && !defined(__amd64__) /* * Exception/Trap Stack Frame */ struct trapframe { int tf_fs; int tf_es; int tf_ds; int tf_edi; int tf_esi; int tf_ebp; int tf_isp; int tf_ebx; int tf_edx; int tf_ecx; int tf_eax; int tf_trapno; /* below portion defined in 386 hardware */ int tf_err; int tf_eip; int tf_cs; int tf_eflags; /* below only when crossing rings (user to kernel) */ int tf_esp; int tf_ss; }; /* Superset of trap frame, for traps from virtual-8086 mode */ struct trapframe_vm86 { int tf_fs; int tf_es; int tf_ds; int tf_edi; int tf_esi; int tf_ebp; int tf_isp; int tf_ebx; int tf_edx; int tf_ecx; int tf_eax; int tf_trapno; /* below portion defined in 386 hardware */ int tf_err; int tf_eip; int tf_cs; int tf_eflags; /* below only when crossing rings (user (including vm86) to kernel) */ int tf_esp; int tf_ss; /* below only when crossing from vm86 mode to kernel */ int tf_vm86_es; int tf_vm86_ds; int tf_vm86_fs; int tf_vm86_gs; }; /* * This alias for the MI TRAPF_USERMODE() should be used when we don't * care about user mode itself, but need to know if a frame has stack * registers. The difference is only logical, but on i386 the logic * for using TRAPF_USERMODE() is complicated by sometimes treating vm86 * bioscall mode (which is a special ring 3 user mode) as kernel mode. */ #define TF_HAS_STACKREGS(tf) TRAPF_USERMODE(tf) #endif /* __i386__ */ #ifdef __amd64__ /* * Exception/Trap Stack Frame * * The ordering of this is specifically so that we can take first 6 * the syscall arguments directly from the beginning of the frame. */ struct trapframe { register_t tf_rdi; register_t tf_rsi; register_t tf_rdx; register_t tf_rcx; register_t tf_r8; register_t tf_r9; register_t tf_rax; register_t tf_rbx; register_t tf_rbp; register_t tf_r10; register_t tf_r11; register_t tf_r12; register_t tf_r13; register_t tf_r14; register_t tf_r15; uint32_t tf_trapno; uint16_t tf_fs; uint16_t tf_gs; register_t tf_addr; uint32_t tf_flags; uint16_t tf_es; uint16_t tf_ds; /* below portion defined in hardware */ register_t tf_err; register_t tf_rip; register_t tf_cs; register_t tf_rflags; /* the amd64 frame always has the stack registers */ register_t tf_rsp; register_t tf_ss; }; #define TF_HASSEGS 0x1 #define TF_HASBASES 0x2 #define TF_HASFPXSTATE 0x4 #endif /* __amd64__ */ #endif /* _MACHINE_FRAME_H_ */ /*- * Copyright (c) 2003 Peter Wemm * All rights reserved. * * 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. * * 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. * * $FreeBSD$ */ #ifndef _MACHINE_METADATA_H_ #define _MACHINE_METADATA_H_ #define MODINFOMD_SMAP 0x1001 #define MODINFOMD_SMAP_XATTR 0x1002 #define MODINFOMD_DTBP 0x1003 #define MODINFOMD_EFI_MAP 0x1004 #define MODINFOMD_EFI_FB 0x1005 #define MODINFOMD_MODULEP 0x1006 struct efi_map_header { uint64_t memory_size; uint64_t descriptor_size; uint32_t descriptor_version; }; struct efi_fb { uint64_t fb_addr; uint64_t fb_size; uint32_t fb_height; uint32_t fb_width; uint32_t fb_stride; uint32_t fb_mask_red; uint32_t fb_mask_green; uint32_t fb_mask_blue; uint32_t fb_mask_reserved; }; #endif /* !_MACHINE_METADATA_H_ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)psl.h 5.2 (Berkeley) 1/18/91 * $FreeBSD$ */ #ifndef _MACHINE_PSL_H_ #define _MACHINE_PSL_H_ /* * 386 processor status longword. */ #define PSL_C 0x00000001 /* carry bit */ #define PSL_PF 0x00000004 /* parity bit */ #define PSL_AF 0x00000010 /* bcd carry bit */ #define PSL_Z 0x00000040 /* zero bit */ #define PSL_N 0x00000080 /* negative bit */ #define PSL_T 0x00000100 /* trace enable bit */ #define PSL_I 0x00000200 /* interrupt enable bit */ #define PSL_D 0x00000400 /* string instruction direction bit */ #define PSL_V 0x00000800 /* overflow bit */ #define PSL_IOPL 0x00003000 /* i/o privilege level */ #define PSL_NT 0x00004000 /* nested task bit */ #define PSL_RF 0x00010000 /* resume flag bit */ #define PSL_VM 0x00020000 /* virtual 8086 mode bit */ #define PSL_AC 0x00040000 /* alignment checking */ #define PSL_VIF 0x00080000 /* virtual interrupt enable */ #define PSL_VIP 0x00100000 /* virtual interrupt pending */ #define PSL_ID 0x00200000 /* identification bit */ /* * The i486 manual says that we are not supposed to change reserved flags, * but this is too much trouble since the reserved flags depend on the cpu * and setting them to their historical values works in practice. */ #define PSL_RESERVED_DEFAULT 0x00000002 /* * Initial flags for kernel and user mode. The kernel later inherits * PSL_I and some other flags from user mode. */ #define PSL_KERNEL PSL_RESERVED_DEFAULT #define PSL_USER (PSL_RESERVED_DEFAULT | PSL_I) /* * Bits that can be changed in user mode on 486's. We allow these bits * to be changed using ptrace(), sigreturn() and procfs. Setting PS_NT * is undesirable but it may as well be allowed since users can inflict * it on the kernel directly. Changes to PSL_AC are silently ignored on * 386's. * * Users are allowed to change the privileged flag PSL_RF. The cpu sets PSL_RF * in tf_eflags for faults. Debuggers should sometimes set it there too. * tf_eflags is kept in the signal context during signal handling and there is * no other place to remember it, so the PSL_RF bit may be corrupted by the * signal handler without us knowing. Corruption of the PSL_RF bit at worst * causes one more or one less debugger trap, so allowing it is fairly * harmless. */ #define PSL_USERCHANGE (PSL_C | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_T \ | PSL_D | PSL_V | PSL_NT | PSL_RF | PSL_AC | PSL_ID) #endif /* !_MACHINE_PSL_H_ */ /*- * Copyright (c) 1989, 1990 William F. Jolitz * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 */ #ifndef _X86_SEGMENTS_H_ #define _X86_SEGMENTS_H_ /* * X86 Segmentation Data Structures and definitions */ /* * Selectors */ #define SEL_RPL_MASK 3 /* requester priv level */ #define ISPL(s) ((s)&3) /* priority level of a selector */ #define SEL_KPL 0 /* kernel priority level */ #define SEL_UPL 3 /* user priority level */ #define ISLDT(s) ((s)&SEL_LDT) /* is it local or global */ #define SEL_LDT 4 /* local descriptor table */ #define IDXSEL(s) (((s)>>3) & 0x1fff) /* index of selector */ #define LSEL(s,r) (((s)<<3) | SEL_LDT | r) /* a local selector */ #define GSEL(s,r) (((s)<<3) | r) /* a global selector */ /* * User segment descriptors (%cs, %ds etc for i386 apps. 64 bit wide) * For long-mode apps, %cs only has the conforming bit in sd_type, the sd_dpl, * sd_p, sd_l and sd_def32 which must be zero). %ds only has sd_p. */ struct segment_descriptor { unsigned sd_lolimit:16; /* segment extent (lsb) */ unsigned sd_lobase:24; /* segment base address (lsb) */ unsigned sd_type:5; /* segment type */ unsigned sd_dpl:2; /* segment descriptor priority level */ unsigned sd_p:1; /* segment descriptor present */ unsigned sd_hilimit:4; /* segment extent (msb) */ unsigned sd_xx:2; /* unused */ unsigned sd_def32:1; /* default 32 vs 16 bit size */ unsigned sd_gran:1; /* limit granularity (byte/page units)*/ unsigned sd_hibase:8; /* segment base address (msb) */ } __packed; struct user_segment_descriptor { unsigned sd_lolimit:16; /* segment extent (lsb) */ unsigned sd_lobase:24; /* segment base address (lsb) */ unsigned sd_type:5; /* segment type */ unsigned sd_dpl:2; /* segment descriptor priority level */ unsigned sd_p:1; /* segment descriptor present */ unsigned sd_hilimit:4; /* segment extent (msb) */ unsigned sd_xx:1; /* unused */ unsigned sd_long:1; /* long mode (cs only) */ unsigned sd_def32:1; /* default 32 vs 16 bit size */ unsigned sd_gran:1; /* limit granularity (byte/page units)*/ unsigned sd_hibase:8; /* segment base address (msb) */ } __packed; #define USD_GETBASE(sd) (((sd)->sd_lobase) | (sd)->sd_hibase << 24) #define USD_SETBASE(sd, b) (sd)->sd_lobase = (b); \ (sd)->sd_hibase = ((b) >> 24); #define USD_GETLIMIT(sd) (((sd)->sd_lolimit) | (sd)->sd_hilimit << 16) #define USD_SETLIMIT(sd, l) (sd)->sd_lolimit = (l); \ (sd)->sd_hilimit = ((l) >> 16); #ifdef __i386__ /* * Gate descriptors (e.g. indirect descriptors) */ struct gate_descriptor { unsigned gd_looffset:16; /* gate offset (lsb) */ unsigned gd_selector:16; /* gate segment selector */ unsigned gd_stkcpy:5; /* number of stack wds to cpy */ unsigned gd_xx:3; /* unused */ unsigned gd_type:5; /* segment type */ unsigned gd_dpl:2; /* segment descriptor priority level */ unsigned gd_p:1; /* segment descriptor present */ unsigned gd_hioffset:16; /* gate offset (msb) */ } __packed; /* * Generic descriptor */ union descriptor { struct segment_descriptor sd; struct gate_descriptor gd; }; #else /* * Gate descriptors (e.g. indirect descriptors, trap, interrupt etc. 128 bit) * Only interrupt and trap gates have gd_ist. */ struct gate_descriptor { uint64_t gd_looffset:16; /* gate offset (lsb) */ uint64_t gd_selector:16; /* gate segment selector */ uint64_t gd_ist:3; /* IST table index */ uint64_t gd_xx:5; /* unused */ uint64_t gd_type:5; /* segment type */ uint64_t gd_dpl:2; /* segment descriptor priority level */ uint64_t gd_p:1; /* segment descriptor present */ uint64_t gd_hioffset:48; /* gate offset (msb) */ uint64_t sd_xx1:32; } __packed; /* * Generic descriptor */ union descriptor { struct user_segment_descriptor sd; struct gate_descriptor gd; }; #endif /* system segments and gate types */ #define SDT_SYSNULL 0 /* system null */ #define SDT_SYS286TSS 1 /* system 286 TSS available */ #define SDT_SYSLDT 2 /* system local descriptor table */ #define SDT_SYS286BSY 3 /* system 286 TSS busy */ #define SDT_SYS286CGT 4 /* system 286 call gate */ #define SDT_SYSTASKGT 5 /* system task gate */ #define SDT_SYS286IGT 6 /* system 286 interrupt gate */ #define SDT_SYS286TGT 7 /* system 286 trap gate */ #define SDT_SYSNULL2 8 /* system null again */ #define SDT_SYS386TSS 9 /* system 386 TSS available */ #define SDT_SYSTSS 9 /* system available 64 bit TSS */ #define SDT_SYSNULL3 10 /* system null again */ #define SDT_SYS386BSY 11 /* system 386 TSS busy */ #define SDT_SYSBSY 11 /* system busy 64 bit TSS */ #define SDT_SYS386CGT 12 /* system 386 call gate */ #define SDT_SYSCGT 12 /* system 64 bit call gate */ #define SDT_SYSNULL4 13 /* system null again */ #define SDT_SYS386IGT 14 /* system 386 interrupt gate */ #define SDT_SYSIGT 14 /* system 64 bit interrupt gate */ #define SDT_SYS386TGT 15 /* system 386 trap gate */ #define SDT_SYSTGT 15 /* system 64 bit trap gate */ /* memory segment types */ #define SDT_MEMRO 16 /* memory read only */ #define SDT_MEMROA 17 /* memory read only accessed */ #define SDT_MEMRW 18 /* memory read write */ #define SDT_MEMRWA 19 /* memory read write accessed */ #define SDT_MEMROD 20 /* memory read only expand dwn limit */ #define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */ #define SDT_MEMRWD 22 /* memory read write expand dwn limit */ #define SDT_MEMRWDA 23 /* memory read write expand dwn limit accessed*/ #define SDT_MEME 24 /* memory execute only */ #define SDT_MEMEA 25 /* memory execute only accessed */ #define SDT_MEMER 26 /* memory execute read */ #define SDT_MEMERA 27 /* memory execute read accessed */ #define SDT_MEMEC 28 /* memory execute only conforming */ #define SDT_MEMEAC 29 /* memory execute only accessed conforming */ #define SDT_MEMERC 30 /* memory execute read conforming */ #define SDT_MEMERAC 31 /* memory execute read accessed conforming */ /* * Size of IDT table */ #define NIDT 256 /* 32 reserved, 0x80 syscall, most are h/w */ #define NRSVIDT 32 /* reserved entries for cpu exceptions */ /* * Entries in the Interrupt Descriptor Table (IDT) */ #define IDT_DE 0 /* #DE: Divide Error */ #define IDT_DB 1 /* #DB: Debug */ #define IDT_NMI 2 /* Nonmaskable External Interrupt */ #define IDT_BP 3 /* #BP: Breakpoint */ #define IDT_OF 4 /* #OF: Overflow */ #define IDT_BR 5 /* #BR: Bound Range Exceeded */ #define IDT_UD 6 /* #UD: Undefined/Invalid Opcode */ #define IDT_NM 7 /* #NM: No Math Coprocessor */ #define IDT_DF 8 /* #DF: Double Fault */ #define IDT_FPUGP 9 /* Coprocessor Segment Overrun */ #define IDT_TS 10 /* #TS: Invalid TSS */ #define IDT_NP 11 /* #NP: Segment Not Present */ #define IDT_SS 12 /* #SS: Stack Segment Fault */ #define IDT_GP 13 /* #GP: General Protection Fault */ #define IDT_PF 14 /* #PF: Page Fault */ #define IDT_MF 16 /* #MF: FPU Floating-Point Error */ #define IDT_AC 17 /* #AC: Alignment Check */ #define IDT_MC 18 /* #MC: Machine Check */ #define IDT_XF 19 /* #XF: SIMD Floating-Point Exception */ #define IDT_IO_INTS NRSVIDT /* Base of IDT entries for I/O interrupts. */ #define IDT_SYSCALL 0x80 /* System Call Interrupt Vector */ #define IDT_DTRACE_RET 0x92 /* DTrace pid provider Interrupt Vector */ #define IDT_EVTCHN 0x93 /* Xen HVM Event Channel Interrupt Vector */ #if defined(__i386__) /* * Entries in the Global Descriptor Table (GDT) * Note that each 4 entries share a single 32 byte L1 cache line. * Some of the fast syscall instructions require a specific order here. */ #define GNULL_SEL 0 /* Null Descriptor */ #define GPRIV_SEL 1 /* SMP Per-Processor Private Data */ #define GUFS_SEL 2 /* User %fs Descriptor (order critical: 1) */ #define GUGS_SEL 3 /* User %gs Descriptor (order critical: 2) */ #define GCODE_SEL 4 /* Kernel Code Descriptor (order critical: 1) */ #define GDATA_SEL 5 /* Kernel Data Descriptor (order critical: 2) */ #define GUCODE_SEL 6 /* User Code Descriptor (order critical: 3) */ #define GUDATA_SEL 7 /* User Data Descriptor (order critical: 4) */ #define GBIOSLOWMEM_SEL 8 /* BIOS low memory access (must be entry 8) */ #define GPROC0_SEL 9 /* Task state process slot zero and up */ #define GLDT_SEL 10 /* Default User LDT */ #define GUSERLDT_SEL 11 /* User LDT */ #define GPANIC_SEL 12 /* Task state to consider panic from */ #define GBIOSCODE32_SEL 13 /* BIOS interface (32bit Code) */ #define GBIOSCODE16_SEL 14 /* BIOS interface (16bit Code) */ #define GBIOSDATA_SEL 15 /* BIOS interface (Data) */ #define GBIOSUTIL_SEL 16 /* BIOS interface (Utility) */ #define GBIOSARGS_SEL 17 /* BIOS interface (Arguments) */ #define GNDIS_SEL 18 /* For the NDIS layer */ #define NGDT 19 /* * Entries in the Local Descriptor Table (LDT) */ #define LSYS5CALLS_SEL 0 /* forced by intel BCS */ #define LSYS5SIGR_SEL 1 #define LUCODE_SEL 3 #define LUDATA_SEL 5 #define NLDT (LUDATA_SEL + 1) #else /* !__i386__ */ /* * Entries in the Global Descriptor Table (GDT) */ #define GNULL_SEL 0 /* Null Descriptor */ #define GNULL2_SEL 1 /* Null Descriptor */ #define GUFS32_SEL 2 /* User 32 bit %fs Descriptor */ #define GUGS32_SEL 3 /* User 32 bit %gs Descriptor */ #define GCODE_SEL 4 /* Kernel Code Descriptor */ #define GDATA_SEL 5 /* Kernel Data Descriptor */ #define GUCODE32_SEL 6 /* User 32 bit code Descriptor */ #define GUDATA_SEL 7 /* User 32/64 bit Data Descriptor */ #define GUCODE_SEL 8 /* User 64 bit Code Descriptor */ #define GPROC0_SEL 9 /* TSS for entering kernel etc */ /* slot 10 is second half of GPROC0_SEL */ #define GUSERLDT_SEL 11 /* LDT */ /* slot 12 is second half of GUSERLDT_SEL */ #define NGDT 13 #endif /* __i386__ */ #endif /* !_X86_SEGMENTS_H_ */ /*- * Copyright (c) 1998 John Birrell . * All rights reserved. * * 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. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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. * * $FreeBSD$ */ #ifndef _MACHINE_SETJMP_H_ #define _MACHINE_SETJMP_H_ #include #define _JBLEN 12 /* Size of the jmp_buf on AMD64. */ /* * jmp_buf and sigjmp_buf are encapsulated in different structs to force * compile-time diagnostics for mismatches. The structs are the same * internally to avoid some run-time errors for mismatches. */ #if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE typedef struct _sigjmp_buf { long _sjb[_JBLEN]; } sigjmp_buf[1]; #endif typedef struct _jmp_buf { long _jb[_JBLEN]; } jmp_buf[1]; #endif /* !_MACHINE_SETJMP_H_ */ /*- * Copyright (c) 1986, 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. * Copyright (c) 2003 Peter Wemm. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)signal.h 8.1 (Berkeley) 6/11/93 * $FreeBSD$ */ #ifndef _X86_SIGNAL_H #define _X86_SIGNAL_H 1 /* * Machine-dependent signal definitions */ #include #include #if __BSD_VISIBLE #include /* codes for SIGILL, SIGFPE */ #endif #if defined(__i386__) && !defined(__amd64__) typedef int sig_atomic_t; #if __BSD_VISIBLE struct sigcontext { struct __sigset sc_mask; /* signal mask to restore */ int sc_onstack; /* sigstack state to restore */ int sc_gs; /* machine state (struct trapframe) */ int sc_fs; int sc_es; int sc_ds; int sc_edi; int sc_esi; int sc_ebp; int sc_isp; int sc_ebx; int sc_edx; int sc_ecx; int sc_eax; int sc_trapno; int sc_err; int sc_eip; int sc_cs; int sc_efl; int sc_esp; int sc_ss; int sc_len; /* sizeof(mcontext_t) */ /* * See and for * the following fields. */ int sc_fpformat; int sc_ownedfp; int sc_flags; int sc_fpstate[128] __aligned(16); int sc_fsbase; int sc_gsbase; int sc_xfpustate; int sc_xfpustate_len; int sc_spare2[4]; }; #define sc_sp sc_esp #define sc_fp sc_ebp #define sc_pc sc_eip #define sc_ps sc_efl #define sc_eflags sc_efl #endif /* __BSD_VISIBLE */ #endif /* __i386__ */ #ifdef __amd64__ typedef long sig_atomic_t; #if __BSD_VISIBLE /* * Information pushed on stack when a signal is delivered. * This is used by the kernel to restore state following * execution of the signal handler. It is also made available * to the handler to allow it to restore state properly if * a non-standard exit is performed. * * The sequence of the fields/registers after sc_mask in struct * sigcontext must match those in mcontext_t and struct trapframe. */ struct sigcontext { struct __sigset sc_mask; /* signal mask to restore */ long sc_onstack; /* sigstack state to restore */ long sc_rdi; /* machine state (struct trapframe) */ long sc_rsi; long sc_rdx; long sc_rcx; long sc_r8; long sc_r9; long sc_rax; long sc_rbx; long sc_rbp; long sc_r10; long sc_r11; long sc_r12; long sc_r13; long sc_r14; long sc_r15; int sc_trapno; short sc_fs; short sc_gs; long sc_addr; int sc_flags; short sc_es; short sc_ds; long sc_err; long sc_rip; long sc_cs; long sc_rflags; long sc_rsp; long sc_ss; long sc_len; /* sizeof(mcontext_t) */ /* * See and for the following * fields. */ long sc_fpformat; long sc_ownedfp; long sc_fpstate[64] __aligned(16); long sc_fsbase; long sc_gsbase; long sc_xfpustate; long sc_xfpustate_len; long sc_spare[4]; }; #endif /* __BSD_VISIBLE */ #endif /* __amd64__ */ #endif /*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91 * $FreeBSD$ */ #ifndef _MACHINE_SPECIALREG_H_ #define _MACHINE_SPECIALREG_H_ /* * Bits in 386 special registers: */ #define CR0_PE 0x00000001 /* Protected mode Enable */ #define CR0_MP 0x00000002 /* "Math" (fpu) Present */ #define CR0_EM 0x00000004 /* EMulate FPU instructions. (trap ESC only) */ #define CR0_TS 0x00000008 /* Task Switched (if MP, trap ESC and WAIT) */ #define CR0_PG 0x80000000 /* PaGing enable */ /* * Bits in 486 special registers: */ #define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ #define CR0_WP 0x00010000 /* Write Protect (honor page protect in all modes) */ #define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */ #define CR0_NW 0x20000000 /* Not Write-through */ #define CR0_CD 0x40000000 /* Cache Disable */ #define CR3_PCID_SAVE 0x8000000000000000 #define CR3_PCID_MASK 0xfff /* * Bits in PPro special registers */ #define CR4_VME 0x00000001 /* Virtual 8086 mode extensions */ #define CR4_PVI 0x00000002 /* Protected-mode virtual interrupts */ #define CR4_TSD 0x00000004 /* Time stamp disable */ #define CR4_DE 0x00000008 /* Debugging extensions */ #define CR4_PSE 0x00000010 /* Page size extensions */ #define CR4_PAE 0x00000020 /* Physical address extension */ #define CR4_MCE 0x00000040 /* Machine check enable */ #define CR4_PGE 0x00000080 /* Page global enable */ #define CR4_PCE 0x00000100 /* Performance monitoring counter enable */ #define CR4_FXSR 0x00000200 /* Fast FPU save/restore used by OS */ #define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */ #define CR4_VMXE 0x00002000 /* enable VMX operation (Intel-specific) */ #define CR4_FSGSBASE 0x00010000 /* Enable FS/GS BASE accessing instructions */ #define CR4_PCIDE 0x00020000 /* Enable Context ID */ #define CR4_XSAVE 0x00040000 /* XSETBV/XGETBV */ #define CR4_SMEP 0x00100000 /* Supervisor-Mode Execution Prevention */ /* * Bits in AMD64 special registers. EFER is 64 bits wide. */ #define EFER_SCE 0x000000001 /* System Call Extensions (R/W) */ #define EFER_LME 0x000000100 /* Long mode enable (R/W) */ #define EFER_LMA 0x000000400 /* Long mode active (R) */ #define EFER_NXE 0x000000800 /* PTE No-Execute bit enable (R/W) */ #define EFER_SVM 0x000001000 /* SVM enable bit for AMD, reserved for Intel */ #define EFER_LMSLE 0x000002000 /* Long Mode Segment Limit Enable */ #define EFER_FFXSR 0x000004000 /* Fast FXSAVE/FSRSTOR */ #define EFER_TCE 0x000008000 /* Translation Cache Extension */ /* * Intel Extended Features registers */ #define XCR0 0 /* XFEATURE_ENABLED_MASK register */ #define XFEATURE_ENABLED_X87 0x00000001 #define XFEATURE_ENABLED_SSE 0x00000002 #define XFEATURE_ENABLED_YMM_HI128 0x00000004 #define XFEATURE_ENABLED_AVX XFEATURE_ENABLED_YMM_HI128 #define XFEATURE_ENABLED_BNDREGS 0x00000008 #define XFEATURE_ENABLED_BNDCSR 0x00000010 #define XFEATURE_ENABLED_OPMASK 0x00000020 #define XFEATURE_ENABLED_ZMM_HI256 0x00000040 #define XFEATURE_ENABLED_HI16_ZMM 0x00000080 #define XFEATURE_AVX \ (XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE | XFEATURE_ENABLED_AVX) #define XFEATURE_AVX512 \ (XFEATURE_ENABLED_OPMASK | XFEATURE_ENABLED_ZMM_HI256 | \ XFEATURE_ENABLED_HI16_ZMM) #define XFEATURE_MPX \ (XFEATURE_ENABLED_BNDREGS | XFEATURE_ENABLED_BNDCSR) /* * CPUID instruction features register */ #define CPUID_FPU 0x00000001 #define CPUID_VME 0x00000002 #define CPUID_DE 0x00000004 #define CPUID_PSE 0x00000008 #define CPUID_TSC 0x00000010 #define CPUID_MSR 0x00000020 #define CPUID_PAE 0x00000040 #define CPUID_MCE 0x00000080 #define CPUID_CX8 0x00000100 #define CPUID_APIC 0x00000200 #define CPUID_B10 0x00000400 #define CPUID_SEP 0x00000800 #define CPUID_MTRR 0x00001000 #define CPUID_PGE 0x00002000 #define CPUID_MCA 0x00004000 #define CPUID_CMOV 0x00008000 #define CPUID_PAT 0x00010000 #define CPUID_PSE36 0x00020000 #define CPUID_PSN 0x00040000 #define CPUID_CLFSH 0x00080000 #define CPUID_B20 0x00100000 #define CPUID_DS 0x00200000 #define CPUID_ACPI 0x00400000 #define CPUID_MMX 0x00800000 #define CPUID_FXSR 0x01000000 #define CPUID_SSE 0x02000000 #define CPUID_XMM 0x02000000 #define CPUID_SSE2 0x04000000 #define CPUID_SS 0x08000000 #define CPUID_HTT 0x10000000 #define CPUID_TM 0x20000000 #define CPUID_IA64 0x40000000 #define CPUID_PBE 0x80000000 #define CPUID2_SSE3 0x00000001 #define CPUID2_PCLMULQDQ 0x00000002 #define CPUID2_DTES64 0x00000004 #define CPUID2_MON 0x00000008 #define CPUID2_DS_CPL 0x00000010 #define CPUID2_VMX 0x00000020 #define CPUID2_SMX 0x00000040 #define CPUID2_EST 0x00000080 #define CPUID2_TM2 0x00000100 #define CPUID2_SSSE3 0x00000200 #define CPUID2_CNXTID 0x00000400 #define CPUID2_SDBG 0x00000800 #define CPUID2_FMA 0x00001000 #define CPUID2_CX16 0x00002000 #define CPUID2_XTPR 0x00004000 #define CPUID2_PDCM 0x00008000 #define CPUID2_PCID 0x00020000 #define CPUID2_DCA 0x00040000 #define CPUID2_SSE41 0x00080000 #define CPUID2_SSE42 0x00100000 #define CPUID2_X2APIC 0x00200000 #define CPUID2_MOVBE 0x00400000 #define CPUID2_POPCNT 0x00800000 #define CPUID2_TSCDLT 0x01000000 #define CPUID2_AESNI 0x02000000 #define CPUID2_XSAVE 0x04000000 #define CPUID2_OSXSAVE 0x08000000 #define CPUID2_AVX 0x10000000 #define CPUID2_F16C 0x20000000 #define CPUID2_RDRAND 0x40000000 #define CPUID2_HV 0x80000000 /* * Important bits in the Thermal and Power Management flags * CPUID.6 EAX and ECX. */ #define CPUTPM1_SENSOR 0x00000001 #define CPUTPM1_TURBO 0x00000002 #define CPUTPM1_ARAT 0x00000004 #define CPUTPM2_EFFREQ 0x00000001 /* * Important bits in the AMD extended cpuid flags */ #define AMDID_SYSCALL 0x00000800 #define AMDID_MP 0x00080000 #define AMDID_NX 0x00100000 #define AMDID_EXT_MMX 0x00400000 #define AMDID_FFXSR 0x02000000 #define AMDID_PAGE1GB 0x04000000 #define AMDID_RDTSCP 0x08000000 #define AMDID_LM 0x20000000 #define AMDID_EXT_3DNOW 0x40000000 #define AMDID_3DNOW 0x80000000 #define AMDID2_LAHF 0x00000001 #define AMDID2_CMP 0x00000002 #define AMDID2_SVM 0x00000004 #define AMDID2_EXT_APIC 0x00000008 #define AMDID2_CR8 0x00000010 #define AMDID2_ABM 0x00000020 #define AMDID2_SSE4A 0x00000040 #define AMDID2_MAS 0x00000080 #define AMDID2_PREFETCH 0x00000100 #define AMDID2_OSVW 0x00000200 #define AMDID2_IBS 0x00000400 #define AMDID2_XOP 0x00000800 #define AMDID2_SKINIT 0x00001000 #define AMDID2_WDT 0x00002000 #define AMDID2_LWP 0x00008000 #define AMDID2_FMA4 0x00010000 #define AMDID2_TCE 0x00020000 #define AMDID2_NODE_ID 0x00080000 #define AMDID2_TBM 0x00200000 #define AMDID2_TOPOLOGY 0x00400000 #define AMDID2_PCXC 0x00800000 #define AMDID2_PNXC 0x01000000 #define AMDID2_DBE 0x04000000 #define AMDID2_PTSC 0x08000000 #define AMDID2_PTSCEL2I 0x10000000 /* * CPUID instruction 1 eax info */ #define CPUID_STEPPING 0x0000000f #define CPUID_MODEL 0x000000f0 #define CPUID_FAMILY 0x00000f00 #define CPUID_EXT_MODEL 0x000f0000 #define CPUID_EXT_FAMILY 0x0ff00000 #ifdef __i386__ #define CPUID_TO_MODEL(id) \ ((((id) & CPUID_MODEL) >> 4) | \ ((((id) & CPUID_FAMILY) >= 0x600) ? \ (((id) & CPUID_EXT_MODEL) >> 12) : 0)) #define CPUID_TO_FAMILY(id) \ ((((id) & CPUID_FAMILY) >> 8) + \ ((((id) & CPUID_FAMILY) == 0xf00) ? \ (((id) & CPUID_EXT_FAMILY) >> 20) : 0)) #else #define CPUID_TO_MODEL(id) \ ((((id) & CPUID_MODEL) >> 4) | \ (((id) & CPUID_EXT_MODEL) >> 12)) #define CPUID_TO_FAMILY(id) \ ((((id) & CPUID_FAMILY) >> 8) + \ (((id) & CPUID_EXT_FAMILY) >> 20)) #endif /* * CPUID instruction 1 ebx info */ #define CPUID_BRAND_INDEX 0x000000ff #define CPUID_CLFUSH_SIZE 0x0000ff00 #define CPUID_HTT_CORES 0x00ff0000 #define CPUID_LOCAL_APIC_ID 0xff000000 /* * CPUID instruction 5 info */ #define CPUID5_MON_MIN_SIZE 0x0000ffff /* eax */ #define CPUID5_MON_MAX_SIZE 0x0000ffff /* ebx */ #define CPUID5_MON_MWAIT_EXT 0x00000001 /* ecx */ #define CPUID5_MWAIT_INTRBREAK 0x00000002 /* ecx */ /* * MWAIT cpu power states. Lower 4 bits are sub-states. */ #define MWAIT_C0 0xf0 #define MWAIT_C1 0x00 #define MWAIT_C2 0x10 #define MWAIT_C3 0x20 #define MWAIT_C4 0x30 /* * MWAIT extensions. */ /* Interrupt breaks MWAIT even when masked. */ #define MWAIT_INTRBREAK 0x00000001 /* * CPUID instruction 6 ecx info */ #define CPUID_PERF_STAT 0x00000001 #define CPUID_PERF_BIAS 0x00000008 /* * CPUID instruction 0xb ebx info. */ #define CPUID_TYPE_INVAL 0 #define CPUID_TYPE_SMT 1 #define CPUID_TYPE_CORE 2 /* * CPUID instruction 0xd Processor Extended State Enumeration Sub-leaf 1 */ #define CPUID_EXTSTATE_XSAVEOPT 0x00000001 #define CPUID_EXTSTATE_XSAVEC 0x00000002 #define CPUID_EXTSTATE_XINUSE 0x00000004 #define CPUID_EXTSTATE_XSAVES 0x00000008 /* * AMD extended function 8000_0007h edx info */ #define AMDPM_TS 0x00000001 #define AMDPM_FID 0x00000002 #define AMDPM_VID 0x00000004 #define AMDPM_TTP 0x00000008 #define AMDPM_TM 0x00000010 #define AMDPM_STC 0x00000020 #define AMDPM_100MHZ_STEPS 0x00000040 #define AMDPM_HW_PSTATE 0x00000080 #define AMDPM_TSC_INVARIANT 0x00000100 #define AMDPM_CPB 0x00000200 /* * AMD extended function 8000_0008h ecx info */ #define AMDID_CMP_CORES 0x000000ff #define AMDID_COREID_SIZE 0x0000f000 #define AMDID_COREID_SIZE_SHIFT 12 /* * CPUID instruction 7 Structured Extended Features, leaf 0 ebx info */ #define CPUID_STDEXT_FSGSBASE 0x00000001 #define CPUID_STDEXT_TSC_ADJUST 0x00000002 #define CPUID_STDEXT_BMI1 0x00000008 #define CPUID_STDEXT_HLE 0x00000010 #define CPUID_STDEXT_AVX2 0x00000020 #define CPUID_STDEXT_FDP_EXC 0x00000040 #define CPUID_STDEXT_SMEP 0x00000080 #define CPUID_STDEXT_BMI2 0x00000100 #define CPUID_STDEXT_ERMS 0x00000200 #define CPUID_STDEXT_INVPCID 0x00000400 #define CPUID_STDEXT_RTM 0x00000800 #define CPUID_STDEXT_MPX 0x00004000 #define CPUID_STDEXT_AVX512F 0x00010000 #define CPUID_STDEXT_AVX512DQ 0x00020000 #define CPUID_STDEXT_RDSEED 0x00040000 #define CPUID_STDEXT_ADX 0x00080000 #define CPUID_STDEXT_SMAP 0x00100000 #define CPUID_STDEXT_AVX512IFMA 0x00200000 #define CPUID_STDEXT_PCOMMIT 0x00400000 #define CPUID_STDEXT_CLFLUSHOPT 0x00800000 #define CPUID_STDEXT_CLWB 0x01000000 #define CPUID_STDEXT_PROCTRACE 0x02000000 #define CPUID_STDEXT_AVX512PF 0x04000000 #define CPUID_STDEXT_AVX512ER 0x08000000 #define CPUID_STDEXT_AVX512CD 0x10000000 #define CPUID_STDEXT_SHA 0x20000000 #define CPUID_STDEXT_AVX512BW 0x40000000 /* * CPUID manufacturers identifiers */ #define AMD_VENDOR_ID "AuthenticAMD" #define CENTAUR_VENDOR_ID "CentaurHauls" #define CYRIX_VENDOR_ID "CyrixInstead" #define INTEL_VENDOR_ID "GenuineIntel" #define NEXGEN_VENDOR_ID "NexGenDriven" #define NSC_VENDOR_ID "Geode by NSC" #define RISE_VENDOR_ID "RiseRiseRise" #define SIS_VENDOR_ID "SiS SiS SiS " #define TRANSMETA_VENDOR_ID "GenuineTMx86" #define UMC_VENDOR_ID "UMC UMC UMC " /* * Model-specific registers for the i386 family */ #define MSR_P5_MC_ADDR 0x000 #define MSR_P5_MC_TYPE 0x001 #define MSR_TSC 0x010 #define MSR_P5_CESR 0x011 #define MSR_P5_CTR0 0x012 #define MSR_P5_CTR1 0x013 #define MSR_IA32_PLATFORM_ID 0x017 #define MSR_APICBASE 0x01b #define MSR_EBL_CR_POWERON 0x02a #define MSR_TEST_CTL 0x033 #define MSR_IA32_FEATURE_CONTROL 0x03a #define MSR_BIOS_UPDT_TRIG 0x079 #define MSR_BBL_CR_D0 0x088 #define MSR_BBL_CR_D1 0x089 #define MSR_BBL_CR_D2 0x08a #define MSR_BIOS_SIGN 0x08b #define MSR_PERFCTR0 0x0c1 #define MSR_PERFCTR1 0x0c2 #define MSR_PLATFORM_INFO 0x0ce #define MSR_MPERF 0x0e7 #define MSR_APERF 0x0e8 #define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ #define MSR_MTRRcap 0x0fe #define MSR_BBL_CR_ADDR 0x116 #define MSR_BBL_CR_DECC 0x118 #define MSR_BBL_CR_CTL 0x119 #define MSR_BBL_CR_TRIG 0x11a #define MSR_BBL_CR_BUSY 0x11b #define MSR_BBL_CR_CTL3 0x11e #define MSR_SYSENTER_CS_MSR 0x174 #define MSR_SYSENTER_ESP_MSR 0x175 #define MSR_SYSENTER_EIP_MSR 0x176 #define MSR_MCG_CAP 0x179 #define MSR_MCG_STATUS 0x17a #define MSR_MCG_CTL 0x17b #define MSR_EVNTSEL0 0x186 #define MSR_EVNTSEL1 0x187 #define MSR_THERM_CONTROL 0x19a #define MSR_THERM_INTERRUPT 0x19b #define MSR_THERM_STATUS 0x19c #define MSR_IA32_MISC_ENABLE 0x1a0 #define MSR_IA32_TEMPERATURE_TARGET 0x1a2 #define MSR_TURBO_RATIO_LIMIT 0x1ad #define MSR_TURBO_RATIO_LIMIT1 0x1ae #define MSR_DEBUGCTLMSR 0x1d9 #define MSR_LASTBRANCHFROMIP 0x1db #define MSR_LASTBRANCHTOIP 0x1dc #define MSR_LASTINTFROMIP 0x1dd #define MSR_LASTINTTOIP 0x1de #define MSR_ROB_CR_BKUPTMPDR6 0x1e0 #define MSR_MTRRVarBase 0x200 #define MSR_MTRR64kBase 0x250 #define MSR_MTRR16kBase 0x258 #define MSR_MTRR4kBase 0x268 #define MSR_PAT 0x277 #define MSR_MC0_CTL2 0x280 #define MSR_MTRRdefType 0x2ff #define MSR_MC0_CTL 0x400 #define MSR_MC0_STATUS 0x401 #define MSR_MC0_ADDR 0x402 #define MSR_MC0_MISC 0x403 #define MSR_MC1_CTL 0x404 #define MSR_MC1_STATUS 0x405 #define MSR_MC1_ADDR 0x406 #define MSR_MC1_MISC 0x407 #define MSR_MC2_CTL 0x408 #define MSR_MC2_STATUS 0x409 #define MSR_MC2_ADDR 0x40a #define MSR_MC2_MISC 0x40b #define MSR_MC3_CTL 0x40c #define MSR_MC3_STATUS 0x40d #define MSR_MC3_ADDR 0x40e #define MSR_MC3_MISC 0x40f #define MSR_MC4_CTL 0x410 #define MSR_MC4_STATUS 0x411 #define MSR_MC4_ADDR 0x412 #define MSR_MC4_MISC 0x413 #define MSR_RAPL_POWER_UNIT 0x606 #define MSR_PKG_ENERGY_STATUS 0x611 #define MSR_DRAM_ENERGY_STATUS 0x619 #define MSR_PP0_ENERGY_STATUS 0x639 #define MSR_PP1_ENERGY_STATUS 0x641 /* * VMX MSRs */ #define MSR_VMX_BASIC 0x480 #define MSR_VMX_PINBASED_CTLS 0x481 #define MSR_VMX_PROCBASED_CTLS 0x482 #define MSR_VMX_EXIT_CTLS 0x483 #define MSR_VMX_ENTRY_CTLS 0x484 #define MSR_VMX_CR0_FIXED0 0x486 #define MSR_VMX_CR0_FIXED1 0x487 #define MSR_VMX_CR4_FIXED0 0x488 #define MSR_VMX_CR4_FIXED1 0x489 #define MSR_VMX_PROCBASED_CTLS2 0x48b #define MSR_VMX_EPT_VPID_CAP 0x48c #define MSR_VMX_TRUE_PINBASED_CTLS 0x48d #define MSR_VMX_TRUE_PROCBASED_CTLS 0x48e #define MSR_VMX_TRUE_EXIT_CTLS 0x48f #define MSR_VMX_TRUE_ENTRY_CTLS 0x490 /* * X2APIC MSRs */ #define MSR_APIC_000 0x800 #define MSR_APIC_ID 0x802 #define MSR_APIC_VERSION 0x803 #define MSR_APIC_TPR 0x808 #define MSR_APIC_EOI 0x80b #define MSR_APIC_LDR 0x80d #define MSR_APIC_SVR 0x80f #define MSR_APIC_ISR0 0x810 #define MSR_APIC_ISR1 0x811 #define MSR_APIC_ISR2 0x812 #define MSR_APIC_ISR3 0x813 #define MSR_APIC_ISR4 0x814 #define MSR_APIC_ISR5 0x815 #define MSR_APIC_ISR6 0x816 #define MSR_APIC_ISR7 0x817 #define MSR_APIC_TMR0 0x818 #define MSR_APIC_IRR0 0x820 #define MSR_APIC_ESR 0x828 #define MSR_APIC_LVT_CMCI 0x82F #define MSR_APIC_ICR 0x830 #define MSR_APIC_LVT_TIMER 0x832 #define MSR_APIC_LVT_THERMAL 0x833 #define MSR_APIC_LVT_PCINT 0x834 #define MSR_APIC_LVT_LINT0 0x835 #define MSR_APIC_LVT_LINT1 0x836 #define MSR_APIC_LVT_ERROR 0x837 #define MSR_APIC_ICR_TIMER 0x838 #define MSR_APIC_CCR_TIMER 0x839 #define MSR_APIC_DCR_TIMER 0x83e #define MSR_APIC_SELF_IPI 0x83f #define MSR_IA32_XSS 0xda0 /* * Constants related to MSR's. */ #define APICBASE_RESERVED 0x000002ff #define APICBASE_BSP 0x00000100 #define APICBASE_X2APIC 0x00000400 #define APICBASE_ENABLED 0x00000800 #define APICBASE_ADDRESS 0xfffff000 /* MSR_IA32_FEATURE_CONTROL related */ #define IA32_FEATURE_CONTROL_LOCK 0x01 /* lock bit */ #define IA32_FEATURE_CONTROL_SMX_EN 0x02 /* enable VMX inside SMX */ #define IA32_FEATURE_CONTROL_VMX_EN 0x04 /* enable VMX outside SMX */ /* MSR IA32_MISC_ENABLE */ #define IA32_MISC_EN_FASTSTR 0x0000000000000001ULL #define IA32_MISC_EN_ATCCE 0x0000000000000008ULL #define IA32_MISC_EN_PERFMON 0x0000000000000080ULL #define IA32_MISC_EN_PEBSU 0x0000000000001000ULL #define IA32_MISC_EN_ESSTE 0x0000000000010000ULL #define IA32_MISC_EN_MONE 0x0000000000040000ULL #define IA32_MISC_EN_LIMCPUID 0x0000000000400000ULL #define IA32_MISC_EN_xTPRD 0x0000000000800000ULL #define IA32_MISC_EN_XDD 0x0000000400000000ULL /* * PAT modes. */ #define PAT_UNCACHEABLE 0x00 #define PAT_WRITE_COMBINING 0x01 #define PAT_WRITE_THROUGH 0x04 #define PAT_WRITE_PROTECTED 0x05 #define PAT_WRITE_BACK 0x06 #define PAT_UNCACHED 0x07 #define PAT_VALUE(i, m) ((long long)(m) << (8 * (i))) #define PAT_MASK(i) PAT_VALUE(i, 0xff) /* * Constants related to MTRRs */ #define MTRR_UNCACHEABLE 0x00 #define MTRR_WRITE_COMBINING 0x01 #define MTRR_WRITE_THROUGH 0x04 #define MTRR_WRITE_PROTECTED 0x05 #define MTRR_WRITE_BACK 0x06 #define MTRR_N64K 8 /* numbers of fixed-size entries */ #define MTRR_N16K 16 #define MTRR_N4K 64 #define MTRR_CAP_WC 0x0000000000000400 #define MTRR_CAP_FIXED 0x0000000000000100 #define MTRR_CAP_VCNT 0x00000000000000ff #define MTRR_DEF_ENABLE 0x0000000000000800 #define MTRR_DEF_FIXED_ENABLE 0x0000000000000400 #define MTRR_DEF_TYPE 0x00000000000000ff #define MTRR_PHYSBASE_PHYSBASE 0x000ffffffffff000 #define MTRR_PHYSBASE_TYPE 0x00000000000000ff #define MTRR_PHYSMASK_PHYSMASK 0x000ffffffffff000 #define MTRR_PHYSMASK_VALID 0x0000000000000800 /* * Cyrix configuration registers, accessible as IO ports. */ #define CCR0 0xc0 /* Configuration control register 0 */ #define CCR0_NC0 0x01 /* First 64K of each 1M memory region is non-cacheable */ #define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */ #define CCR0_A20M 0x04 /* Enables A20M# input pin */ #define CCR0_KEN 0x08 /* Enables KEN# input pin */ #define CCR0_FLUSH 0x10 /* Enables FLUSH# input pin */ #define CCR0_BARB 0x20 /* Flushes internal cache when entering hold state */ #define CCR0_CO 0x40 /* Cache org: 1=direct mapped, 0=2x set assoc */ #define CCR0_SUSPEND 0x80 /* Enables SUSP# and SUSPA# pins */ #define CCR1 0xc1 /* Configuration control register 1 */ #define CCR1_RPL 0x01 /* Enables RPLSET and RPLVAL# pins */ #define CCR1_SMI 0x02 /* Enables SMM pins */ #define CCR1_SMAC 0x04 /* System management memory access */ #define CCR1_MMAC 0x08 /* Main memory access */ #define CCR1_NO_LOCK 0x10 /* Negate LOCK# */ #define CCR1_SM3 0x80 /* SMM address space address region 3 */ #define CCR2 0xc2 #define CCR2_WB 0x02 /* Enables WB cache interface pins */ #define CCR2_SADS 0x02 /* Slow ADS */ #define CCR2_LOCK_NW 0x04 /* LOCK NW Bit */ #define CCR2_SUSP_HLT 0x08 /* Suspend on HALT */ #define CCR2_WT1 0x10 /* WT region 1 */ #define CCR2_WPR1 0x10 /* Write-protect region 1 */ #define CCR2_BARB 0x20 /* Flushes write-back cache when entering hold state. */ #define CCR2_BWRT 0x40 /* Enables burst write cycles */ #define CCR2_USE_SUSP 0x80 /* Enables suspend pins */ #define CCR3 0xc3 #define CCR3_SMILOCK 0x01 /* SMM register lock */ #define CCR3_NMI 0x02 /* Enables NMI during SMM */ #define CCR3_LINBRST 0x04 /* Linear address burst cycles */ #define CCR3_SMMMODE 0x08 /* SMM Mode */ #define CCR3_MAPEN0 0x10 /* Enables Map0 */ #define CCR3_MAPEN1 0x20 /* Enables Map1 */ #define CCR3_MAPEN2 0x40 /* Enables Map2 */ #define CCR3_MAPEN3 0x80 /* Enables Map3 */ #define CCR4 0xe8 #define CCR4_IOMASK 0x07 #define CCR4_MEM 0x08 /* Enables momory bypassing */ #define CCR4_DTE 0x10 /* Enables directory table entry cache */ #define CCR4_FASTFPE 0x20 /* Fast FPU exception */ #define CCR4_CPUID 0x80 /* Enables CPUID instruction */ #define CCR5 0xe9 #define CCR5_WT_ALLOC 0x01 /* Write-through allocate */ #define CCR5_SLOP 0x02 /* LOOP instruction slowed down */ #define CCR5_LBR1 0x10 /* Local bus region 1 */ #define CCR5_ARREN 0x20 /* Enables ARR region */ #define CCR6 0xea #define CCR7 0xeb /* Performance Control Register (5x86 only). */ #define PCR0 0x20 #define PCR0_RSTK 0x01 /* Enables return stack */ #define PCR0_BTB 0x02 /* Enables branch target buffer */ #define PCR0_LOOP 0x04 /* Enables loop */ #define PCR0_AIS 0x08 /* Enables all instrcutions stalled to serialize pipe. */ #define PCR0_MLR 0x10 /* Enables reordering of misaligned loads */ #define PCR0_BTBRT 0x40 /* Enables BTB test register. */ #define PCR0_LSSER 0x80 /* Disable reorder */ /* Device Identification Registers */ #define DIR0 0xfe #define DIR1 0xff /* * Machine Check register constants. */ #define MCG_CAP_COUNT 0x000000ff #define MCG_CAP_CTL_P 0x00000100 #define MCG_CAP_EXT_P 0x00000200 #define MCG_CAP_CMCI_P 0x00000400 #define MCG_CAP_TES_P 0x00000800 #define MCG_CAP_EXT_CNT 0x00ff0000 #define MCG_CAP_SER_P 0x01000000 #define MCG_STATUS_RIPV 0x00000001 #define MCG_STATUS_EIPV 0x00000002 #define MCG_STATUS_MCIP 0x00000004 #define MCG_CTL_ENABLE 0xffffffffffffffff #define MCG_CTL_DISABLE 0x0000000000000000 #define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4) #define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4) #define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4) #define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4) #define MSR_MC_CTL2(x) (MSR_MC0_CTL2 + (x)) /* If MCG_CAP_CMCI_P */ #define MC_STATUS_MCA_ERROR 0x000000000000ffff #define MC_STATUS_MODEL_ERROR 0x00000000ffff0000 #define MC_STATUS_OTHER_INFO 0x01ffffff00000000 #define MC_STATUS_COR_COUNT 0x001fffc000000000 /* If MCG_CAP_CMCI_P */ #define MC_STATUS_TES_STATUS 0x0060000000000000 /* If MCG_CAP_TES_P */ #define MC_STATUS_AR 0x0080000000000000 /* If MCG_CAP_TES_P */ #define MC_STATUS_S 0x0100000000000000 /* If MCG_CAP_TES_P */ #define MC_STATUS_PCC 0x0200000000000000 #define MC_STATUS_ADDRV 0x0400000000000000 #define MC_STATUS_MISCV 0x0800000000000000 #define MC_STATUS_EN 0x1000000000000000 #define MC_STATUS_UC 0x2000000000000000 #define MC_STATUS_OVER 0x4000000000000000 #define MC_STATUS_VAL 0x8000000000000000 #define MC_MISC_RA_LSB 0x000000000000003f /* If MCG_CAP_SER_P */ #define MC_MISC_ADDRESS_MODE 0x00000000000001c0 /* If MCG_CAP_SER_P */ #define MC_CTL2_THRESHOLD 0x0000000000007fff #define MC_CTL2_CMCI_EN 0x0000000040000000 /* * The following four 3-byte registers control the non-cacheable regions. * These registers must be written as three separate bytes. * * NCRx+0: A31-A24 of starting address * NCRx+1: A23-A16 of starting address * NCRx+2: A15-A12 of starting address | NCR_SIZE_xx. * * The non-cacheable region's starting address must be aligned to the * size indicated by the NCR_SIZE_xx field. */ #define NCR1 0xc4 #define NCR2 0xc7 #define NCR3 0xca #define NCR4 0xcd #define NCR_SIZE_0K 0 #define NCR_SIZE_4K 1 #define NCR_SIZE_8K 2 #define NCR_SIZE_16K 3 #define NCR_SIZE_32K 4 #define NCR_SIZE_64K 5 #define NCR_SIZE_128K 6 #define NCR_SIZE_256K 7 #define NCR_SIZE_512K 8 #define NCR_SIZE_1M 9 #define NCR_SIZE_2M 10 #define NCR_SIZE_4M 11 #define NCR_SIZE_8M 12 #define NCR_SIZE_16M 13 #define NCR_SIZE_32M 14 #define NCR_SIZE_4G 15 /* * The address region registers are used to specify the location and * size for the eight address regions. * * ARRx + 0: A31-A24 of start address * ARRx + 1: A23-A16 of start address * ARRx + 2: A15-A12 of start address | ARR_SIZE_xx */ #define ARR0 0xc4 #define ARR1 0xc7 #define ARR2 0xca #define ARR3 0xcd #define ARR4 0xd0 #define ARR5 0xd3 #define ARR6 0xd6 #define ARR7 0xd9 #define ARR_SIZE_0K 0 #define ARR_SIZE_4K 1 #define ARR_SIZE_8K 2 #define ARR_SIZE_16K 3 #define ARR_SIZE_32K 4 #define ARR_SIZE_64K 5 #define ARR_SIZE_128K 6 #define ARR_SIZE_256K 7 #define ARR_SIZE_512K 8 #define ARR_SIZE_1M 9 #define ARR_SIZE_2M 10 #define ARR_SIZE_4M 11 #define ARR_SIZE_8M 12 #define ARR_SIZE_16M 13 #define ARR_SIZE_32M 14 #define ARR_SIZE_4G 15 /* * The region control registers specify the attributes associated with * the ARRx addres regions. */ #define RCR0 0xdc #define RCR1 0xdd #define RCR2 0xde #define RCR3 0xdf #define RCR4 0xe0 #define RCR5 0xe1 #define RCR6 0xe2 #define RCR7 0xe3 #define RCR_RCD 0x01 /* Disables caching for ARRx (x = 0-6). */ #define RCR_RCE 0x01 /* Enables caching for ARR7. */ #define RCR_WWO 0x02 /* Weak write ordering. */ #define RCR_WL 0x04 /* Weak locking. */ #define RCR_WG 0x08 /* Write gathering. */ #define RCR_WT 0x10 /* Write-through. */ #define RCR_NLB 0x20 /* LBA# pin is not asserted. */ /* AMD Write Allocate Top-Of-Memory and Control Register */ #define AMD_WT_ALLOC_TME 0x40000 /* top-of-memory enable */ #define AMD_WT_ALLOC_PRE 0x20000 /* programmable range enable */ #define AMD_WT_ALLOC_FRE 0x10000 /* fixed (A0000-FFFFF) range enable */ /* AMD64 MSR's */ #define MSR_EFER 0xc0000080 /* extended features */ #define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target/cs/ss */ #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target rip */ #define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target rip */ #define MSR_SF_MASK 0xc0000084 /* syscall flags mask */ #define MSR_FSBASE 0xc0000100 /* base address of the %fs "segment" */ #define MSR_GSBASE 0xc0000101 /* base address of the %gs "segment" */ #define MSR_KGSBASE 0xc0000102 /* base address of the kernel %gs */ #define MSR_PERFEVSEL0 0xc0010000 #define MSR_PERFEVSEL1 0xc0010001 #define MSR_PERFEVSEL2 0xc0010002 #define MSR_PERFEVSEL3 0xc0010003 #define MSR_K7_PERFCTR0 0xc0010004 #define MSR_K7_PERFCTR1 0xc0010005 #define MSR_K7_PERFCTR2 0xc0010006 #define MSR_K7_PERFCTR3 0xc0010007 #define MSR_SYSCFG 0xc0010010 #define MSR_HWCR 0xc0010015 #define MSR_IORRBASE0 0xc0010016 #define MSR_IORRMASK0 0xc0010017 #define MSR_IORRBASE1 0xc0010018 #define MSR_IORRMASK1 0xc0010019 #define MSR_TOP_MEM 0xc001001a /* boundary for ram below 4G */ #define MSR_TOP_MEM2 0xc001001d /* boundary for ram above 4G */ #define MSR_NB_CFG1 0xc001001f /* NB configuration 1 */ #define MSR_P_STATE_LIMIT 0xc0010061 /* P-state Current Limit Register */ #define MSR_P_STATE_CONTROL 0xc0010062 /* P-state Control Register */ #define MSR_P_STATE_STATUS 0xc0010063 /* P-state Status Register */ #define MSR_P_STATE_CONFIG(n) (0xc0010064 + (n)) /* P-state Config */ #define MSR_SMM_ADDR 0xc0010112 /* SMM TSEG base address */ #define MSR_SMM_MASK 0xc0010113 /* SMM TSEG address mask */ #define MSR_IC_CFG 0xc0011021 /* Instruction Cache Configuration */ #define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ #define MSR_MC0_CTL_MASK 0xc0010044 #define MSR_VM_CR 0xc0010114 /* SVM: feature control */ #define MSR_VM_HSAVE_PA 0xc0010117 /* SVM: host save area address */ /* MSR_VM_CR related */ #define VM_CR_SVMDIS 0x10 /* SVM: disabled by BIOS */ /* VIA ACE crypto featureset: for via_feature_rng */ #define VIA_HAS_RNG 1 /* cpu has RNG */ /* VIA ACE crypto featureset: for via_feature_xcrypt */ #define VIA_HAS_AES 1 /* cpu has AES */ #define VIA_HAS_SHA 2 /* cpu has SHA1 & SHA256 */ #define VIA_HAS_MM 4 /* cpu has RSA instructions */ #define VIA_HAS_AESCTR 8 /* cpu has AES-CTR instructions */ /* Centaur Extended Feature flags */ #define VIA_CPUID_HAS_RNG 0x000004 #define VIA_CPUID_DO_RNG 0x000008 #define VIA_CPUID_HAS_ACE 0x000040 #define VIA_CPUID_DO_ACE 0x000080 #define VIA_CPUID_HAS_ACE2 0x000100 #define VIA_CPUID_DO_ACE2 0x000200 #define VIA_CPUID_HAS_PHE 0x000400 #define VIA_CPUID_DO_PHE 0x000800 #define VIA_CPUID_HAS_PMM 0x001000 #define VIA_CPUID_DO_PMM 0x002000 /* VIA ACE xcrypt-* instruction context control options */ #define VIA_CRYPT_CWLO_ROUND_M 0x0000000f #define VIA_CRYPT_CWLO_ALG_M 0x00000070 #define VIA_CRYPT_CWLO_ALG_AES 0x00000000 #define VIA_CRYPT_CWLO_KEYGEN_M 0x00000080 #define VIA_CRYPT_CWLO_KEYGEN_HW 0x00000000 #define VIA_CRYPT_CWLO_KEYGEN_SW 0x00000080 #define VIA_CRYPT_CWLO_NORMAL 0x00000000 #define VIA_CRYPT_CWLO_INTERMEDIATE 0x00000100 #define VIA_CRYPT_CWLO_ENCRYPT 0x00000000 #define VIA_CRYPT_CWLO_DECRYPT 0x00000200 #define VIA_CRYPT_CWLO_KEY128 0x0000000a /* 128bit, 10 rds */ #define VIA_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */ #define VIA_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */ #endif /* !_MACHINE_SPECIALREG_H_ */ /*- * Copyright (c) 2002 David E. O'Brien. All rights reserved. * * 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. Neither the name of the University nor the names of its contributors * may 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. * * $FreeBSD$ */ #ifndef _MACHINE_STDARG_H_ #define _MACHINE_STDARG_H_ #include #include #ifndef _VA_LIST_DECLARED #define _VA_LIST_DECLARED typedef __va_list va_list; #endif #ifdef __GNUCLIKE_BUILTIN_STDARG #define va_start(ap, last) \ __builtin_va_start((ap), (last)) #define va_arg(ap, type) \ __builtin_va_arg((ap), type) #define __va_copy(dest, src) \ __builtin_va_copy((dest), (src)) #if __ISO_C_VISIBLE >= 1999 #define va_copy(dest, src) \ __va_copy(dest, src) #endif #define va_end(ap) \ __builtin_va_end(ap) #elif defined(lint) /* Provide a fake implementation for lint's benefit */ #define __va_size(type) \ (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long)) #define va_start(ap, last) \ ((ap) = (va_list)&(last) + __va_size(last)) #define va_copy(dst, src) \ ((dst) = (src)) #define va_arg(ap, type) \ (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) #define va_end(ap) #else #error this file needs to be ported to your compiler #endif #endif /* !_MACHINE_STDARG_H_ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: @(#)trap.h 5.4 (Berkeley) 5/9/91 * $FreeBSD$ */ #ifndef _MACHINE_TRAP_H_ #define _MACHINE_TRAP_H_ /* * Trap type values * also known in trap.c for name strings */ #define T_PRIVINFLT 1 /* privileged instruction */ #define T_BPTFLT 3 /* breakpoint instruction */ #define T_ARITHTRAP 6 /* arithmetic trap */ #define T_PROTFLT 9 /* protection fault */ #define T_TRCTRAP 10 /* debug exception (sic) */ #define T_PAGEFLT 12 /* page fault */ #define T_ALIGNFLT 14 /* alignment fault */ #define T_DIVIDE 18 /* integer divide fault */ #define T_NMI 19 /* non-maskable trap */ #define T_OFLOW 20 /* overflow trap */ #define T_BOUND 21 /* bound instruction fault */ #define T_DNA 22 /* device not available fault */ #define T_DOUBLEFLT 23 /* double fault */ #define T_FPOPFLT 24 /* fp coprocessor operand fetch fault */ #define T_TSSFLT 25 /* invalid tss fault */ #define T_SEGNPFLT 26 /* segment not present fault */ #define T_STKFLT 27 /* stack fault */ #define T_MCHK 28 /* machine check trap */ #define T_XMMFLT 29 /* SIMD floating-point exception */ #define T_RESERVED 30 /* reserved (unknown) */ #define T_DTRACE_RET 32 /* DTrace pid return */ /* XXX most of the following codes aren't used, but could be. */ /* definitions for */ #define ILL_RESAD_FAULT T_RESADFLT #define ILL_PRIVIN_FAULT T_PRIVINFLT #define ILL_RESOP_FAULT T_RESOPFLT #define ILL_ALIGN_FAULT T_ALIGNFLT #define ILL_FPOP_FAULT T_FPOPFLT /* coprocessor operand fault */ /* old FreeBSD macros, deprecated */ #define FPE_INTOVF_TRAP 0x1 /* integer overflow */ #define FPE_INTDIV_TRAP 0x2 /* integer divide by zero */ #define FPE_FLTDIV_TRAP 0x3 /* floating/decimal divide by zero */ #define FPE_FLTOVF_TRAP 0x4 /* floating overflow */ #define FPE_FLTUND_TRAP 0x5 /* floating underflow */ #define FPE_FPU_NP_TRAP 0x6 /* floating point unit not present */ #define FPE_SUBRNG_TRAP 0x7 /* subrange out of bounds */ /* codes for SIGBUS */ #define BUS_PAGE_FAULT T_PAGEFLT /* page fault protection base */ #define BUS_SEGNP_FAULT T_SEGNPFLT /* segment not present */ #define BUS_STK_FAULT T_STKFLT /* stack segment */ #define BUS_SEGM_FAULT T_RESERVED /* segment protection base */ /* Trap's coming from user mode */ #define T_USER 0x100 #endif /* !_MACHINE_TRAP_H_ */