Add initial EFI architecture support
This adds support for running barebox in an EFI environment on X86 PC hardware. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
3475ba2a1d
commit
1dff7e414d
|
@ -46,6 +46,7 @@ barebox.uimage
|
|||
barebox.map
|
||||
barebox.kwb
|
||||
barebox.kwbuart
|
||||
barebox.efi
|
||||
barebox-flash-image
|
||||
System.map
|
||||
Module.symvers
|
||||
|
|
3
Makefile
3
Makefile
|
@ -997,7 +997,8 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
|
|||
.tmp_kallsyms* common/barebox_default_env* barebox.ldr \
|
||||
scripts/bareboxenv-target barebox-flash-image \
|
||||
Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
|
||||
barebox.uimage barebox.spi barebox.kwb barebox.kwbuart
|
||||
barebox.uimage barebox.spi barebox.kwb barebox.kwbuart \
|
||||
barebox.efi
|
||||
|
||||
# Directories & files removed with 'make mrproper'
|
||||
MRPROPER_DIRS += include/config include2 usr/include
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
config ARCH_EFI
|
||||
bool
|
||||
default y
|
||||
select HAS_DEBUG_LL
|
||||
select HAS_KALLSYMS
|
||||
select HAVE_DEFAULT_ENVIRONMENT_NEW
|
||||
select EFI_GUID
|
||||
select EFI_DEVICEPATH
|
||||
select PRINTF_UUID
|
||||
|
||||
config ARCH_TEXT_BASE
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
menu "EFI specific settings"
|
||||
|
||||
config 64BIT
|
||||
def_bool y
|
||||
help
|
||||
Say yes to build a 64-bit binary - formerly known as x86_64
|
||||
Say no to build a 32-bit binary - formerly known as i386.
|
||||
|
||||
32-bit support currently does not compile and is not tested
|
||||
due to the lack of hardware.
|
||||
|
||||
config X86_32
|
||||
def_bool y
|
||||
depends on !64BIT
|
||||
|
||||
config X86_64
|
||||
def_bool y
|
||||
depends on 64BIT
|
||||
|
||||
config ARCH_EFI_REGISTER_COM1
|
||||
bool "Register first serial port"
|
||||
help
|
||||
Say yes here to register the first serial port on ioport 0x3f8.
|
||||
This is useful to control barebox over a serial port if the board
|
||||
has one. Enabling this option may not work on boards which do not
|
||||
have a serial port. Also enable DRIVER_SERIAL_NS16550 to enable
|
||||
the NS16550 driver.
|
||||
|
||||
endmenu
|
||||
|
||||
source common/Kconfig
|
||||
source commands/Kconfig
|
||||
source net/Kconfig
|
||||
source drivers/Kconfig
|
||||
source fs/Kconfig
|
||||
source lib/Kconfig
|
||||
source crypto/Kconfig
|
|
@ -0,0 +1,41 @@
|
|||
CFLAGS += -fpic -fshort-wchar -mno-sse -mno-mmx
|
||||
|
||||
ifeq ($(CONFIG_X86_32),y)
|
||||
UTS_MACHINE := i386
|
||||
biarch := $(call cc-option,-m32)
|
||||
AFLAGS += $(biarch)
|
||||
CFLAGS += $(biarch)
|
||||
TARGET = efi-app-ia32
|
||||
else
|
||||
UTS_MACHINE := x86_64
|
||||
AFLAGS += -m64
|
||||
CFLAGS += -m64 -mno-red-zone
|
||||
TARGET = efi-app-x86_64
|
||||
endif
|
||||
|
||||
lds-$(CONFIG_X86_32) := arch/efi/lib/elf_ia32_efi.lds
|
||||
lds-$(CONFIG_X86_64) := arch/efi/lib/elf_x86_64_efi.lds
|
||||
|
||||
cmd_barebox__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_barebox) -o $@ \
|
||||
-T $(lds-y) \
|
||||
-shared -Bsymbolic -nostdlib -znocombreloc \
|
||||
--start-group $(barebox-common) \
|
||||
--end-group \
|
||||
$(filter-out $(barebox-lds) $(barebox-common) FORCE ,$^)
|
||||
|
||||
quiet_cmd_efi_image = EFI-IMG $@
|
||||
cmd_efi_image = objcopy -j .text -j .sdata -j .data -j .dynamic \
|
||||
-j .dynsym -j .rel -j .rela -j .reloc -j __barebox_initcalls \
|
||||
-j __barebox_cmd -j .barebox_magicvar -j .bbenv.* \
|
||||
--target=$(TARGET) $< $@
|
||||
|
||||
KBUILD_BINARY := barebox
|
||||
|
||||
LDFLAGS := -m elf_$(UTS_MACHINE) --no-undefined
|
||||
|
||||
barebox.efi: $(KBUILD_BINARY) FORCE
|
||||
$(call if_changed,efi_image)
|
||||
|
||||
KBUILD_IMAGE := barebox.efi
|
||||
|
||||
common-y += arch/efi/efi/ arch/efi/lib/
|
|
@ -0,0 +1,78 @@
|
|||
CONFIG_MMU=y
|
||||
CONFIG_MALLOC_SIZE=0x0
|
||||
CONFIG_MALLOC_TLSF=y
|
||||
CONFIG_PROMPT="barebox> "
|
||||
CONFIG_HUSH_FANCY_PROMPT=y
|
||||
CONFIG_CMDLINE_EDITING=y
|
||||
CONFIG_AUTO_COMPLETE=y
|
||||
CONFIG_MENU=y
|
||||
# CONFIG_TIMESTAMP is not set
|
||||
CONFIG_CONSOLE_ACTIVATE_ALL=y
|
||||
CONFIG_PARTITION_DISK_EFI=y
|
||||
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
|
||||
CONFIG_POLLER=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_LONGHELP=y
|
||||
CONFIG_CMD_IOMEM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
CONFIG_CMD_BOOTM_SHOW_TYPE=y
|
||||
CONFIG_CMD_BOOTM_VERBOSE=y
|
||||
CONFIG_CMD_BOOTM_INITRD=y
|
||||
CONFIG_CMD_BOOTM_OFTREE=y
|
||||
CONFIG_CMD_GO=y
|
||||
CONFIG_CMD_LOADB=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_UIMAGE=y
|
||||
CONFIG_CMD_PARTITION=y
|
||||
CONFIG_CMD_EXPORT=y
|
||||
CONFIG_CMD_LOADENV=y
|
||||
CONFIG_CMD_PRINTENV=y
|
||||
CONFIG_CMD_MAGICVAR=y
|
||||
CONFIG_CMD_MAGICVAR_HELP=y
|
||||
CONFIG_CMD_SAVEENV=y
|
||||
CONFIG_CMD_FILETYPE=y
|
||||
CONFIG_CMD_LN=y
|
||||
CONFIG_CMD_MD5SUM=y
|
||||
CONFIG_CMD_UNCOMPRESS=y
|
||||
CONFIG_CMD_LET=y
|
||||
CONFIG_CMD_MSLEEP=y
|
||||
CONFIG_CMD_READF=y
|
||||
CONFIG_CMD_SLEEP=y
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_HOST=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_TFTP=y
|
||||
CONFIG_CMD_ECHO_E=y
|
||||
CONFIG_CMD_EDIT=y
|
||||
CONFIG_CMD_MENU=y
|
||||
CONFIG_CMD_MENUTREE=y
|
||||
CONFIG_CMD_READLINE=y
|
||||
CONFIG_CMD_TIMEOUT=y
|
||||
CONFIG_CMD_CRC=y
|
||||
CONFIG_CMD_CRC_CMP=y
|
||||
CONFIG_CMD_MM=y
|
||||
CONFIG_CMD_DETECT=y
|
||||
CONFIG_CMD_FLASH=y
|
||||
CONFIG_CMD_2048=y
|
||||
CONFIG_CMD_BAREBOX_UPDATE=y
|
||||
CONFIG_CMD_OF_NODE=y
|
||||
CONFIG_CMD_OF_PROPERTY=y
|
||||
CONFIG_CMD_OFTREE=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NFS=y
|
||||
CONFIG_NET_NETCONSOLE=y
|
||||
CONFIG_DRIVER_SERIAL_EFI_STDIO=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
||||
CONFIG_DRIVER_NET_EFI_SNP=y
|
||||
# CONFIG_SPI is not set
|
||||
CONFIG_DISK=y
|
||||
CONFIG_FS_EXT4=y
|
||||
CONFIG_FS_TFTP=y
|
||||
CONFIG_FS_NFS=y
|
||||
CONFIG_FS_EFI=y
|
||||
CONFIG_FS_EFIVARFS=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FS_FAT_WRITE=y
|
||||
CONFIG_FS_FAT_LFN=y
|
|
@ -0,0 +1,2 @@
|
|||
obj-y += efi.o clocksource.o efi-block-io.o efi-device.o efi-image.o
|
||||
bbenv-y += env-efi
|
|
@ -0,0 +1,60 @@
|
|||
#include <common.h>
|
||||
#include <efi.h>
|
||||
#include <mach/efi.h>
|
||||
#include <clock.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
uint64_t ticks_read(void)
|
||||
{
|
||||
uint64_t a, d;
|
||||
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
|
||||
return (d << 32) | a;
|
||||
}
|
||||
#else
|
||||
uint64_t ticks_read(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
__asm__ volatile ("rdtsc" : "=A" (val));
|
||||
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint64_t freq;
|
||||
|
||||
/* count TSC ticks during a millisecond delay */
|
||||
static uint64_t ticks_freq(void)
|
||||
{
|
||||
uint64_t ticks_start, ticks_end;
|
||||
|
||||
ticks_start = ticks_read();
|
||||
BS->stall(1000);
|
||||
ticks_end = ticks_read();
|
||||
|
||||
return (ticks_end - ticks_start) * 1000;
|
||||
}
|
||||
|
||||
static uint64_t efi_clocksource_read(void)
|
||||
{
|
||||
return 1000 * 1000 * ticks_read() / freq;
|
||||
}
|
||||
|
||||
static struct clocksource cs = {
|
||||
.read = efi_clocksource_read,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.shift = 0,
|
||||
};
|
||||
|
||||
int efi_clocksource_init(void)
|
||||
{
|
||||
cs.mult = clocksource_hz2mult(1000 * 1000, cs.shift);
|
||||
|
||||
freq = ticks_freq();
|
||||
|
||||
init_clock(&cs);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
#include <common.h>
|
||||
#include <driver.h>
|
||||
#include <init.h>
|
||||
#include <malloc.h>
|
||||
#include <fs.h>
|
||||
#include <string.h>
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <linux/stat.h>
|
||||
#include <xfuncs.h>
|
||||
#include <fcntl.h>
|
||||
#include <efi.h>
|
||||
#include <block.h>
|
||||
#include <disks.h>
|
||||
#include <mach/efi.h>
|
||||
#include <mach/efi-device.h>
|
||||
|
||||
#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
|
||||
#define EFI_BLOCK_IO_PROTOCOL_REVISION3 ((2<<16) | (31))
|
||||
|
||||
struct efi_block_io_media{
|
||||
u32 media_id;
|
||||
bool removable_media;
|
||||
bool media_present;
|
||||
bool logical_partition;
|
||||
bool read_only;
|
||||
bool write_caching;
|
||||
u32 block_size;
|
||||
u32 io_align;
|
||||
u64 last_block;
|
||||
u64 lowest_aligned_lba; /* added in Revision 2 */
|
||||
u32 logical_blocks_per_physical_block; /* added in Revision 2 */
|
||||
u32 optimal_transfer_length_granularity; /* added in Revision 3 */
|
||||
};
|
||||
|
||||
struct efi_block_io_protocol {
|
||||
u64 revision;
|
||||
struct efi_block_io_media *media;
|
||||
efi_status_t(EFIAPI *reset)(struct efi_block_io_protocol *this,
|
||||
bool ExtendedVerification);
|
||||
efi_status_t(EFIAPI *read)(struct efi_block_io_protocol *this, u32 media_id,
|
||||
u64 lba, unsigned long buffer_size, void *buf);
|
||||
efi_status_t(EFIAPI *write)(struct efi_block_io_protocol *this, u32 media_id,
|
||||
u64 lba, unsigned long buffer_size, void *buf);
|
||||
efi_status_t(EFIAPI *flush)(struct efi_block_io_protocol *this);
|
||||
};
|
||||
|
||||
struct efi_bio_priv {
|
||||
struct efi_block_io_protocol *protocol;
|
||||
struct device_d *dev;
|
||||
struct block_device blk;
|
||||
u32 media_id;
|
||||
};
|
||||
|
||||
static int efi_bio_read(struct block_device *blk, void *buffer, int block,
|
||||
int num_blocks)
|
||||
{
|
||||
struct efi_bio_priv *priv = container_of(blk, struct efi_bio_priv, blk);
|
||||
efi_status_t efiret;
|
||||
|
||||
efiret = priv->protocol->read(priv->protocol, priv->media_id,
|
||||
block, num_blocks * 512, buffer);
|
||||
|
||||
if (EFI_ERROR(efiret))
|
||||
return -efi_errno(efiret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efi_bio_write(struct block_device *blk,
|
||||
const void *buffer, int block, int num_blocks)
|
||||
{
|
||||
struct efi_bio_priv *priv = container_of(blk, struct efi_bio_priv, blk);
|
||||
efi_status_t efiret;
|
||||
|
||||
efiret = priv->protocol->write(priv->protocol, priv->media_id,
|
||||
block, num_blocks * 512, (void *)buffer);
|
||||
if (EFI_ERROR(efiret))
|
||||
return -efi_errno(efiret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efi_bio_flush(struct block_device *blk)
|
||||
{
|
||||
struct efi_bio_priv *priv = container_of(blk, struct efi_bio_priv, blk);
|
||||
efi_status_t efiret;
|
||||
|
||||
efiret = priv->protocol->flush(priv->protocol);
|
||||
if (EFI_ERROR(efiret))
|
||||
return -efi_errno(efiret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct block_device_ops efi_bio_ops = {
|
||||
.read = efi_bio_read,
|
||||
.write = efi_bio_write,
|
||||
.flush = efi_bio_flush,
|
||||
};
|
||||
|
||||
static void efi_bio_print_info(struct efi_bio_priv *priv)
|
||||
{
|
||||
struct efi_block_io_media *media = priv->protocol->media;
|
||||
u64 revision = priv->protocol->revision;
|
||||
|
||||
dev_dbg(priv->dev, "revision: 0x%016llx\n", revision);
|
||||
dev_dbg(priv->dev, "media_id: 0x%08x\n", media->media_id);
|
||||
dev_dbg(priv->dev, "removable_media: %d\n", media->removable_media);
|
||||
dev_dbg(priv->dev, "media_present: %d\n", media->media_present);
|
||||
dev_dbg(priv->dev, "logical_partition: %d\n", media->logical_partition);
|
||||
dev_dbg(priv->dev, "read_only: %d\n", media->read_only);
|
||||
dev_dbg(priv->dev, "write_caching: %d\n", media->write_caching);
|
||||
dev_dbg(priv->dev, "block_size: 0x%08x\n", media->block_size);
|
||||
dev_dbg(priv->dev, "io_align: 0x%08x\n", media->io_align);
|
||||
dev_dbg(priv->dev, "last_block: 0x%016llx\n", media->last_block);
|
||||
|
||||
if (revision < EFI_BLOCK_IO_PROTOCOL_REVISION2)
|
||||
return;
|
||||
|
||||
dev_dbg(priv->dev, "u64 lowest_aligned_lba: 0x%08llx\n",
|
||||
media->lowest_aligned_lba);
|
||||
dev_dbg(priv->dev, "logical_blocks_per_physical_block: 0x%08x\n",
|
||||
media->logical_blocks_per_physical_block);
|
||||
|
||||
if (revision < EFI_BLOCK_IO_PROTOCOL_REVISION3)
|
||||
return;
|
||||
|
||||
dev_dbg(priv->dev, "optimal_transfer_length_granularity: 0x%08x\n",
|
||||
media->optimal_transfer_length_granularity);
|
||||
}
|
||||
|
||||
int efi_bio_probe(struct efi_device *efidev)
|
||||
{
|
||||
int ret;
|
||||
struct efi_bio_priv *priv;
|
||||
struct efi_block_io_media *media;
|
||||
|
||||
priv = xzalloc(sizeof(*priv));
|
||||
|
||||
BS->handle_protocol(efidev->handle, &efi_block_io_protocol_guid,
|
||||
(void **)&priv->protocol);
|
||||
if (!priv->protocol)
|
||||
return -ENODEV;
|
||||
|
||||
media = priv->protocol->media;
|
||||
efi_bio_print_info(priv);
|
||||
priv->dev = &efidev->dev;
|
||||
|
||||
priv->blk.cdev.name = asprintf("disk%d", cdev_find_free_index("disk"));
|
||||
priv->blk.blockbits = ffs(media->block_size) - 1;
|
||||
priv->blk.num_blocks = media->last_block;
|
||||
priv->blk.ops = &efi_bio_ops;
|
||||
priv->blk.dev = &efidev->dev;
|
||||
|
||||
priv->media_id = media->media_id;
|
||||
|
||||
ret = blockdevice_register(&priv->blk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
parse_partition_table(&priv->blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct efi_driver efi_fs_driver = {
|
||||
.driver = {
|
||||
.name = "efi-block-io",
|
||||
},
|
||||
.probe = efi_bio_probe,
|
||||
.guid = EFI_BLOCK_IO_PROTOCOL_GUID,
|
||||
};
|
||||
device_efi_driver(efi_fs_driver);
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* efi-device.c - barebox EFI payload support
|
||||
*
|
||||
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <command.h>
|
||||
#include <common.h>
|
||||
#include <driver.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <sizes.h>
|
||||
#include <wchar.h>
|
||||
#include <init.h>
|
||||
#include <efi.h>
|
||||
#include <mach/efi.h>
|
||||
#include <mach/efi-device.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int efi_locate_handle(enum efi_locate_search_type search_type,
|
||||
efi_guid_t *protocol,
|
||||
void *search_key,
|
||||
unsigned long *no_handles,
|
||||
efi_handle_t **buffer)
|
||||
{
|
||||
efi_status_t efiret;
|
||||
unsigned long buffer_size = 0;
|
||||
efi_handle_t *buf;
|
||||
|
||||
efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size,
|
||||
NULL);
|
||||
if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL)
|
||||
return -efi_errno(efiret);
|
||||
|
||||
buf = malloc(buffer_size);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size,
|
||||
buf);
|
||||
if (EFI_ERROR(efiret)) {
|
||||
free(buf);
|
||||
return -efi_errno(efiret);
|
||||
}
|
||||
|
||||
*no_handles = buffer_size / sizeof(efi_handle_t);
|
||||
*buffer = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct efi_device *efi_find_device(efi_handle_t *handle)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct efi_device *efidev;
|
||||
|
||||
bus_for_each_device(&efi_bus, dev) {
|
||||
efidev = container_of(dev, struct efi_device, dev);
|
||||
|
||||
if (efidev->handle == handle)
|
||||
return efidev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void efi_devinfo(struct device_d *dev)
|
||||
{
|
||||
struct efi_device *efidev = to_efi_device(dev);
|
||||
int i;
|
||||
|
||||
printf("Protocols:\n");
|
||||
|
||||
for (i = 0; i < efidev->num_guids; i++)
|
||||
printf(" %d: %pUl\n", i, &efidev->guids[i]);
|
||||
}
|
||||
|
||||
static efi_handle_t *efi_find_parent(efi_handle_t *handle)
|
||||
{
|
||||
unsigned long handle_count = 0;
|
||||
efi_handle_t *handles = NULL, *parent;
|
||||
unsigned long num_guids;
|
||||
efi_guid_t **guids;
|
||||
int ret, i, j, k;
|
||||
efi_status_t efiret;
|
||||
struct efi_open_protocol_information_entry *entry_buffer;
|
||||
unsigned long entry_count;
|
||||
|
||||
ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Normally one would expect a function/pointer to retrieve the parent.
|
||||
* With EFI we have to:
|
||||
* - get all handles
|
||||
* - for each handle get the registered protocols
|
||||
* - for each protocol get the users
|
||||
* - the user which matches the input handle is the parent
|
||||
*/
|
||||
for (i = 0; i < handle_count; i++) {
|
||||
efiret = BS->open_protocol(handles[i], &efi_device_path_protocol_guid,
|
||||
NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
|
||||
if (EFI_ERROR(efiret))
|
||||
continue;
|
||||
|
||||
BS->protocols_per_handle(handles[i], &guids, &num_guids);
|
||||
for (j = 0; j < num_guids; j++) {
|
||||
efiret = BS->open_protocol_information(handles[i], guids[j],
|
||||
&entry_buffer, &entry_count);
|
||||
for (k = 0; k < entry_count; k++) {
|
||||
if (entry_buffer[k].controller_handle == NULL)
|
||||
continue;
|
||||
if (entry_buffer[k].controller_handle == handles[i])
|
||||
continue;
|
||||
if (entry_buffer[k].controller_handle == handle) {
|
||||
parent = handles[i];
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent = NULL;
|
||||
|
||||
free(handles);
|
||||
out:
|
||||
return parent;
|
||||
}
|
||||
|
||||
static struct efi_device *efi_add_device(efi_handle_t *handle, efi_guid_t **guids,
|
||||
int num_guids)
|
||||
{
|
||||
struct efi_device *efidev;
|
||||
int i;
|
||||
efi_guid_t *guidarr;
|
||||
efi_status_t efiret;
|
||||
void *devpath;
|
||||
|
||||
efidev = efi_find_device(handle);
|
||||
if (efidev)
|
||||
return ERR_PTR(-EEXIST);
|
||||
|
||||
efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid,
|
||||
NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
|
||||
if (EFI_ERROR(efiret))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
guidarr = malloc(sizeof(efi_guid_t) * num_guids);
|
||||
|
||||
for (i = 0; i < num_guids; i++)
|
||||
memcpy(&guidarr[i], guids[i], sizeof(efi_guid_t));
|
||||
|
||||
efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid,
|
||||
&devpath, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(efiret))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
efidev = xzalloc(sizeof(*efidev));
|
||||
|
||||
efidev->guids = guidarr;
|
||||
efidev->num_guids = num_guids;
|
||||
efidev->handle = handle;
|
||||
efidev->dev.bus = &efi_bus;
|
||||
efidev->dev.id = DEVICE_ID_SINGLE;
|
||||
efidev->dev.info = efi_devinfo;
|
||||
efidev->devpath = devpath;
|
||||
|
||||
BS->handle_protocol(handle, &guidarr[0], &efidev->protocol);
|
||||
|
||||
sprintf(efidev->dev.name, "handle-%p", handle);
|
||||
|
||||
efidev->parent_handle = efi_find_parent(efidev->handle);
|
||||
|
||||
return efidev;
|
||||
}
|
||||
|
||||
|
||||
static int efi_register_device(struct efi_device *efidev)
|
||||
{
|
||||
char *dev_path_str;
|
||||
struct efi_device *parent;
|
||||
int ret;
|
||||
|
||||
if (efi_find_device(efidev->handle))
|
||||
return -EEXIST;
|
||||
|
||||
if (efidev->parent_handle) {
|
||||
parent = efi_find_device(efidev->parent_handle);
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
efidev->dev.parent = &parent->dev;
|
||||
}
|
||||
|
||||
ret = register_device(&efidev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_path_str = device_path_to_str(efidev->devpath);
|
||||
if (dev_path_str) {
|
||||
dev_add_param_fixed(&efidev->dev, "devpath", dev_path_str);
|
||||
free(dev_path_str);
|
||||
}
|
||||
|
||||
debug("registered efi device %s\n", dev_name(&efidev->dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_register_devices - iterate over all EFI handles and register
|
||||
* the devices found
|
||||
*
|
||||
* in barebox we treat all EFI handles which support the device_path
|
||||
* protocol as devices. This function iterates over all handles and
|
||||
* registers the corresponding devices. efi_register_devices is safe
|
||||
* to call multiple times. Already registered devices will be ignored.
|
||||
*
|
||||
*/
|
||||
void efi_register_devices(void)
|
||||
{
|
||||
unsigned long handle_count = 0;
|
||||
efi_handle_t *handles = NULL;
|
||||
unsigned long num_guids;
|
||||
efi_guid_t **guids;
|
||||
int ret, i;
|
||||
struct efi_device **efidevs;
|
||||
int registered;
|
||||
|
||||
ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
efidevs = xzalloc(handle_count * sizeof(struct efi_device *));
|
||||
|
||||
for (i = 0; i < handle_count; i++) {
|
||||
BS->protocols_per_handle(handles[i], &guids, &num_guids);
|
||||
|
||||
efidevs[i] = efi_add_device(handles[i], guids, num_guids);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a list of devices we want to register, but can only
|
||||
* register a device when all parents are registered already.
|
||||
* Do this by continiously iterating over the list until no
|
||||
* further devices are registered.
|
||||
*/
|
||||
do {
|
||||
registered = 0;
|
||||
|
||||
for (i = 0; i < handle_count; i++) {
|
||||
if (IS_ERR(efidevs[i]))
|
||||
continue;
|
||||
|
||||
ret = efi_register_device(efidevs[i]);
|
||||
if (!ret) {
|
||||
efidevs[i] = ERR_PTR(-EEXIST);
|
||||
registered = 1;
|
||||
}
|
||||
}
|
||||
} while (registered);
|
||||
|
||||
free(efidevs);
|
||||
free(handles);
|
||||
}
|
||||
|
||||
int efi_connect_all(void)
|
||||
{
|
||||
efi_status_t efiret;
|
||||
unsigned long handle_count;
|
||||
efi_handle_t *handle_buffer;
|
||||
int i;
|
||||
|
||||
efiret = BS->locate_handle_buffer(all_handles, NULL, NULL, &handle_count,
|
||||
&handle_buffer);
|
||||
if (EFI_ERROR(efiret))
|
||||
return -efi_errno(efiret);
|
||||
|
||||
for (i = 0; i < handle_count; i++)
|
||||
efiret = BS->connect_controller(handle_buffer[i], NULL, NULL, true);
|
||||
|
||||
if (handle_buffer)
|
||||
BS->free_pool(handle_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efi_bus_match(struct device_d *dev, struct driver_d *drv)
|
||||
{
|
||||
struct efi_driver *efidrv = to_efi_driver(drv);
|
||||
struct efi_device *efidev = to_efi_device(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < efidev->num_guids; i++) {
|
||||
if (!memcmp(&efidrv->guid, &efidev->guids[i], sizeof(efi_guid_t)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int efi_bus_probe(struct device_d *dev)
|
||||
{
|
||||
struct efi_driver *efidrv = to_efi_driver(dev->driver);
|
||||
struct efi_device *efidev = to_efi_device(dev);
|
||||
|
||||
return efidrv->probe(efidev);
|
||||
}
|
||||
|
||||
static void efi_bus_remove(struct device_d *dev)
|
||||
{
|
||||
struct efi_driver *efidrv = to_efi_driver(dev->driver);
|
||||
struct efi_device *efidev = to_efi_device(dev);
|
||||
|
||||
return efidrv->remove(efidev);
|
||||
}
|
||||
|
||||
struct bus_type efi_bus = {
|
||||
.name = "efi",
|
||||
.match = efi_bus_match,
|
||||
.probe = efi_bus_probe,
|
||||
.remove = efi_bus_remove,
|
||||
};
|
||||
|
||||
static int efi_init_devices(void)
|
||||
{
|
||||
bus_register(&efi_bus);
|
||||
|
||||
efi_register_devices();
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(efi_init_devices);
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* efi-image.c - barebox EFI payload support
|
||||
*
|
||||
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <sizes.h>
|
||||
#include <memory.h>
|
||||
#include <command.h>
|
||||
#include <magicvar.h>
|
||||
#include <init.h>
|
||||
#include <driver.h>
|
||||
#include <io.h>
|
||||
#include <efi.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <linux/err.h>
|
||||
#include <boot.h>
|
||||
#include <fs.h>
|
||||
#include <binfmt.h>
|
||||
#include <wchar.h>
|
||||
#include <mach/efi.h>
|
||||
#include <mach/efi-device.h>
|
||||
|
||||
static int efi_execute_image(const char *file)
|
||||
{
|
||||
void *exe;
|
||||
size_t size;
|
||||
efi_handle_t handle;
|
||||
efi_status_t efiret;
|
||||
const char *options;
|
||||
efi_loaded_image_t *loaded_image;
|
||||
|
||||
exe = read_file(file, &size);
|
||||
if (!exe)
|
||||
return -EINVAL;
|
||||
|
||||
efiret = BS->load_image(false, efi_parent_image, efi_device_path, exe, size,
|
||||
&handle);
|
||||
if (EFI_ERROR(efiret)) {
|
||||
pr_err("failed to LoadImage: %s\n", efi_strerror(efiret));
|
||||
return -efi_errno(efiret);;
|
||||
};
|
||||
|
||||
efiret = BS->open_protocol(handle, &efi_loaded_image_protocol_guid,
|
||||
(void **)&loaded_image,
|
||||
efi_parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(efiret))
|
||||
return -efi_errno(efiret);
|
||||
|
||||
options = linux_bootargs_get();
|
||||
loaded_image->load_options = strdup_char_to_wchar(options);
|
||||
loaded_image->load_options_size = (strlen(options) + 1) * sizeof(wchar_t);
|
||||
|
||||
efiret = BS->start_image(handle, NULL, NULL);
|
||||
|
||||
efi_connect_all();
|
||||
efi_register_devices();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_bootm_efi(struct image_data *data)
|
||||
{
|
||||
return efi_execute_image(data->os_file);
|
||||
}
|
||||
|
||||
static struct image_handler efi_handle_tr = {
|
||||
.name = "EFI Application",
|
||||
.bootm = do_bootm_efi,
|
||||
.filetype = filetype_exe,
|
||||
};
|
||||
|
||||
static int efi_execute(struct binfmt_hook *b, char *file, int argc, char **argv)
|
||||
{
|
||||
return efi_execute_image(file);
|
||||
}
|
||||
|
||||
static struct binfmt_hook binfmt_efi_hook = {
|
||||
.type = filetype_exe,
|
||||
.hook = efi_execute,
|
||||
};
|
||||
|
||||
static int efi_register_image_handler(void)
|
||||
{
|
||||
register_image_handler(&efi_handle_tr);
|
||||
binfmt_register(&binfmt_efi_hook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(efi_register_image_handler);
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* efi.c - barebox EFI payload support
|
||||
*
|
||||
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <sizes.h>
|
||||
#include <memory.h>
|
||||
#include <clock.h>
|
||||
#include <command.h>
|
||||
#include <magicvar.h>
|
||||
#include <init.h>
|
||||
#include <driver.h>
|
||||
#include <ns16550.h>
|
||||
#include <io.h>
|
||||
#include <efi.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <linux/err.h>
|
||||
#include <boot.h>
|
||||
#include <fs.h>
|
||||
#include <binfmt.h>
|
||||
#include <wchar.h>
|
||||
#include <envfs.h>
|
||||
#include <mach/efi.h>
|
||||
#include <mach/efi-device.h>
|
||||
|
||||
efi_runtime_services_t *RT;
|
||||
efi_boot_services_t *BS;
|
||||
efi_system_table_t *efi_sys_table;
|
||||
efi_handle_t efi_parent_image;
|
||||
struct efi_device_path *efi_device_path;
|
||||
efi_loaded_image_t *efi_loaded_image;
|
||||
|
||||
void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size)
|
||||
{
|
||||
efi_status_t efiret;
|
||||
void *buf;
|
||||
unsigned long size = 0;
|
||||
s16 *name16 = strdup_char_to_wchar(name);
|
||||
|
||||
efiret = RT->get_variable(name16, vendor, NULL, &size, NULL);
|
||||
|
||||
if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) {
|
||||
buf = ERR_PTR(-efi_errno(efiret));
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
buf = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
efiret = RT->get_variable(name16, vendor, NULL, &size, buf);
|
||||
if (EFI_ERROR(efiret)) {
|
||||
free(buf);
|
||||
buf = ERR_PTR(-efi_errno(efiret));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (var_size)
|
||||
*var_size = size;
|
||||
|
||||
out:
|
||||
free(name16);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct efi_boot {
|
||||
u32 attributes;
|
||||
u16 file_path_len;
|
||||
char *description;
|
||||
struct efi_device_path *path;
|
||||
void *binary;
|
||||
};
|
||||
|
||||
struct efi_boot *efi_get_boot(int num)
|
||||
{
|
||||
struct efi_boot *boot = xzalloc(sizeof(*boot));
|
||||
void *buf, *ptr;
|
||||
int size;
|
||||
char *name;
|
||||
|
||||
name = asprintf("Boot%04X", num);
|
||||
|
||||
buf = efi_get_global_var(name, &size);
|
||||
|
||||
free(name);
|
||||
|
||||
if (!buf) {
|
||||
free(boot);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
|
||||
boot->attributes = *(u32 *)ptr;
|
||||
|
||||
ptr += sizeof(u32);
|
||||
|
||||
boot->file_path_len = *(u16 *)ptr;
|
||||
|
||||
ptr += sizeof(u16);
|
||||
|
||||
boot->description = strdup_wchar_to_char(ptr);
|
||||
|
||||
ptr += (strlen(boot->description) + 1) * 2;
|
||||
|
||||
printf("description: %s\n", boot->description);
|
||||
|
||||
boot->path = memdup(ptr, boot->file_path_len);
|
||||
|
||||
printf("path: %s\n", device_path_to_str(boot->path));
|
||||
|
||||
return boot;
|
||||
}
|
||||
|
||||
static int misc_init(void)
|
||||
{
|
||||
efi_get_boot(1);
|
||||
efi_get_boot(2);
|
||||
efi_get_boot(3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(misc_init);
|
||||
|
||||
const char *efi_strerror(efi_status_t err)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (err) {
|
||||
case EFI_SUCCESS: str = "Success"; break;
|
||||
case EFI_LOAD_ERROR: str = "Load Error"; break;
|
||||
case EFI_INVALID_PARAMETER: str = "Invalid Parameter"; break;
|
||||
case EFI_UNSUPPORTED: str = "Unsupported"; break;
|
||||
case EFI_BAD_BUFFER_SIZE: str = "Bad Buffer Size"; break;
|
||||
case EFI_BUFFER_TOO_SMALL: str = "Buffer Too Small"; break;
|
||||
case EFI_NOT_READY: str = "Not Ready"; break;
|
||||
case EFI_DEVICE_ERROR: str = "Device Error"; break;
|
||||
case EFI_WRITE_PROTECTED: str = "Write Protected"; break;
|
||||
case EFI_OUT_OF_RESOURCES: str = "Out of Resources"; break;
|
||||
case EFI_VOLUME_CORRUPTED: str = "Volume Corrupt"; break;
|
||||
case EFI_VOLUME_FULL: str = "Volume Full"; break;
|
||||
case EFI_NO_MEDIA: str = "No Media"; break;
|
||||
case EFI_MEDIA_CHANGED: str = "Media changed"; break;
|
||||
case EFI_NOT_FOUND: str = "Not Found"; break;
|
||||
case EFI_ACCESS_DENIED: str = "Access Denied"; break;
|
||||
case EFI_NO_RESPONSE: str = "No Response"; break;
|
||||
case EFI_NO_MAPPING: str = "No mapping"; break;
|
||||
case EFI_TIMEOUT: str = "Time out"; break;
|
||||
case EFI_NOT_STARTED: str = "Not started"; break;
|
||||
case EFI_ALREADY_STARTED: str = "Already started"; break;
|
||||
case EFI_ABORTED: str = "Aborted"; break;
|
||||
case EFI_ICMP_ERROR: str = "ICMP Error"; break;
|
||||
case EFI_TFTP_ERROR: str = "TFTP Error"; break;
|
||||
case EFI_PROTOCOL_ERROR: str = "Protocol Error"; break;
|
||||
case EFI_INCOMPATIBLE_VERSION: str = "Incompatible Version"; break;
|
||||
case EFI_SECURITY_VIOLATION: str = "Security Violation"; break;
|
||||
case EFI_CRC_ERROR: str = "CRC Error"; break;
|
||||
case EFI_END_OF_MEDIA: str = "End of Media"; break;
|
||||
case EFI_END_OF_FILE: str = "End of File"; break;
|
||||
case EFI_INVALID_LANGUAGE: str = "Invalid Language"; break;
|
||||
case EFI_COMPROMISED_DATA: str = "Compromised Data"; break;
|
||||
default: str = "unknown error";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int efi_errno(efi_status_t err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (err) {
|
||||
case EFI_SUCCESS: ret = 0; break;
|
||||
case EFI_LOAD_ERROR: ret = EIO; break;
|
||||
case EFI_INVALID_PARAMETER: ret = EINVAL; break;
|
||||
case EFI_UNSUPPORTED: ret = ENOTSUPP; break;
|
||||
case EFI_BAD_BUFFER_SIZE: ret = EINVAL; break;
|
||||
case EFI_BUFFER_TOO_SMALL: ret = EINVAL; break;
|
||||
case EFI_NOT_READY: ret = EAGAIN; break;
|
||||
case EFI_DEVICE_ERROR: ret = EIO; break;
|
||||
case EFI_WRITE_PROTECTED: ret = EROFS; break;
|
||||
case EFI_OUT_OF_RESOURCES: ret = ENOMEM; break;
|
||||
case EFI_VOLUME_CORRUPTED: ret = EIO; break;
|
||||
case EFI_VOLUME_FULL: ret = ENOSPC; break;
|
||||
case EFI_NO_MEDIA: ret = ENOMEDIUM; break;
|
||||
case EFI_MEDIA_CHANGED: ret = ENOMEDIUM; break;
|
||||
case EFI_NOT_FOUND: ret = ENODEV; break;
|
||||
case EFI_ACCESS_DENIED: ret = EACCES; break;
|
||||
case EFI_NO_RESPONSE: ret = ETIMEDOUT; break;
|
||||
case EFI_NO_MAPPING: ret = EINVAL; break;
|
||||
case EFI_TIMEOUT: ret = ETIMEDOUT; break;
|
||||
case EFI_NOT_STARTED: ret = EINVAL; break;
|
||||
case EFI_ALREADY_STARTED: ret = EINVAL; break;
|
||||
case EFI_ABORTED: ret = EINTR; break;
|
||||
case EFI_ICMP_ERROR: ret = EINVAL; break;
|
||||
case EFI_TFTP_ERROR: ret = EINVAL; break;
|
||||
case EFI_PROTOCOL_ERROR: ret = EPROTO; break;
|
||||
case EFI_INCOMPATIBLE_VERSION: ret = EINVAL; break;
|
||||
case EFI_SECURITY_VIOLATION: ret = EINVAL; break;
|
||||
case EFI_CRC_ERROR: ret = EINVAL; break;
|
||||
case EFI_END_OF_MEDIA: ret = EINVAL; break;
|
||||
case EFI_END_OF_FILE: ret = EINVAL; break;
|
||||
case EFI_INVALID_LANGUAGE: ret = EINVAL; break;
|
||||
case EFI_COMPROMISED_DATA: ret = EINVAL; break;
|
||||
default: ret = EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct NS16550_plat ns16550_plat = {
|
||||
.clock = 115200 * 16,
|
||||
};
|
||||
|
||||
static int efi_console_init(void)
|
||||
{
|
||||
add_generic_device("efi-stdio", DEVICE_ID_SINGLE, NULL, 0 , 0, 0, NULL);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_EFI_REGISTER_COM1))
|
||||
add_ns16550_device(0, 0x3f8, 0x10, IORESOURCE_IO | IORESOURCE_MEM_8BIT,
|
||||
&ns16550_plat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
console_initcall(efi_console_init);
|
||||
|
||||
void reset_cpu(unsigned long addr)
|
||||
{
|
||||
BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
extern char image_base[];
|
||||
extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
|
||||
__barebox_initcalls_end[];
|
||||
|
||||
/*
|
||||
* We have a position independent binary generated with -fpic. This function
|
||||
* fixes the linker generated tables.
|
||||
*/
|
||||
static void fixup_tables(void)
|
||||
{
|
||||
initcall_t *initcall;
|
||||
unsigned long offset = (unsigned long)image_base;
|
||||
struct command *cmdtp;
|
||||
struct magicvar *m;
|
||||
|
||||
for (initcall = __barebox_initcalls_start;
|
||||
initcall < __barebox_initcalls_end; initcall++)
|
||||
*initcall += offset;
|
||||
|
||||
for (cmdtp = &__barebox_cmd_start;
|
||||
cmdtp != &__barebox_cmd_end;
|
||||
cmdtp++) {
|
||||
cmdtp->name += offset;
|
||||
cmdtp->cmd += offset;
|
||||
if (cmdtp->complete)
|
||||
cmdtp->complete += offset;
|
||||
if (cmdtp->desc)
|
||||
cmdtp->desc += offset;
|
||||
if (cmdtp->help)
|
||||
cmdtp->help += offset;
|
||||
if (cmdtp->opts)
|
||||
cmdtp->opts += offset;
|
||||
if (cmdtp->aliases)
|
||||
cmdtp->aliases = (void *)cmdtp->aliases + offset;
|
||||
}
|
||||
|
||||
for (m = &__barebox_magicvar_start;
|
||||
m != &__barebox_magicvar_end;
|
||||
m++) {
|
||||
m->name += offset;
|
||||
m->description += offset;
|
||||
}
|
||||
}
|
||||
|
||||
static int efi_init(void)
|
||||
{
|
||||
barebox_set_model("barebox EFI payload");
|
||||
|
||||
defaultenv_append_directory(env_efi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(efi_init);
|
||||
|
||||
/**
|
||||
* efi-main - Entry point for EFI images
|
||||
*/
|
||||
efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
|
||||
{
|
||||
void *mem;
|
||||
efi_status_t efiret;
|
||||
|
||||
#ifdef DEBUG
|
||||
sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
|
||||
#endif
|
||||
|
||||
BS = sys_table->boottime;
|
||||
|
||||
efi_parent_image = image;
|
||||
efi_sys_table = sys_table;
|
||||
RT = sys_table->runtime;
|
||||
|
||||
efiret = BS->open_protocol(efi_parent_image, &efi_loaded_image_protocol_guid,
|
||||
(void **)&efi_loaded_image,
|
||||
efi_parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (!EFI_ERROR(efiret))
|
||||
BS->handle_protocol(efi_loaded_image->device_handle,
|
||||
&efi_device_path_protocol_guid, (void **)&efi_device_path);
|
||||
|
||||
fixup_tables();
|
||||
|
||||
BS->allocate_pool(efi_loaded_image->image_data_type, SZ_16M, &mem);
|
||||
mem_malloc_init(mem, mem + SZ_16M);
|
||||
|
||||
efi_clocksource_init();
|
||||
|
||||
start_barebox();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
for i in /boot/network-drivers/*; do
|
||||
$i;
|
||||
done
|
|
@ -0,0 +1 @@
|
|||
/* dummy */
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef _SANDBOX_BITOPS_H
|
||||
#define _SANDBOX_BITOPS_H
|
||||
|
||||
/* nothing but the defaults.. */
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/__fls.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/ops.h>
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _I386_BYTEORDER_H
|
||||
#define _I386_BYTEORDER_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
#include <linux/byteorder/little_endian.h>
|
||||
|
||||
#endif /* _I386_BYTEORDER_H */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef ASM_COMMON_H
|
||||
#define ASM_COMMON_H
|
||||
|
||||
#endif /* ASM_COMMON_H */
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
*
|
||||
* This file is released under the GPLv2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ASM_DMA_H
|
||||
#define __ASM_DMA_H
|
||||
|
||||
/* empty*/
|
||||
|
||||
#endif /* __ASM_DMA_H */
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef __ASM_SANDBOX_ELF_H__
|
||||
#define __ASM_SANDBOX_ELF_H__
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
typedef struct user_fxsr_struct elf_fpxregset_t;
|
||||
|
||||
#define R_386_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_386_PC32 2
|
||||
#define R_386_GOT32 3
|
||||
#define R_386_PLT32 4
|
||||
#define R_386_COPY 5
|
||||
#define R_386_GLOB_DAT 6
|
||||
#define R_386_JMP_SLOT 7
|
||||
#define R_386_RELATIVE 8
|
||||
#define R_386_GOTOFF 9
|
||||
#define R_386_GOTPC 10
|
||||
#define R_386_NUM 11
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_386
|
||||
|
||||
#else
|
||||
|
||||
/* x86-64 relocation types */
|
||||
#define R_X86_64_NONE 0 /* No reloc */
|
||||
#define R_X86_64_64 1 /* Direct 64 bit */
|
||||
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
|
||||
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
|
||||
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
|
||||
#define R_X86_64_COPY 5 /* Copy symbol at runtime */
|
||||
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
|
||||
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
|
||||
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
|
||||
#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
|
||||
offset to GOT */
|
||||
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
|
||||
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
|
||||
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
|
||||
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
|
||||
#define R_X86_64_8 14 /* Direct 8 bit sign extended */
|
||||
#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
|
||||
|
||||
#define R_X86_64_NUM 16
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_X86_64
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_SANDBOX_ELF_H__ */
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef __ASM_SANDBOX_IO_H
|
||||
#define __ASM_SANDBOX_IO_H
|
||||
|
||||
#define build_mmio_read(name, size, type, reg, barrier) \
|
||||
static inline type name(const volatile void *addr) \
|
||||
{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \
|
||||
:"m" (*(volatile type*)addr) barrier); return ret; }
|
||||
|
||||
build_mmio_read(readb, "b", unsigned char, "=q", :"memory")
|
||||
build_mmio_read(readw, "w", unsigned short, "=r", :"memory")
|
||||
build_mmio_read(readl, "l", unsigned int, "=r", :"memory")
|
||||
|
||||
#define build_mmio_write(name, size, type, reg, barrier) \
|
||||
static inline void name(type val, volatile void *addr) \
|
||||
{ asm volatile("mov" size " %0,%1": :reg (val), \
|
||||
"m" (*(volatile type*)addr) barrier); }
|
||||
|
||||
build_mmio_write(writeb, "b", unsigned char, "q", :"memory")
|
||||
build_mmio_write(writew, "w", unsigned short, "r", :"memory")
|
||||
build_mmio_write(writel, "l", unsigned int, "r", :"memory")
|
||||
|
||||
#define BUILDIO(bwl, bw, type) \
|
||||
static inline void out##bwl(unsigned type value, int port) \
|
||||
{ \
|
||||
asm volatile("out" #bwl " %" #bw "0, %w1" \
|
||||
: : "a"(value), "Nd"(port)); \
|
||||
} \
|
||||
\
|
||||
static inline unsigned type in##bwl(int port) \
|
||||
{ \
|
||||
unsigned type value; \
|
||||
asm volatile("in" #bwl " %w1, %" #bw "0" \
|
||||
: "=a"(value) : "Nd"(port)); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static inline void outs##bwl(int port, const void *addr, unsigned long count) \
|
||||
{ \
|
||||
asm volatile("rep; outs" #bwl \
|
||||
: "+S"(addr), "+c"(count) : "d"(port)); \
|
||||
} \
|
||||
\
|
||||
static inline void ins##bwl(int port, void *addr, unsigned long count) \
|
||||
{ \
|
||||
asm volatile("rep; ins" #bwl \
|
||||
: "+D"(addr), "+c"(count) : "d"(port)); \
|
||||
}
|
||||
|
||||
BUILDIO(b, b, char)
|
||||
BUILDIO(w, w, short)
|
||||
BUILDIO(l, , int)
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
#endif /* __ASM_SANDBOX_IO_H */
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef __ARCH_I386_POSIX_TYPES_H
|
||||
#define __ARCH_I386_POSIX_TYPES_H
|
||||
|
||||
/*
|
||||
* This file is generally used by user-level software, so you need to
|
||||
* be a little careful about namespace pollution etc. Also, we cannot
|
||||
* assume GCC is being used.
|
||||
*/
|
||||
|
||||
typedef unsigned long __kernel_ino_t;
|
||||
typedef unsigned short __kernel_mode_t;
|
||||
typedef unsigned short __kernel_nlink_t;
|
||||
typedef long __kernel_off_t;
|
||||
typedef int __kernel_pid_t;
|
||||
typedef unsigned short __kernel_ipc_pid_t;
|
||||
typedef unsigned short __kernel_uid_t;
|
||||
typedef unsigned short __kernel_gid_t;
|
||||
/*
|
||||
* Most 32 bit architectures use "unsigned int" size_t,
|
||||
* and all 64 bit architectures use "unsigned long" size_t.
|
||||
*
|
||||
* TODO: It's not clean to use __x86_64__ here. It's better
|
||||
* to check on __BITS_PER_LONG here. But this is wrong set in
|
||||
* arch/sandbox/include/asm/types.h.
|
||||
*/
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long __kernel_size_t;
|
||||
typedef long __kernel_ssize_t;
|
||||
typedef long __kernel_ptrdiff_t;
|
||||
#else
|
||||
typedef unsigned int __kernel_size_t;
|
||||
typedef int __kernel_ssize_t;
|
||||
typedef int __kernel_ptrdiff_t;
|
||||
#endif
|
||||
typedef long __kernel_time_t;
|
||||
typedef long __kernel_suseconds_t;
|
||||
typedef long __kernel_clock_t;
|
||||
typedef int __kernel_daddr_t;
|
||||
typedef char * __kernel_caddr_t;
|
||||
typedef unsigned short __kernel_uid16_t;
|
||||
typedef unsigned short __kernel_gid16_t;
|
||||
typedef unsigned int __kernel_uid32_t;
|
||||
typedef unsigned int __kernel_gid32_t;
|
||||
|
||||
typedef unsigned short __kernel_old_uid_t;
|
||||
typedef unsigned short __kernel_old_gid_t;
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef long long __kernel_loff_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#if defined(__KERNEL__) || defined(__USE_ALL)
|
||||
int val[2];
|
||||
#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
|
||||
int __val[2];
|
||||
#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
|
||||
} __kernel_fsid_t;
|
||||
|
||||
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
|
||||
|
||||
#undef __FD_SET
|
||||
#define __FD_SET(fd,fdsetp) \
|
||||
__asm__ __volatile__("btsl %1,%0": \
|
||||
"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
|
||||
|
||||
#undef __FD_CLR
|
||||
#define __FD_CLR(fd,fdsetp) \
|
||||
__asm__ __volatile__("btrl %1,%0": \
|
||||
"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
|
||||
|
||||
#undef __FD_ISSET
|
||||
#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
|
||||
unsigned char __result; \
|
||||
__asm__ __volatile__("btl %1,%2 ; setb %0" \
|
||||
:"=q" (__result) :"r" ((int) (fd)), \
|
||||
"m" (*(__kernel_fd_set *) (fdsetp))); \
|
||||
__result; }))
|
||||
|
||||
#undef __FD_ZERO
|
||||
#define __FD_ZERO(fdsetp) \
|
||||
do { \
|
||||
int __d0, __d1; \
|
||||
__asm__ __volatile__("cld ; rep ; stosl" \
|
||||
:"=m" (*(__kernel_fd_set *) (fdsetp)), \
|
||||
"=&c" (__d0), "=&D" (__d1) \
|
||||
:"a" (0), "1" (__FDSET_LONGS), \
|
||||
"2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \
|
||||
} while (0)
|
||||
|
||||
#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include <asm-generic/sections.h>
|
|
@ -0,0 +1 @@
|
|||
/* dummy */
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _ASM_SWAB_H
|
||||
#define _ASM_SWAB_H
|
||||
|
||||
/* nothing. use generic functions */
|
||||
|
||||
#endif /* _ASM_SWAB_H */
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef __ASM_I386_TYPES_H
|
||||
#define __ASM_I386_TYPES_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef __x86_64__
|
||||
/*
|
||||
* This is used in dlmalloc. On X86_64 we need it to be
|
||||
* 64 bit
|
||||
*/
|
||||
#define INTERNAL_SIZE_T unsigned long
|
||||
|
||||
/*
|
||||
* This is a Kconfig variable in the Kernel, but we want to detect
|
||||
* this during compile time, so we set it here.
|
||||
*/
|
||||
#define CONFIG_PHYS_ADDR_T_64BIT
|
||||
|
||||
#endif
|
||||
|
||||
typedef unsigned short umode_t;
|
||||
|
||||
/*
|
||||
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
|
||||
* header files exported to user space
|
||||
*/
|
||||
|
||||
typedef __signed__ char __s8;
|
||||
typedef unsigned char __u8;
|
||||
|
||||
typedef __signed__ short __s16;
|
||||
typedef unsigned short __u16;
|
||||
|
||||
typedef __signed__ int __s32;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
typedef __signed__ long long __s64;
|
||||
typedef unsigned long long __u64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These aren't exported outside the kernel to avoid name space clashes
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
|
||||
typedef signed char s8;
|
||||
typedef unsigned char u8;
|
||||
|
||||
typedef signed short s16;
|
||||
typedef unsigned short u16;
|
||||
|
||||
typedef signed int s32;
|
||||
typedef unsigned int u32;
|
||||
|
||||
typedef signed long long s64;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define BITS_PER_LONG 64
|
||||
#else
|
||||
#define BITS_PER_LONG 32
|
||||
#endif
|
||||
|
||||
/* Dma addresses are 32-bits wide. */
|
||||
|
||||
typedef u32 dma_addr_t;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _ASM_SANDBOX_UNALIGNED_H
|
||||
#define _ASM_SANDBOX_UNALIGNED_H
|
||||
|
||||
/*
|
||||
* The architecture sandbox is compiled on can do unaligned accesses itself.
|
||||
*/
|
||||
|
||||
#include <linux/unaligned/access_ok.h>
|
||||
#include <linux/unaligned/generic.h>
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define get_unaligned __get_unaligned_le
|
||||
#define put_unaligned __put_unaligned_le
|
||||
#else
|
||||
#define get_unaligned __get_unaligned_be
|
||||
#define put_unaligned __put_unaligned_be
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SANDBOX_UNALIGNED_H */
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __MACH_DEBUG_LL_H__
|
||||
#define __MACH_DEBUG_LL_H__
|
||||
|
||||
#define EFI_DEBUG 0
|
||||
#define EFI_DEBUG_CLEAR_MEMORY 0
|
||||
|
||||
#include <efi.h>
|
||||
#include <mach/efi.h>
|
||||
|
||||
static inline void PUTC_LL(char c)
|
||||
{
|
||||
uint16_t str[2] = {};
|
||||
struct efi_simple_text_output_protocol *con_out = efi_sys_table->con_out;
|
||||
|
||||
str[0] = c;
|
||||
|
||||
con_out->output_string(con_out, str);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef __MACH_EFI_DEVICE_H
|
||||
#define __MACH_EFI_DEVICE_H
|
||||
|
||||
struct efi_device {
|
||||
struct device_d dev;
|
||||
efi_guid_t *guids;
|
||||
int num_guids;
|
||||
efi_handle_t handle;
|
||||
efi_handle_t parent_handle;
|
||||
void *protocol;
|
||||
struct efi_device_path *devpath;
|
||||
};
|
||||
|
||||
struct efi_driver {
|
||||
struct driver_d driver;
|
||||
int (*probe)(struct efi_device *efidev);
|
||||
void (*remove)(struct efi_device *efidev);
|
||||
efi_guid_t guid;
|
||||
};
|
||||
|
||||
extern struct bus_type efi_bus;
|
||||
|
||||
static inline struct efi_device *to_efi_device(struct device_d *dev)
|
||||
{
|
||||
return container_of(dev, struct efi_device, dev);
|
||||
}
|
||||
|
||||
static inline struct efi_driver *to_efi_driver(struct driver_d *drv)
|
||||
{
|
||||
return container_of(drv, struct efi_driver, driver);
|
||||
}
|
||||
|
||||
#define device_efi_driver(drv) \
|
||||
register_driver_macro(device, efi, drv)
|
||||
|
||||
static inline int efi_driver_register(struct efi_driver *efidrv)
|
||||
{
|
||||
efidrv->driver.bus = &efi_bus;
|
||||
return register_driver(&efidrv->driver);
|
||||
}
|
||||
|
||||
int efi_connect_all(void);
|
||||
void efi_register_devices(void);
|
||||
|
||||
#endif /* __MACH_EFI_DEVICE_H */
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __MACH_EFI_H
|
||||
#define __MACH_EFI_H
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
const char *efi_strerror(efi_status_t err);
|
||||
|
||||
extern efi_system_table_t *efi_sys_table;
|
||||
extern efi_handle_t efi_parent_image;
|
||||
extern struct efi_device_path *efi_device_path;
|
||||
extern efi_loaded_image_t *efi_loaded_image;
|
||||
|
||||
int efi_errno(efi_status_t err);
|
||||
|
||||
int efi_clocksource_init(void);
|
||||
|
||||
void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size);
|
||||
|
||||
static inline void *efi_get_global_var(char *name, int *var_size)
|
||||
{
|
||||
return efi_get_variable(name, &efi_global_variable_guid, var_size);
|
||||
}
|
||||
|
||||
#endif /* __MACH_EFI_H */
|
|
@ -0,0 +1,2 @@
|
|||
elf_x86_64_efi.lds
|
||||
elf_ia32_efi.lds
|
|
@ -0,0 +1,4 @@
|
|||
obj-$(CONFIG_X86_64) += reloc_x86_64.o crt0-efi-x86_64.o
|
||||
obj-$(CONFIG_X86_32) += reloc_ia32.o crt0-efi-ia32.o
|
||||
extra-$(CONFIG_X86_32) += elf_ia32_efi.lds
|
||||
extra-$(CONFIG_X86_64) += elf_x86_64_efi.lds
|
|
@ -0,0 +1,76 @@
|
|||
/* crt0-efi-ia32.S - x86 EFI startup code.
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.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:
|
||||
|
||||
* 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.
|
||||
* 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 ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
pushl 12(%ebp) # copy "image" argument
|
||||
pushl 8(%ebp) # copy "systab" argument
|
||||
|
||||
call 0f
|
||||
0: popl %eax
|
||||
movl %eax,%ebx
|
||||
|
||||
addl $image_base-0b,%eax # %eax = ldbase
|
||||
addl $_DYNAMIC-0b,%ebx # %ebx = _DYNAMIC
|
||||
|
||||
pushl %ebx # pass _DYNAMIC as second argument
|
||||
pushl %eax # pass ldbase as first argument
|
||||
call _relocate
|
||||
popl %ebx
|
||||
popl %ebx
|
||||
testl %eax,%eax
|
||||
jne .exit
|
||||
|
||||
call efi_main # call app with "image" and "systab" argument
|
||||
|
||||
.exit: leave
|
||||
ret
|
||||
|
||||
/* hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: */
|
||||
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc
|
||||
.long dummy /* Page RVA */
|
||||
.long 10 /* Block Size (2*4+2) */
|
||||
.word (IMAGE_REL_ABSOLUTE<<12) + 0 /* reloc for dummy */
|
|
@ -0,0 +1,75 @@
|
|||
/* crt0-efi-x86_64.S - x86_64 EFI startup code.
|
||||
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:
|
||||
|
||||
* 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.
|
||||
* 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 ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
subq $8, %rsp
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
|
||||
0:
|
||||
lea image_base(%rip), %rdi
|
||||
lea _DYNAMIC(%rip), %rsi
|
||||
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
call _relocate
|
||||
|
||||
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
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc, "a"
|
||||
label1:
|
||||
.long dummy-label1 /* Page RVA */
|
||||
.long 10 /* Block Size (2*4+2) */
|
||||
.word (IMAGE_REL_ABSOLUTE<<12) + 0 /* reloc for dummy */
|
|
@ -0,0 +1,102 @@
|
|||
#include <asm-generic/barebox.lds.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
image_base = .;
|
||||
.hash : { *(.hash) } /* this MUST come first! */
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_stext = .;
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
}
|
||||
|
||||
_etext = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.sdata : {
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.srodata)
|
||||
*(.sdata)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
_sdata = .;
|
||||
|
||||
.data : {
|
||||
*(.rodata*)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.sdata)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
* it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
. = ALIGN(64);
|
||||
|
||||
__barebox_initcalls_start = .;
|
||||
__barebox_initcalls : { INITCALLS }
|
||||
__barebox_initcalls_end = .;
|
||||
|
||||
. = ALIGN(64);
|
||||
__barebox_magicvar_start = .;
|
||||
.barebox_magicvar : { BAREBOX_MAGICVARS }
|
||||
__barebox_magicvar_end = .;
|
||||
|
||||
. = ALIGN(64);
|
||||
__barebox_cmd_start = .;
|
||||
__barebox_cmd : { BAREBOX_CMDS }
|
||||
__barebox_cmd_end = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rel : {
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.got)
|
||||
*(.rel.stab)
|
||||
*(.data.rel.ro.local)
|
||||
*(.data.rel.local)
|
||||
*(.data.rel.ro)
|
||||
*(.data.rel*)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.reloc : /* This is the PECOFF .reloc section! */
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#include <asm-generic/barebox.lds.h>
|
||||
|
||||
/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
|
||||
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
image_base = .;
|
||||
.hash : { *(.hash) } /* this MUST come first! */
|
||||
. = ALIGN(4096);
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
|
||||
.text : {
|
||||
_stext = .;
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
}
|
||||
|
||||
_etext = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
|
||||
.reloc : {
|
||||
*(.reloc)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
_sdata = .;
|
||||
|
||||
.data : {
|
||||
*(.rodata*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
* it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
*(.rel.local)
|
||||
}
|
||||
|
||||
. = ALIGN(64);
|
||||
|
||||
__barebox_initcalls_start = .;
|
||||
__barebox_initcalls : { INITCALLS }
|
||||
__barebox_initcalls_end = .;
|
||||
|
||||
. = ALIGN(64);
|
||||
__barebox_magicvar_start = .;
|
||||
.barebox_magicvar : { BAREBOX_MAGICVARS }
|
||||
__barebox_magicvar_end = .;
|
||||
|
||||
. = ALIGN(64);
|
||||
__barebox_cmd_start = .;
|
||||
__barebox_cmd : { BAREBOX_CMDS }
|
||||
__barebox_cmd_end = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
|
||||
.rela : {
|
||||
*(.rela.data*)
|
||||
*(.rela.got)
|
||||
*(.rela.stab)
|
||||
}
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.ignored.reloc : {
|
||||
*(.rela.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* reloc_ia32.c - position independent x86 ELF shared object relocator
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.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:
|
||||
|
||||
* 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.
|
||||
* 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 ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (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 <common.h>
|
||||
#include <efi.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image, efi_system_table_t *systab)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf32_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_REL:
|
||||
rel = (Elf32_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELSZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELA:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF32_R_TYPE (rel->r_info)) {
|
||||
case R_386_NONE:
|
||||
break;
|
||||
|
||||
case R_386_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf32_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* reloc_x86_64.c - position independent x86_64 ELF shared object relocator
|
||||
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:
|
||||
|
||||
* 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.
|
||||
* 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 ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (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 <common.h>
|
||||
#include <efi.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
efi_status_t _relocate (long ldbase, Elf64_Dyn *dyn, efi_handle_t image, efi_system_table_t *systab)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf64_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_RELA:
|
||||
rel = (Elf64_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELASZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELAENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF64_R_TYPE (rel->r_info)) {
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
|
||||
case R_X86_64_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf64_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -64,6 +64,14 @@ config MENUTREE
|
|||
select GLOB
|
||||
select GLOB_SORT
|
||||
|
||||
config EFI_GUID
|
||||
bool
|
||||
help
|
||||
With this option a table of EFI guids is compiled in.
|
||||
|
||||
config EFI_DEVICEPATH
|
||||
bool
|
||||
|
||||
menu "General Settings"
|
||||
|
||||
config LOCALVERSION
|
||||
|
|
|
@ -43,7 +43,9 @@ obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
|||
obj-$(CONFIG_SHELL_HUSH) += hush.o
|
||||
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
|
||||
obj-$(CONFIG_UIMAGE) += image.o uimage.o
|
||||
obj-$(CONFIG_MENUTREE) += menutree.o
|
||||
obj-$(CONFIG_MENUTREE) += menutree.o
|
||||
obj-$(CONFIG_EFI_GUID) += efi-guid.o
|
||||
obj-$(CONFIG_EFI_DEVICEPATH) += efi-devicepath.o
|
||||
|
||||
quiet_cmd_pwd_h = PWDH $@
|
||||
ifdef CONFIG_PASSWORD
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
|||
#include <common.h>
|
||||
#include <efi.h>
|
||||
|
||||
efi_guid_t efi_file_info_id = EFI_FILE_INFO_GUID;
|
||||
efi_guid_t efi_simple_file_system_protocol_guid = EFI_SIMPLE_FILE_SYSTEM_GUID;
|
||||
efi_guid_t efi_device_path_protocol_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
||||
efi_guid_t efi_loaded_image_protocol_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
efi_guid_t efi_unknown_device_guid = EFI_UNKNOWN_DEVICE_GUID;
|
||||
efi_guid_t efi_null_guid = EFI_NULL_GUID;
|
||||
efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
efi_guid_t efi_block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
|
|
@ -58,7 +58,7 @@ void mem_malloc_init(void *start, void *end)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef __SANDBOX__
|
||||
#if !defined __SANDBOX__ && !defined CONFIG_ARCH_EFI
|
||||
static int mem_malloc_resource(void)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -232,7 +232,7 @@ static int is_gpt_valid(struct block_device *blk, u64 lba,
|
|||
static inline int
|
||||
is_pte_valid(const gpt_entry *pte, const u64 lastlba)
|
||||
{
|
||||
if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
|
||||
if ((!efi_guidcmp(pte->partition_type_guid, EFI_NULL_GUID)) ||
|
||||
le64_to_cpu(pte->starting_lba) > lastlba ||
|
||||
le64_to_cpu(pte->ending_lba) > lastlba)
|
||||
return 0;
|
||||
|
|
|
@ -4,7 +4,7 @@ config OFTREE
|
|||
|
||||
config OFTREE_MEM_GENERIC
|
||||
depends on OFTREE
|
||||
depends on PPC || ARM
|
||||
depends on PPC || ARM || ARCH_EFI
|
||||
def_bool y
|
||||
|
||||
config DTC
|
||||
|
|
469
include/efi.h
469
include/efi.h
|
@ -14,6 +14,14 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_EFI
|
||||
#define EFIAPI __attribute__((ms_abi))
|
||||
#else
|
||||
#define EFIAPI
|
||||
#endif
|
||||
|
||||
struct efi_device_path;
|
||||
|
||||
#define EFI_SUCCESS 0
|
||||
#define EFI_LOAD_ERROR ( 1 | (1UL << (BITS_PER_LONG-1)))
|
||||
#define EFI_INVALID_PARAMETER ( 2 | (1UL << (BITS_PER_LONG-1)))
|
||||
|
@ -52,13 +60,15 @@
|
|||
typedef unsigned long efi_status_t;
|
||||
typedef u8 efi_bool_t;
|
||||
typedef u16 efi_char16_t; /* UNICODE character */
|
||||
typedef u64 efi_physical_addr_t;
|
||||
typedef void *efi_handle_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u8 b[16];
|
||||
} efi_guid_t;
|
||||
|
||||
#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
|
||||
#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
|
||||
((efi_guid_t) \
|
||||
{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
|
||||
(b) & 0xff, ((b) >> 8) & 0xff, \
|
||||
|
@ -109,22 +119,7 @@ typedef struct {
|
|||
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
|
||||
|
||||
#define EFI_PAGE_SHIFT 12
|
||||
|
||||
typedef struct {
|
||||
u32 type;
|
||||
u32 pad;
|
||||
u64 phys_addr;
|
||||
u64 virt_addr;
|
||||
u64 num_pages;
|
||||
u64 attribute;
|
||||
} efi_memory_desc_t;
|
||||
|
||||
typedef struct {
|
||||
efi_guid_t guid;
|
||||
u32 headersize;
|
||||
u32 flags;
|
||||
u32 imagesize;
|
||||
} efi_capsule_header_t;
|
||||
#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
|
||||
|
||||
/*
|
||||
* Allocation types for calls to boottime->allocate_pages.
|
||||
|
@ -163,6 +158,19 @@ typedef struct {
|
|||
u8 sets_to_zero;
|
||||
} efi_time_cap_t;
|
||||
|
||||
enum efi_locate_search_type {
|
||||
all_handles,
|
||||
by_register_notify,
|
||||
by_protocol
|
||||
};
|
||||
|
||||
struct efi_open_protocol_information_entry {
|
||||
efi_handle_t agent_handle;
|
||||
efi_handle_t controller_handle;
|
||||
u32 attributes;
|
||||
u32 open_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* EFI Boot Services table
|
||||
*/
|
||||
|
@ -170,41 +178,69 @@ typedef struct {
|
|||
efi_table_hdr_t hdr;
|
||||
void *raise_tpl;
|
||||
void *restore_tpl;
|
||||
void *allocate_pages;
|
||||
void *free_pages;
|
||||
void *get_memory_map;
|
||||
void *allocate_pool;
|
||||
void *free_pool;
|
||||
efi_status_t (EFIAPI *allocate_pages)(int, int, unsigned long,
|
||||
efi_physical_addr_t *);
|
||||
efi_status_t (EFIAPI *free_pages)(efi_physical_addr_t, unsigned long);
|
||||
efi_status_t (EFIAPI *get_memory_map)(unsigned long *, void *, unsigned long *,
|
||||
unsigned long *, u32 *);
|
||||
efi_status_t (EFIAPI *allocate_pool)(int, unsigned long, void **);
|
||||
efi_status_t (EFIAPI *free_pool)(void *);
|
||||
void *create_event;
|
||||
void *set_timer;
|
||||
void *wait_for_event;
|
||||
efi_status_t(EFIAPI *wait_for_event)(unsigned long number_of_events, void *event,
|
||||
unsigned long *index);
|
||||
void *signal_event;
|
||||
void *close_event;
|
||||
void *check_event;
|
||||
void *install_protocol_interface;
|
||||
void *reinstall_protocol_interface;
|
||||
void *uninstall_protocol_interface;
|
||||
void *handle_protocol;
|
||||
efi_status_t (EFIAPI *handle_protocol)(efi_handle_t, efi_guid_t *, void **);
|
||||
void *__reserved;
|
||||
void *register_protocol_notify;
|
||||
void *locate_handle;
|
||||
void *locate_device_path;
|
||||
efi_status_t (EFIAPI *locate_handle) (enum efi_locate_search_type search_type,
|
||||
efi_guid_t *protocol, void *search_key,
|
||||
unsigned long *buffer_size, efi_handle_t *buffer);
|
||||
efi_status_t (EFIAPI *locate_device_path)(efi_guid_t *protocol,
|
||||
struct efi_device_path **device_path, efi_handle_t *device);
|
||||
void *install_configuration_table;
|
||||
void *load_image;
|
||||
void *start_image;
|
||||
void *exit;
|
||||
efi_status_t (EFIAPI *load_image)(bool boot_policiy, efi_handle_t parent_image,
|
||||
struct efi_device_path *file_path, void *source_buffer,
|
||||
unsigned long source_size, efi_handle_t *image);
|
||||
efi_status_t (EFIAPI *start_image)(efi_handle_t handle,
|
||||
unsigned long *exitdata_size, s16 **exitdata);
|
||||
efi_status_t(EFIAPI *exit)(efi_handle_t handle, efi_status_t exit_status,
|
||||
unsigned long exitdata_size, s16 *exitdata);
|
||||
void *unload_image;
|
||||
void *exit_boot_services;
|
||||
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
|
||||
void *get_next_monotonic_count;
|
||||
void *stall;
|
||||
efi_status_t (EFIAPI *stall)(unsigned long usecs);
|
||||
void *set_watchdog_timer;
|
||||
void *connect_controller;
|
||||
efi_status_t(EFIAPI *connect_controller)(efi_handle_t controller_handle,
|
||||
efi_handle_t *driver_image_handle,
|
||||
struct efi_device_path *remaining_device_path,
|
||||
bool Recursive);
|
||||
void *disconnect_controller;
|
||||
void *open_protocol;
|
||||
#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
|
||||
efi_status_t (EFIAPI *open_protocol)(efi_handle_t handle, efi_guid_t *protocol,
|
||||
void ** interface, efi_handle_t agent_handle,
|
||||
efi_handle_t controller_handle, u32 attributes);
|
||||
void *close_protocol;
|
||||
void *open_protocol_information;
|
||||
void *protocols_per_handle;
|
||||
void *locate_handle_buffer;
|
||||
efi_status_t(EFIAPI *open_protocol_information)(efi_handle_t handle, efi_guid_t *Protocol,
|
||||
struct efi_open_protocol_information_entry **entry_buffer,
|
||||
unsigned long *entry_count);
|
||||
efi_status_t (EFIAPI *protocols_per_handle)(efi_handle_t handle,
|
||||
efi_guid_t ***protocol_buffer,
|
||||
unsigned long *protocols_buffer_count);
|
||||
efi_status_t (EFIAPI *locate_handle_buffer) (
|
||||
enum efi_locate_search_type search_type,
|
||||
efi_guid_t *protocol, void *search_key,
|
||||
unsigned long *no_handles, efi_handle_t **buffer);
|
||||
void *locate_protocol;
|
||||
void *install_multiple_protocol_interfaces;
|
||||
void *uninstall_multiple_protocol_interfaces;
|
||||
|
@ -214,6 +250,8 @@ typedef struct {
|
|||
void *create_event_ex;
|
||||
} efi_boot_services_t;
|
||||
|
||||
extern efi_boot_services_t *BS;
|
||||
|
||||
/*
|
||||
* Types and defines for EFI ResetSystem
|
||||
*/
|
||||
|
@ -229,90 +267,63 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
efi_table_hdr_t hdr;
|
||||
unsigned long get_time;
|
||||
unsigned long set_time;
|
||||
unsigned long get_wakeup_time;
|
||||
unsigned long set_wakeup_time;
|
||||
unsigned long set_virtual_address_map;
|
||||
unsigned long convert_pointer;
|
||||
unsigned long get_variable;
|
||||
unsigned long get_next_variable;
|
||||
unsigned long set_variable;
|
||||
unsigned long get_next_high_mono_count;
|
||||
unsigned long reset_system;
|
||||
unsigned long update_capsule;
|
||||
unsigned long query_capsule_caps;
|
||||
unsigned long query_variable_info;
|
||||
void *get_time;
|
||||
void *set_time;
|
||||
void *get_wakeup_time;
|
||||
void *set_wakeup_time;
|
||||
void *set_virtual_address_map;
|
||||
void *convert_pointer;
|
||||
efi_status_t (EFIAPI *get_variable)(s16 *variable_name, efi_guid_t *vendor,
|
||||
u32 *Attributes, unsigned long *data_size, void *data);
|
||||
efi_status_t (EFIAPI *get_next_variable)(unsigned long *variable_name_size,
|
||||
s16 *variable_name, efi_guid_t *vendor);
|
||||
void *set_variable;
|
||||
void *get_next_high_mono_count;
|
||||
void *reset_system;
|
||||
void *update_capsule;
|
||||
void *query_capsule_caps;
|
||||
void *query_variable_info;
|
||||
} efi_runtime_services_t;
|
||||
|
||||
typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
|
||||
typedef efi_status_t efi_set_time_t (efi_time_t *tm);
|
||||
typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
|
||||
efi_time_t *tm);
|
||||
typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm);
|
||||
typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
|
||||
unsigned long *data_size, void *data);
|
||||
typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name,
|
||||
efi_guid_t *vendor);
|
||||
typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor,
|
||||
u32 attr, unsigned long data_size,
|
||||
void *data);
|
||||
typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
|
||||
typedef void efi_reset_system_t (int reset_type, efi_status_t status,
|
||||
unsigned long data_size, efi_char16_t *data);
|
||||
typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_size,
|
||||
unsigned long descriptor_size,
|
||||
u32 descriptor_version,
|
||||
efi_memory_desc_t *virtual_map);
|
||||
typedef efi_status_t efi_query_variable_info_t(u32 attr,
|
||||
u64 *storage_space,
|
||||
u64 *remaining_space,
|
||||
u64 *max_variable_size);
|
||||
typedef efi_status_t efi_update_capsule_t(efi_capsule_header_t **capsules,
|
||||
unsigned long count,
|
||||
unsigned long sg_list);
|
||||
typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
|
||||
unsigned long count,
|
||||
u64 *max_size,
|
||||
int *reset_type);
|
||||
extern efi_runtime_services_t *RT;
|
||||
|
||||
/*
|
||||
* EFI Configuration Table and GUID definitions
|
||||
*/
|
||||
#define NULL_GUID \
|
||||
#define EFI_NULL_GUID \
|
||||
EFI_GUID( 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
|
||||
|
||||
#define MPS_TABLE_GUID \
|
||||
#define EFI_MPS_TABLE_GUID \
|
||||
EFI_GUID( 0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
|
||||
|
||||
#define ACPI_TABLE_GUID \
|
||||
#define EFI_ACPI_TABLE_GUID \
|
||||
EFI_GUID( 0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
|
||||
|
||||
#define ACPI_20_TABLE_GUID \
|
||||
#define EFI_ACPI_20_TABLE_GUID \
|
||||
EFI_GUID( 0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
|
||||
|
||||
#define SMBIOS_TABLE_GUID \
|
||||
#define EFI_SMBIOS_TABLE_GUID \
|
||||
EFI_GUID( 0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
|
||||
|
||||
#define SAL_SYSTEM_TABLE_GUID \
|
||||
#define EFI_SAL_SYSTEM_TABLE_GUID \
|
||||
EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
|
||||
|
||||
#define HCDP_TABLE_GUID \
|
||||
#define EFI_HCDP_TABLE_GUID \
|
||||
EFI_GUID( 0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
|
||||
|
||||
#define UGA_IO_PROTOCOL_GUID \
|
||||
#define EFI_UGA_IO_PROTOCOL_GUID \
|
||||
EFI_GUID( 0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 )
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE_GUID \
|
||||
EFI_GUID( 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c )
|
||||
|
||||
#define UV_SYSTEM_TABLE_GUID \
|
||||
#define EFI_UV_SYSTEM_TABLE_GUID \
|
||||
EFI_GUID( 0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
|
||||
|
||||
#define LINUX_EFI_CRASH_GUID \
|
||||
#define EFI_LINUX_EFI_CRASH_GUID \
|
||||
EFI_GUID( 0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 )
|
||||
|
||||
#define LOADED_IMAGE_PROTOCOL_GUID \
|
||||
#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
|
||||
EFI_GUID( 0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
|
||||
|
||||
#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
|
||||
|
@ -324,26 +335,38 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
|
|||
#define EFI_PCI_IO_PROTOCOL_GUID \
|
||||
EFI_GUID( 0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a )
|
||||
|
||||
#define EFI_FILE_INFO_ID \
|
||||
#define EFI_FILE_INFO_GUID \
|
||||
EFI_GUID( 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
|
||||
|
||||
#define EFI_FILE_SYSTEM_GUID \
|
||||
#define EFI_SIMPLE_FILE_SYSTEM_GUID \
|
||||
EFI_GUID( 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
|
||||
|
||||
typedef struct {
|
||||
efi_guid_t guid;
|
||||
u64 table;
|
||||
} efi_config_table_64_t;
|
||||
#define EFI_DEVICE_TREE_GUID \
|
||||
EFI_GUID( 0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 )
|
||||
|
||||
typedef struct {
|
||||
efi_guid_t guid;
|
||||
u32 table;
|
||||
} efi_config_table_32_t;
|
||||
#define EFI_DEVICE_PATH_PROTOCOL_GUID \
|
||||
EFI_GUID( 0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
|
||||
|
||||
typedef struct {
|
||||
efi_guid_t guid;
|
||||
unsigned long table;
|
||||
} efi_config_table_t;
|
||||
#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \
|
||||
EFI_GUID( 0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D )
|
||||
|
||||
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
|
||||
EFI_GUID(0x0964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
|
||||
#define EFI_UNKNOWN_DEVICE_GUID \
|
||||
EFI_GUID(0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b)
|
||||
|
||||
#define EFI_BLOCK_IO_PROTOCOL_GUID \
|
||||
EFI_GUID(0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
|
||||
extern efi_guid_t efi_file_info_id;
|
||||
extern efi_guid_t efi_simple_file_system_protocol_guid;
|
||||
extern efi_guid_t efi_device_path_protocol_guid;
|
||||
extern efi_guid_t efi_loaded_image_protocol_guid;
|
||||
extern efi_guid_t efi_unknown_device_guid;
|
||||
extern efi_guid_t efi_null_guid;
|
||||
extern efi_guid_t efi_global_variable_guid;
|
||||
extern efi_guid_t efi_block_io_protocol_guid;
|
||||
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
|
||||
|
||||
|
@ -354,65 +377,22 @@ typedef struct {
|
|||
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
|
||||
#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
|
||||
|
||||
typedef struct {
|
||||
efi_table_hdr_t hdr;
|
||||
u64 fw_vendor; /* physical addr of CHAR16 vendor string */
|
||||
u32 fw_revision;
|
||||
u32 __pad1;
|
||||
u64 con_in_handle;
|
||||
u64 con_in;
|
||||
u64 con_out_handle;
|
||||
u64 con_out;
|
||||
u64 stderr_handle;
|
||||
u64 _stderr;
|
||||
u64 runtime;
|
||||
u64 boottime;
|
||||
u32 nr_tables;
|
||||
u32 __pad2;
|
||||
u64 tables;
|
||||
} efi_system_table_64_t;
|
||||
|
||||
typedef struct {
|
||||
efi_table_hdr_t hdr;
|
||||
u32 fw_vendor; /* physical addr of CHAR16 vendor string */
|
||||
u32 fw_revision;
|
||||
u32 con_in_handle;
|
||||
u32 con_in;
|
||||
u32 con_out_handle;
|
||||
u32 con_out;
|
||||
u32 stderr_handle;
|
||||
u32 _stderr;
|
||||
u32 runtime;
|
||||
u32 boottime;
|
||||
u32 nr_tables;
|
||||
u32 tables;
|
||||
} efi_system_table_32_t;
|
||||
|
||||
typedef struct {
|
||||
efi_table_hdr_t hdr;
|
||||
unsigned long fw_vendor; /* physical addr of CHAR16 vendor string */
|
||||
u32 fw_revision;
|
||||
unsigned long con_in_handle;
|
||||
unsigned long con_in;
|
||||
struct efi_simple_input_interface *con_in;
|
||||
unsigned long con_out_handle;
|
||||
unsigned long con_out;
|
||||
struct efi_simple_text_output_protocol *con_out;
|
||||
unsigned long stderr_handle;
|
||||
unsigned long _stderr;
|
||||
unsigned long std_err;
|
||||
efi_runtime_services_t *runtime;
|
||||
efi_boot_services_t *boottime;
|
||||
unsigned long nr_tables;
|
||||
unsigned long tables;
|
||||
} efi_system_table_t;
|
||||
|
||||
struct efi_memory_map {
|
||||
void *phys_map;
|
||||
void *map;
|
||||
void *map_end;
|
||||
int nr_map;
|
||||
unsigned long desc_version;
|
||||
unsigned long desc_size;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u32 revision;
|
||||
void *parent_handle;
|
||||
|
@ -429,85 +409,12 @@ typedef struct {
|
|||
unsigned long unload;
|
||||
} efi_loaded_image_t;
|
||||
|
||||
typedef struct {
|
||||
u64 revision;
|
||||
void *open_volume;
|
||||
} efi_file_io_interface_t;
|
||||
|
||||
typedef struct {
|
||||
u64 size;
|
||||
u64 file_size;
|
||||
u64 phys_size;
|
||||
efi_time_t create_time;
|
||||
efi_time_t last_access_time;
|
||||
efi_time_t modification_time;
|
||||
__aligned_u64 attribute;
|
||||
efi_char16_t filename[1];
|
||||
} efi_file_info_t;
|
||||
|
||||
typedef struct {
|
||||
u64 revision;
|
||||
void *open;
|
||||
void *close;
|
||||
void *delete;
|
||||
void *read;
|
||||
void *write;
|
||||
void *get_position;
|
||||
void *set_position;
|
||||
void *get_info;
|
||||
void *set_info;
|
||||
void *flush;
|
||||
} efi_file_handle_t;
|
||||
|
||||
#define EFI_FILE_MODE_READ 0x0000000000000001
|
||||
#define EFI_FILE_MODE_WRITE 0x0000000000000002
|
||||
#define EFI_FILE_MODE_CREATE 0x8000000000000000
|
||||
|
||||
#define EFI_INVALID_TABLE_ADDR (~0UL)
|
||||
|
||||
/*
|
||||
* All runtime access to EFI goes through this structure:
|
||||
*/
|
||||
extern struct efi {
|
||||
efi_system_table_t *systab; /* EFI system table */
|
||||
unsigned int runtime_version; /* Runtime services version */
|
||||
unsigned long mps; /* MPS table */
|
||||
unsigned long acpi; /* ACPI table (IA64 ext 0.71) */
|
||||
unsigned long acpi20; /* ACPI table (ACPI 2.0) */
|
||||
unsigned long smbios; /* SM BIOS table */
|
||||
unsigned long sal_systab; /* SAL system table */
|
||||
unsigned long boot_info; /* boot info table */
|
||||
unsigned long hcdp; /* HCDP table */
|
||||
unsigned long uga; /* UGA table */
|
||||
unsigned long uv_systab; /* UV system table */
|
||||
efi_get_time_t *get_time;
|
||||
efi_set_time_t *set_time;
|
||||
efi_get_wakeup_time_t *get_wakeup_time;
|
||||
efi_set_wakeup_time_t *set_wakeup_time;
|
||||
efi_get_variable_t *get_variable;
|
||||
efi_get_next_variable_t *get_next_variable;
|
||||
efi_set_variable_t *set_variable;
|
||||
efi_query_variable_info_t *query_variable_info;
|
||||
efi_update_capsule_t *update_capsule;
|
||||
efi_query_capsule_caps_t *query_capsule_caps;
|
||||
efi_get_next_high_mono_count_t *get_next_high_mono_count;
|
||||
efi_reset_system_t *reset_system;
|
||||
efi_set_virtual_address_map_t *set_virtual_address_map;
|
||||
} efi;
|
||||
|
||||
static inline int
|
||||
efi_guidcmp (efi_guid_t left, efi_guid_t right)
|
||||
{
|
||||
return memcmp(&left, &right, sizeof (efi_guid_t));
|
||||
}
|
||||
|
||||
static inline char *
|
||||
efi_guid_unparse(efi_guid_t *guid, char *out)
|
||||
{
|
||||
sprintf(out, "%pUl", guid->b);
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Variable Attributes
|
||||
*/
|
||||
|
@ -527,48 +434,80 @@ efi_guid_unparse(efi_guid_t *guid, char *out)
|
|||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
|
||||
EFI_VARIABLE_APPEND_WRITE)
|
||||
/*
|
||||
* The type of search to perform when calling boottime->locate_handle
|
||||
* Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
|
||||
* not including trailing NUL
|
||||
*/
|
||||
#define EFI_LOCATE_ALL_HANDLES 0
|
||||
#define EFI_LOCATE_BY_REGISTER_NOTIFY 1
|
||||
#define EFI_LOCATE_BY_PROTOCOL 2
|
||||
#define EFI_VARIABLE_GUID_LEN 36
|
||||
|
||||
/*
|
||||
* EFI Device Path information
|
||||
*/
|
||||
#define EFI_DEV_HW 0x01
|
||||
#define EFI_DEV_PCI 1
|
||||
#define EFI_DEV_PCCARD 2
|
||||
#define EFI_DEV_MEM_MAPPED 3
|
||||
#define EFI_DEV_VENDOR 4
|
||||
#define EFI_DEV_CONTROLLER 5
|
||||
#define EFI_DEV_ACPI 0x02
|
||||
#define EFI_DEV_BASIC_ACPI 1
|
||||
#define EFI_DEV_EXPANDED_ACPI 2
|
||||
#define EFI_DEV_MSG 0x03
|
||||
#define EFI_DEV_MSG_ATAPI 1
|
||||
#define EFI_DEV_MSG_SCSI 2
|
||||
#define EFI_DEV_MSG_FC 3
|
||||
#define EFI_DEV_MSG_1394 4
|
||||
#define EFI_DEV_MSG_USB 5
|
||||
#define EFI_DEV_MSG_USB_CLASS 15
|
||||
#define EFI_DEV_MSG_I20 6
|
||||
#define EFI_DEV_MSG_MAC 11
|
||||
#define EFI_DEV_MSG_IPV4 12
|
||||
#define EFI_DEV_MSG_IPV6 13
|
||||
#define EFI_DEV_MSG_INFINIBAND 9
|
||||
#define EFI_DEV_MSG_UART 14
|
||||
#define EFI_DEV_MSG_VENDOR 10
|
||||
#define EFI_DEV_MEDIA 0x04
|
||||
#define EFI_DEV_MEDIA_HARD_DRIVE 1
|
||||
#define EFI_DEV_MEDIA_CDROM 2
|
||||
#define EFI_DEV_MEDIA_VENDOR 3
|
||||
#define EFI_DEV_MEDIA_FILE 4
|
||||
#define EFI_DEV_MEDIA_PROTOCOL 5
|
||||
#define EFI_DEV_BIOS_BOOT 0x05
|
||||
#define EFI_DEV_END_PATH 0x7F
|
||||
#define EFI_DEV_END_PATH2 0xFF
|
||||
#define EFI_DEV_END_INSTANCE 0x01
|
||||
#define EFI_DEV_END_ENTIRE 0xFF
|
||||
struct efi_device_path {
|
||||
u8 type;
|
||||
u8 sub_type;
|
||||
u16 length;
|
||||
} __attribute ((packed));
|
||||
|
||||
struct simple_text_output_mode {
|
||||
s32 max_mode;
|
||||
s32 mode;
|
||||
s32 attribute;
|
||||
s32 cursor_column;
|
||||
s32 cursor_row;
|
||||
bool cursor_visible;
|
||||
};
|
||||
|
||||
struct efi_simple_text_output_protocol {
|
||||
void *reset;
|
||||
efi_status_t (EFIAPI *output_string)(void *, void *);
|
||||
void *test_string;
|
||||
|
||||
efi_status_t(EFIAPI *query_mode)(struct efi_simple_text_output_protocol *this,
|
||||
unsigned long mode_number, unsigned long *columns, unsigned long *rows);
|
||||
efi_status_t(EFIAPI *set_mode)(struct efi_simple_text_output_protocol *this,
|
||||
unsigned long mode_number);
|
||||
efi_status_t(EFIAPI *set_attribute)(struct efi_simple_text_output_protocol *this,
|
||||
unsigned long attribute);
|
||||
efi_status_t(EFIAPI *clear_screen) (struct efi_simple_text_output_protocol *this);
|
||||
efi_status_t(EFIAPI *set_cursor_position) (struct efi_simple_text_output_protocol *this,
|
||||
unsigned long column, unsigned long row);
|
||||
efi_status_t(EFIAPI *enable_cursor)(void *, bool enable);
|
||||
struct simple_text_output_mode *mode;
|
||||
};
|
||||
|
||||
struct efi_input_key {
|
||||
u16 scan_code;
|
||||
s16 unicode_char;
|
||||
};
|
||||
|
||||
struct efi_simple_input_interface {
|
||||
efi_status_t(EFIAPI *reset)(struct efi_simple_input_interface *this,
|
||||
bool ExtendedVerification);
|
||||
efi_status_t(EFIAPI *read_key_stroke)(struct efi_simple_input_interface *this,
|
||||
struct efi_input_key *key);
|
||||
void *wait_for_key;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t Addr[32];
|
||||
} efi_mac_address;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Addr[4];
|
||||
} efi_ipv4_address;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Addr[16];
|
||||
} efi_ipv6_address;
|
||||
|
||||
typedef union {
|
||||
uint32_t Addr[4];
|
||||
efi_ipv4_address v4;
|
||||
efi_ipv6_address v6;
|
||||
} efi_ip_address;
|
||||
|
||||
static inline int efi_compare_guid(efi_guid_t *a, efi_guid_t *b)
|
||||
{
|
||||
return memcmp(a, b, sizeof(efi_guid_t));
|
||||
}
|
||||
|
||||
char *device_path_to_str(struct efi_device_path *dev_path);
|
||||
|
||||
#endif /* _LINUX_EFI_H */
|
||||
|
|
Loading…
Reference in New Issue