Support UEFI booting on amd64 via loader.efi
This is largely the work from the projects/uefi branch, with some additional refinements. This is derived from (and replaces) the original i386 efi implementation; i386 support will be restored later. Specific revisions of note from projects/uefi: r247380: Adjust our load device when we boot from CD under UEFI. The process for booting from a CD under UEFI involves adding a FAT filesystem containing your loader code as an El Torito boot image. When UEFI detects this, it provides a block IO instance that points at the FAT filesystem as a child of the device that represents the CD itself. The problem being that the CD device is flagged as a "raw device" while the boot image is flagged as a "logical partition". The existing EFI partition code only looks for logical partitions and so the CD filesystem was rendered invisible. To fix this, check the type of each block IO device. If it's found to be a CD, and thus an El Torito boot image, look up its parent device and add that instead so that the loader will then load the kernel from the CD filesystem. This is done by using the handle for the boot filesystem as an alias. Something similar to this will be required for booting from other media as well as the loader will live in the EFI system partition, not on the partition containing the kernel. r246231: Add necessary code to hand off from loader to an amd64 kernel. r246335: Grab the EFI memory map and store it as module metadata on the kernel. This is the same approach used to provide the BIOS SMAP to the kernel. r246336: Pass the ACPI table metadata via hints so the kernel ACPI code can find them. r246608: Rework copy routines to ensure we always use memory allocated via EFI. The previous code assumed it could copy wherever it liked. This is not the case. The approach taken by this code is pretty ham-fisted in that it simply allocates a large (32MB) buffer area and stages into that, then copies the whole area into place when it's time to execute. A more elegant solution could be used but this works for now. r247214: Fix a number of problems preventing proper handover to the kernel. There were two issues at play here. Firstly, there was nothing preventing UEFI from placing the loader code above 1GB in RAM. This meant that when we switched in the page tables the kernel expects to be running on, we are suddenly unmapped and things no longer work. We solve this by making our trampoline code not dependent on being at any given position and simply copying it to a "safe" location before calling it. Secondly, UEFI could allocate our stack wherever it wants. As it happened on my PC, that was right where I was copying the kernel to. This did not cause happiness. The solution to this was to also switch to a temporary stack in a safe location before performing the final copy of the loaded kernel. r246231: Add necessary code to hand off from loader to an amd64 kernel. r246335: Grab the EFI memory map and store it as module metadata on the kernel. This is the same approach used to provide the BIOS SMAP to the kernel. r246336: Pass the ACPI table metadata via hints so the kernel ACPI code can find them. r246608: Rework copy routines to ensure we always use memory allocated via EFI. The previous code assumed it could copy wherever it liked. This is not the case. The approach taken by this code is pretty ham-fisted in that it simply allocates a large (32MB) buffer area and stages into that, then copies the whole area into place when it's time to execute. A more elegant solution could be used but this works for now. r247214: Fix a number of problems preventing proper handover to the kernel. There were two issues at play here. Firstly, there was nothing preventing UEFI from placing the loader code above 1GB in RAM. This meant that when we switched in the page tables the kernel expects to be running on, we are suddenly unmapped and things no longer work. We solve this by making our trampoline code not dependent on being at any given position and simply copying it to a "safe" location before calling it. Secondly, UEFI could allocate our stack wherever it wants. As it happened on my PC, that was right where I was copying the kernel to. This did not cause happiness. The solution to this was to also switch to a temporary stack in a safe location before performing the final copy of the loaded kernel. r247216: Use the UEFI Graphics Output Protocol to get the parameters of the framebuffer. Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
1792ca3cfb
commit
c72005d63b
7
sys/boot/amd64/Makefile
Normal file
7
sys/boot/amd64/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= efi
|
||||
|
||||
.include <bsd.subdir.mk>
|
11
sys/boot/amd64/Makefile.inc
Normal file
11
sys/boot/amd64/Makefile.inc
Normal file
@ -0,0 +1,11 @@
|
||||
# Common defines for all of /sys/boot/amd64/
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
BINDIR?= /boot
|
||||
|
||||
CFLAGS+= -ffreestanding
|
||||
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
|
||||
LDFLAGS+= -nostdlib
|
||||
|
||||
.include "../Makefile.inc"
|
@ -1,7 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NO_MAN=
|
||||
BUILDING_EFI=
|
||||
|
||||
.include <bsd.own.mk>
|
||||
MK_SSP= no
|
||||
@ -13,30 +12,30 @@ INTERNALPROG=
|
||||
SRCS= autoload.c \
|
||||
bootinfo.c \
|
||||
conf.c \
|
||||
copy.c \
|
||||
devicename.c \
|
||||
efimd.c \
|
||||
elf32_freebsd.c \
|
||||
exec.c \
|
||||
i386_copy.c \
|
||||
elf64_freebsd.c \
|
||||
framebuffer.c \
|
||||
main.c \
|
||||
reloc.c \
|
||||
vers.c
|
||||
SRCS+= start.S
|
||||
SRCS+= amd64_tramp.S \
|
||||
start.S
|
||||
|
||||
CFLAGS+= -fPIC
|
||||
CFLAGS+= -I.
|
||||
CFLAGS+= -I${.CURDIR}/../../efi/include
|
||||
CFLAGS+= -I${.CURDIR}/../../efi/include/i386
|
||||
CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH}
|
||||
CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include
|
||||
CFLAGS+= -I${.CURDIR}/../../..
|
||||
|
||||
.if ${MK_FORTH} != "no"
|
||||
BOOT_FORTH= yes
|
||||
CFLAGS+= -DBOOT_FORTH
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl/i386
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
LIBFICL= ${.OBJDIR}/../../ficl32/libficl.a
|
||||
.else
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
|
||||
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Include bcache code.
|
||||
HAVE_BCACHE= yes
|
||||
@ -49,14 +48,14 @@ CFLAGS+= -I${.CURDIR}/../../common
|
||||
FILES= loader.efi
|
||||
FILESMODE_loader.efi= ${BINMODE}
|
||||
|
||||
LDSCRIPT= ${.CURDIR}/ldscript.i386
|
||||
LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared
|
||||
LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
|
||||
LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc
|
||||
|
||||
${PROG}: ${LDSCRIPT}
|
||||
|
||||
CLEANFILES= vers.c loader.efi
|
||||
|
||||
NEWVERSWHAT= "EFI loader" x86
|
||||
NEWVERSWHAT= "EFI loader" ${MACHINE_CPUARCH}
|
||||
|
||||
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
|
||||
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
|
||||
@ -64,28 +63,36 @@ vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
|
||||
OBJCOPY?= objcopy
|
||||
OBJDUMP?= objdump
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
EFI_TARGET= efi-app-x86_64
|
||||
.else
|
||||
EFI_TARGET= efi-app-ia32
|
||||
.endif
|
||||
|
||||
loader.efi: loader.sym
|
||||
if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
|
||||
${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
|
||||
exit 1; \
|
||||
fi
|
||||
${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
|
||||
-j .rel.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \
|
||||
--target=efi-app-ia32 ${.ALLSRC} ${.TARGET}
|
||||
${OBJCOPY} -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 \
|
||||
--target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
|
||||
|
||||
LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
|
||||
LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a
|
||||
CFLAGS+= -I${.CURDIR}/../libi386
|
||||
CFLAGS+= -I${.CURDIR}/../btx/lib
|
||||
CFLAGS+= -I${.CURDIR}/../../common
|
||||
|
||||
DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
|
||||
LDADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
CFLAGS+= -I.
|
||||
beforedepend ${OBJS}: machine
|
||||
beforedepend ${OBJS}: machine x86
|
||||
|
||||
CLEANFILES+= machine x86
|
||||
|
||||
machine:
|
||||
ln -sf ${.CURDIR}/../../../i386/include machine
|
||||
.endif
|
||||
ln -sf ${.CURDIR}/../../../amd64/include machine
|
||||
|
||||
x86:
|
||||
ln -sf ${.CURDIR}/../../../x86/include x86
|
64
sys/boot/amd64/efi/amd64_tramp.S
Normal file
64
sys/boot/amd64/efi/amd64_tramp.S
Normal file
@ -0,0 +1,64 @@
|
||||
/*-
|
||||
* 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 <machine/asmacros.h>
|
||||
|
||||
.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
|
@ -28,7 +28,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
int
|
||||
i386_autoload(void)
|
||||
x86_efi_autoload(void)
|
||||
{
|
||||
|
||||
return (0);
|
360
sys/boot/amd64/efi/bootinfo.c
Normal file
360
sys/boot/amd64/efi/bootinfo.c
Normal file
@ -0,0 +1,360 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/boot.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/metadata.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "framebuffer.h"
|
||||
#include "x86_efi.h"
|
||||
|
||||
UINTN x86_efi_mapkey;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 <name>=<value>, with a single nul
|
||||
* separating each variable, and a double nul terminating the environment.
|
||||
*/
|
||||
static 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 (x86_efi_copyin(ep->ev_name, addr, len) != len)
|
||||
break;
|
||||
addr += len;
|
||||
if (x86_efi_copyin("=", addr, 1) != 1)
|
||||
break;
|
||||
addr++;
|
||||
if (ep->ev_value != NULL) {
|
||||
len = strlen(ep->ev_value);
|
||||
if (x86_efi_copyin(ep->ev_value, addr, len) != len)
|
||||
break;
|
||||
addr += len;
|
||||
}
|
||||
if (x86_efi_copyin("", addr, 1) != 1)
|
||||
break;
|
||||
last = ++addr;
|
||||
}
|
||||
|
||||
if (x86_efi_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) \
|
||||
x86_efi_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) \
|
||||
x86_efi_copyin(s, a, strlen(s) + 1); \
|
||||
a += roundup(strlen(s) + 1, sizeof(uint64_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) \
|
||||
x86_efi_copyin(&s, a, sizeof(s)); \
|
||||
a += roundup(sizeof(s), sizeof(uint64_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) \
|
||||
x86_efi_copyin(mm->md_data, a, mm->md_size); \
|
||||
a += roundup(mm->md_size, sizeof(uint64_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;
|
||||
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 mmsz, pages, sz;
|
||||
UINT32 mmver;
|
||||
struct efi_map_header *efihdr;
|
||||
struct efi_fb efifb;
|
||||
|
||||
if (efi_find_framebuffer(&efifb) == 0)
|
||||
file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb);
|
||||
|
||||
efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
|
||||
|
||||
/*
|
||||
* 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, &x86_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() returned 0x%lx\n", __func__,
|
||||
(long)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 *)addr;
|
||||
mm = (void *)((uint8_t *)efihdr + efisz);
|
||||
sz = (EFI_PAGE_SIZE * pages) - efisz;
|
||||
status = BS->GetMemoryMap(&sz, mm, &x86_efi_mapkey, &mmsz, &mmver);
|
||||
if (EFI_ERROR(status)) {
|
||||
printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
|
||||
(long)status);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
efihdr->memory_size = sz;
|
||||
efihdr->descriptor_size = mmsz;
|
||||
efihdr->descriptor_version = mmver;
|
||||
|
||||
file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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");
|
||||
x86_efi_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(x86_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);
|
||||
|
||||
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);
|
||||
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
|
||||
|
||||
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);
|
||||
|
||||
/* Copy module list and metadata. */
|
||||
(void)bi_copymodules(addr);
|
||||
|
||||
return (0);
|
||||
}
|
@ -52,20 +52,12 @@ struct netif_driver *netif_drivers[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef notyet
|
||||
extern struct file_format amd64_elf;
|
||||
extern struct file_format amd64_elf_obj;
|
||||
#endif
|
||||
extern struct file_format i386_elf;
|
||||
extern struct file_format i386_elf_obj;
|
||||
|
||||
struct file_format *file_formats[] = {
|
||||
#ifdef notyet
|
||||
&amd64_elf,
|
||||
&amd64_elf_obj,
|
||||
#endif
|
||||
&i386_elf,
|
||||
&i386_elf_obj,
|
||||
NULL
|
||||
};
|
||||
|
102
sys/boot/amd64/efi/copy.c
Normal file
102
sys/boot/amd64/efi/copy.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#define STAGE_PAGES 8192 /* 32MB */
|
||||
|
||||
EFI_PHYSICAL_ADDRESS staging;
|
||||
int stage_offset_set = 0;
|
||||
ssize_t stage_offset;
|
||||
|
||||
int
|
||||
x86_efi_copy_init(void)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
|
||||
status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
|
||||
STAGE_PAGES, &staging);
|
||||
if (EFI_ERROR(status)) {
|
||||
printf("failed to allocate staging area: %d\n",
|
||||
status & EFI_ERROR_MASK);
|
||||
return (status);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
x86_efi_copyin(const void *src, vm_offset_t dest, const size_t len)
|
||||
{
|
||||
|
||||
if (!stage_offset_set) {
|
||||
stage_offset = (vm_offset_t)staging - dest;
|
||||
stage_offset_set = 1;
|
||||
}
|
||||
|
||||
bcopy(src, (void *)(dest + stage_offset), len);
|
||||
return (len);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
x86_efi_copyout(const vm_offset_t src, void *dest, const size_t len)
|
||||
{
|
||||
|
||||
bcopy((void *)(src + stage_offset), dest, len);
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
x86_efi_readin(const int fd, vm_offset_t dest, const size_t len)
|
||||
{
|
||||
|
||||
return (read(fd, (void *)(dest + stage_offset), len));
|
||||
}
|
||||
|
||||
void
|
||||
x86_efi_copy_finish(void)
|
||||
{
|
||||
uint64_t *src, *dst, *last;
|
||||
|
||||
src = (uint64_t *)staging;
|
||||
dst = (uint64_t *)(staging - stage_offset);
|
||||
last = (uint64_t *)(staging + STAGE_PAGES * EFI_PAGE_SIZE);
|
||||
|
||||
while (src < last)
|
||||
*dst++ = *src++;
|
||||
}
|
@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
static int i386_parsedev(struct devdesc **, const char *, const char **);
|
||||
static int x86_efi_parsedev(struct devdesc **, const char *, const char **);
|
||||
|
||||
/*
|
||||
* Point (dev) at an allocated device specifier for the device matching the
|
||||
@ -44,7 +44,7 @@ static int i386_parsedev(struct devdesc **, const char *, const char **);
|
||||
* use that. If not, use the default device.
|
||||
*/
|
||||
int
|
||||
i386_getdev(void **vdev, const char *devspec, const char **path)
|
||||
x86_efi_getdev(void **vdev, const char *devspec, const char **path)
|
||||
{
|
||||
struct devdesc **dev = (struct devdesc **)vdev;
|
||||
int rv;
|
||||
@ -54,14 +54,14 @@ i386_getdev(void **vdev, const char *devspec, const char **path)
|
||||
* use the current device instead.
|
||||
*/
|
||||
if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
|
||||
rv = i386_parsedev(dev, getenv("currdev"), NULL);
|
||||
rv = x86_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 (i386_parsedev(dev, devspec, path));
|
||||
return (x86_efi_parsedev(dev, devspec, path));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -78,7 +78,7 @@ i386_getdev(void **vdev, const char *devspec, const char **path)
|
||||
* fs<unit>:
|
||||
*/
|
||||
static int
|
||||
i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
|
||||
x86_efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
|
||||
{
|
||||
struct devdesc *idev;
|
||||
struct devsw *dv;
|
||||
@ -132,7 +132,7 @@ i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
|
||||
}
|
||||
|
||||
char *
|
||||
i386_fmtdev(void *vdev)
|
||||
x86_efi_fmtdev(void *vdev)
|
||||
{
|
||||
struct devdesc *dev = (struct devdesc *)vdev;
|
||||
static char buf[32]; /* XXX device length constant? */
|
||||
@ -154,12 +154,12 @@ i386_fmtdev(void *vdev)
|
||||
* Set currdev to suit the value being supplied in (value)
|
||||
*/
|
||||
int
|
||||
i386_setcurrdev(struct env_var *ev, int flags, const void *value)
|
||||
x86_efi_setcurrdev(struct env_var *ev, int flags, const void *value)
|
||||
{
|
||||
struct devdesc *ncurr;
|
||||
int rv;
|
||||
|
||||
rv = i386_parsedev(&ncurr, value, NULL);
|
||||
rv = x86_efi_parsedev(&ncurr, value, NULL);
|
||||
if (rv != 0)
|
||||
return(rv);
|
||||
|
189
sys/boot/amd64/efi/elf64_freebsd.c
Normal file
189
sys/boot/amd64/efi/elf64_freebsd.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#define __ELF_WORD_SIZE 64
|
||||
#include <sys/param.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/linker.h>
|
||||
#include <string.h>
|
||||
#include <machine/elf.h>
|
||||
#include <stand.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
#include "platform/acfreebsd.h"
|
||||
#include "acconfig.h"
|
||||
#define ACPI_SYSTEM_XFACE
|
||||
#include "actypes.h"
|
||||
#include "actbl.h"
|
||||
|
||||
#include "x86_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);
|
||||
|
||||
struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
|
||||
struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
|
||||
|
||||
#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;
|
||||
EFI_STATUS status;
|
||||
|
||||
rsdp = efi_get_table(&acpi20_guid);
|
||||
if (rsdp == NULL) {
|
||||
rsdp = efi_get_table(&acpi_guid);
|
||||
}
|
||||
if (rsdp != NULL) {
|
||||
sprintf(buf, "0x%016llx", 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", 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);
|
||||
|
||||
err = bi_load(fp->f_args, &modulep, &kernend);
|
||||
if (err != 0)
|
||||
return(err);
|
||||
|
||||
status = BS->ExitBootServices(IH, x86_efi_mapkey);
|
||||
if (EFI_ERROR(status)) {
|
||||
printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
|
||||
(long)status);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
dev_cleanup();
|
||||
|
||||
trampoline(trampstack, x86_efi_copy_finish, kernend, modulep, PT4,
|
||||
ehdr->e_entry);
|
||||
|
||||
panic("exec returned");
|
||||
}
|
||||
|
||||
static int
|
||||
elf64_obj_exec(struct preloaded_file *fp)
|
||||
{
|
||||
return (EFTYPE);
|
||||
}
|
85
sys/boot/amd64/efi/framebuffer.c
Normal file
85
sys/boot/amd64/efi/framebuffer.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <machine/metadata.h>
|
||||
|
||||
static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
|
||||
int
|
||||
efi_find_framebuffer(struct efi_fb *efifb)
|
||||
{
|
||||
EFI_GRAPHICS_OUTPUT *gop;
|
||||
EFI_STATUS status;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
|
||||
status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
|
||||
if (EFI_ERROR(status))
|
||||
return (1);
|
||||
|
||||
mode = gop->Mode;
|
||||
info = gop->Mode->Info;
|
||||
|
||||
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;
|
||||
|
||||
switch (info->PixelFormat) {
|
||||
case PixelRedGreenBlueReserved8BitPerColor:
|
||||
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 = info->PixelInformation.RedMask;
|
||||
efifb->fb_mask_green = info->PixelInformation.GreenMask;
|
||||
efifb->fb_mask_blue = info->PixelInformation.BlueMask;
|
||||
efifb->fb_mask_reserved =
|
||||
info->PixelInformation.ReservedMask;
|
||||
break;
|
||||
default:
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
36
sys/boot/amd64/efi/framebuffer.h
Normal file
36
sys/boot/amd64/efi/framebuffer.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*-
|
||||
* 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_ */
|
@ -7,11 +7,13 @@ SECTIONS
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
. = SIZEOF_HEADERS;
|
||||
.hash : { *(.hash) } /* this MUST come first! */
|
||||
. = ALIGN(4096);
|
||||
.eh_frame : {
|
||||
.eh_frame :
|
||||
{
|
||||
*(.eh_frame)
|
||||
}
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.text : {
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
@ -51,24 +53,14 @@ SECTIONS
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.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.data*)
|
||||
*(.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.*)
|
||||
*(.rela.stab)
|
||||
*(.relaset_*)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.reloc : { *(.reloc) }
|
||||
. = ALIGN(4096);
|
||||
.hash : { *(.hash) }
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <efilib.h>
|
||||
|
||||
#include <bootstrap.h>
|
||||
#include "../libi386/libi386.h"
|
||||
#include "x86_efi.h"
|
||||
|
||||
extern char bootprog_name[];
|
||||
extern char bootprog_rev[];
|
||||
@ -61,7 +61,7 @@ main(int argc, CHAR16 *argv[])
|
||||
EFI_LOADED_IMAGE *img;
|
||||
int i;
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -69,6 +69,11 @@ main(int argc, CHAR16 *argv[])
|
||||
*/
|
||||
cons_probe();
|
||||
|
||||
if (x86_efi_copy_init()) {
|
||||
printf("failed to allocate staging area\n");
|
||||
return (EFI_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
/*
|
||||
* March through the device switch probing for things.
|
||||
*/
|
||||
@ -106,18 +111,18 @@ main(int argc, CHAR16 *argv[])
|
||||
*/
|
||||
BS->SetWatchdogTimer(0, 0, 0, NULL);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev),
|
||||
i386_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset,
|
||||
env_setenv("currdev", EV_VOLATILE, x86_efi_fmtdev(&currdev),
|
||||
x86_efi_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, x86_efi_fmtdev(&currdev), env_noset,
|
||||
env_nounset);
|
||||
|
||||
setenv("LINES", "24", 1); /* optional */
|
||||
|
||||
archsw.arch_autoload = i386_autoload;
|
||||
archsw.arch_getdev = i386_getdev;
|
||||
archsw.arch_copyin = i386_copyin;
|
||||
archsw.arch_copyout = i386_copyout;
|
||||
archsw.arch_readin = i386_readin;
|
||||
|
||||
archsw.arch_autoload = x86_efi_autoload;
|
||||
archsw.arch_getdev = x86_efi_getdev;
|
||||
archsw.arch_copyin = x86_efi_copyin;
|
||||
archsw.arch_copyout = x86_efi_copyout;
|
||||
archsw.arch_readin = x86_efi_readin;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
|
||||
@ -195,7 +200,7 @@ command_memmap(int argc, char *argv[])
|
||||
ndesc = sz / dsz;
|
||||
printf("%23s %12s %12s %8s %4s\n",
|
||||
"Type", "Physical", "Virtual", "#Pages", "Attr");
|
||||
|
||||
|
||||
for (i = 0, p = map; i < ndesc;
|
||||
i++, p = NextMemoryDescriptor(p, dsz)) {
|
||||
printf("%23s %012lx %012lx %08lx ",
|
||||
@ -265,7 +270,7 @@ command_configuration(int argc, char *argv[])
|
||||
}
|
||||
|
||||
return CMD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
|
76
sys/boot/amd64/efi/start.S
Normal file
76
sys/boot/amd64/efi/start.S
Normal file
@ -0,0 +1,76 @@
|
||||
/*-
|
||||
* Copyright (C) 1999 Hewlett-Packard Co.
|
||||
* Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
* Copyright (C) 2005 Intel Co.
|
||||
* Contributed by Fenghua Yu <fenghua.yu@intel.com>.
|
||||
* 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 _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
|
49
sys/boot/amd64/efi/x86_efi.h
Normal file
49
sys/boot/amd64/efi/x86_efi.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* 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 _X86_EFI_COPY_H_
|
||||
#define _X86_EFI_COPY_H_
|
||||
|
||||
int x86_efi_autoload(void);
|
||||
|
||||
int x86_efi_getdev(void **vdev, const char *devspec, const char **path);
|
||||
char *x86_efi_fmtdev(void *vdev);
|
||||
int x86_efi_setcurrdev(struct env_var *ev, int flags, const void *value);
|
||||
|
||||
int x86_efi_copy_init(void);
|
||||
void x86_efi_copy_finish(void);
|
||||
|
||||
ssize_t x86_efi_copyin(const void *src, vm_offset_t dest, const size_t len);
|
||||
ssize_t x86_efi_copyout(const vm_offset_t src, void *dest, const size_t len);
|
||||
ssize_t x86_efi_readin(const int fd, vm_offset_t dest, const size_t len);
|
||||
|
||||
extern UINTN x86_efi_mapkey;
|
||||
|
||||
#endif /* _X86_EFI_COPY_H_ */
|
@ -52,6 +52,7 @@ Revision History
|
||||
#include "efiapi.h"
|
||||
#include "efifs.h"
|
||||
#include "efierr.h"
|
||||
#include "efigop.h"
|
||||
|
||||
#define EFI_STRINGIZE(a) #a
|
||||
#define EFI_PROTOCOL_DEFINITION(a) EFI_STRINGIZE(Protocol/a/a.h)
|
||||
|
122
sys/boot/efi/include/efigop.h
Normal file
122
sys/boot/efi/include/efigop.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* $FreeBSD$ */
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
efigop.h
|
||||
|
||||
Abstract:
|
||||
Info about framebuffers
|
||||
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _EFIGOP_H
|
||||
#define _EFIGOP_H
|
||||
|
||||
#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
|
||||
{ 0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, \
|
||||
0x51, 0x6a }
|
||||
|
||||
INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT);
|
||||
|
||||
typedef struct {
|
||||
UINT32 RedMask;
|
||||
UINT32 GreenMask;
|
||||
UINT32 BlueMask;
|
||||
UINT32 ReservedMask;
|
||||
} EFI_PIXEL_BITMASK;
|
||||
|
||||
typedef enum {
|
||||
PixelRedGreenBlueReserved8BitPerColor,
|
||||
PixelBlueGreenRedReserved8BitPerColor,
|
||||
PixelBitMask,
|
||||
PixelBltOnly,
|
||||
PixelFormatMax,
|
||||
} EFI_GRAPHICS_PIXEL_FORMAT;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
UINT32 HorizontalResolution;
|
||||
UINT32 VerticalResolution;
|
||||
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
|
||||
EFI_PIXEL_BITMASK PixelInformation;
|
||||
UINT32 PixelsPerScanLine;
|
||||
} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
|
||||
|
||||
typedef struct {
|
||||
UINT32 MaxMode;
|
||||
UINT32 Mode;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
|
||||
UINTN SizeOfInfo;
|
||||
EFI_PHYSICAL_ADDRESS FrameBufferBase;
|
||||
UINTN FrameBufferSize;
|
||||
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
|
||||
IN struct _EFI_GRAPHICS_OUTPUT *This,
|
||||
IN UINT32 ModeNumber,
|
||||
OUT UINTN *SizeOfInfo,
|
||||
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
|
||||
IN struct _EFI_GRAPHICS_OUTPUT *This,
|
||||
IN UINT32 ModeNumber
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
UINT8 Blue;
|
||||
UINT8 Green;
|
||||
UINT8 Red;
|
||||
UINT8 Reserved;
|
||||
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
|
||||
|
||||
typedef enum {
|
||||
EfiBltVideoFill,
|
||||
EfiBltVideoToBltBuffer,
|
||||
EfiBltBufferToVideo,
|
||||
EfiBltVideoToVideo,
|
||||
EfiGraphcisOutputBltOperationMax,
|
||||
} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
|
||||
IN struct _EFI_GRAPHICS_OUTPUT *This,
|
||||
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
|
||||
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
|
||||
);
|
||||
|
||||
typedef struct _EFI_GRAPHICS_OUTPUT {
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
|
||||
} EFI_GRAPHICS_OUTPUT;
|
||||
|
||||
#endif /* _EFIGOP_H */
|
Loading…
Reference in New Issue
Block a user