* [PATCH v2] Initial EFI support
@ 2014-07-11 7:36 Sascha Hauer
2014-07-11 7:36 ` [PATCH 1/7] Documentation: Add EFI documentation Sascha Hauer
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
Second round of barebox on EFI patches. I merged the preparatory patches
already to -next, so here are only the EFI patches again.
Changes since v1:
- Add documentation how to run this on qemu
- The root directory on EFI filesystems now works on Tianocore (tested with qemu)
- Made 64-bit mandatory since 32-bit doesn't compile and cannot be tested
- Updated defconfig. For some reason the original defconfig had all relevant drivers
disabled
- Add patch from Jean-Christophe to print GUIDs as strings
Sascha
The following changes since commit b6a37cf0c3eb5dddf69a5067c1b1d629d48a2fa0:
efi: Add more error codes (2014-07-11 09:27:18 +0200)
are available in the git repository at:
git://git.pengutronix.de/git/barebox.git efi
for you to fetch changes up to 873c978375a9a0b689c5bc73ac2281d748e0b809:
EFI: introduce efi_strguid to convert GUID to human readable names (2014-07-11 09:29:13 +0200)
----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (1):
EFI: introduce efi_strguid to convert GUID to human readable names
Sascha Hauer (6):
Documentation: Add EFI documentation
Add initial EFI architecture support
net: Add EFI Simple Network Protocol Driver
serial: Add EFI stdio driver
fs: implement EFI filesystem driver
fs: implement EFI variable filesystem driver
.gitignore | 1 +
Documentation/boards/efi.rst | 298 ++++++
Documentation/glossary.rst | 3 +
Makefile | 3 +-
arch/efi/Kconfig | 51 ++
arch/efi/Makefile | 41 +
arch/efi/configs/efi_defconfig | 78 ++
arch/efi/efi/Makefile | 2 +
arch/efi/efi/clocksource.c | 60 ++
arch/efi/efi/efi-block-io.c | 174 ++++
arch/efi/efi/efi-device.c | 349 +++++++
arch/efi/efi/efi-image.c | 105 +++
arch/efi/efi/efi.c | 343 +++++++
arch/efi/efi/env-efi/network/eth0-discover | 5 +
arch/efi/include/asm/barebox.h | 1 +
arch/efi/include/asm/bitops.h | 15 +
arch/efi/include/asm/byteorder.h | 8 +
arch/efi/include/asm/common.h | 4 +
arch/efi/include/asm/dma.h | 13 +
arch/efi/include/asm/elf.h | 60 ++
arch/efi/include/asm/io.h | 55 ++
arch/efi/include/asm/posix_types.h | 93 ++
arch/efi/include/asm/sections.h | 1 +
arch/efi/include/asm/string.h | 1 +
arch/efi/include/asm/swab.h | 6 +
arch/efi/include/asm/types.h | 73 ++
arch/efi/include/asm/unaligned.h | 19 +
arch/efi/include/mach/debug_ll.h | 20 +
arch/efi/include/mach/efi-device.h | 45 +
arch/efi/include/mach/efi.h | 24 +
arch/efi/lib/.gitignore | 2 +
arch/efi/lib/Makefile | 4 +
arch/efi/lib/crt0-efi-ia32.S | 76 ++
arch/efi/lib/crt0-efi-x86_64.S | 75 ++
arch/efi/lib/elf_ia32_efi.lds.S | 102 +++
arch/efi/lib/elf_x86_64_efi.lds.S | 93 ++
arch/efi/lib/reloc_ia32.c | 97 ++
arch/efi/lib/reloc_x86_64.c | 96 ++
commands/edit.c | 11 +-
common/Kconfig | 8 +
common/Makefile | 4 +-
common/efi-devicepath.c | 1370 ++++++++++++++++++++++++++++
common/efi-guid.c | 84 ++
common/memory.c | 2 +-
common/partitions/efi.c | 2 +-
drivers/net/Kconfig | 4 +
drivers/net/Makefile | 1 +
drivers/net/efi-snp.c | 296 ++++++
drivers/of/Kconfig | 2 +-
drivers/serial/Kconfig | 4 +
drivers/serial/Makefile | 1 +
drivers/serial/efi-stdio.c | 367 ++++++++
fs/Kconfig | 15 +
fs/Makefile | 2 +
fs/efi.c | 563 ++++++++++++
fs/efivarfs.c | 340 +++++++
include/efi.h | 572 ++++++------
57 files changed, 5873 insertions(+), 271 deletions(-)
create mode 100644 Documentation/boards/efi.rst
create mode 100644 arch/efi/Kconfig
create mode 100644 arch/efi/Makefile
create mode 100644 arch/efi/configs/efi_defconfig
create mode 100644 arch/efi/efi/Makefile
create mode 100644 arch/efi/efi/clocksource.c
create mode 100644 arch/efi/efi/efi-block-io.c
create mode 100644 arch/efi/efi/efi-device.c
create mode 100644 arch/efi/efi/efi-image.c
create mode 100644 arch/efi/efi/efi.c
create mode 100644 arch/efi/efi/env-efi/network/eth0-discover
create mode 100644 arch/efi/include/asm/barebox.h
create mode 100644 arch/efi/include/asm/bitops.h
create mode 100644 arch/efi/include/asm/byteorder.h
create mode 100644 arch/efi/include/asm/common.h
create mode 100644 arch/efi/include/asm/dma.h
create mode 100644 arch/efi/include/asm/elf.h
create mode 100644 arch/efi/include/asm/io.h
create mode 100644 arch/efi/include/asm/posix_types.h
create mode 100644 arch/efi/include/asm/sections.h
create mode 100644 arch/efi/include/asm/string.h
create mode 100644 arch/efi/include/asm/swab.h
create mode 100644 arch/efi/include/asm/types.h
create mode 100644 arch/efi/include/asm/unaligned.h
create mode 100644 arch/efi/include/mach/debug_ll.h
create mode 100644 arch/efi/include/mach/efi-device.h
create mode 100644 arch/efi/include/mach/efi.h
create mode 100644 arch/efi/lib/.gitignore
create mode 100644 arch/efi/lib/Makefile
create mode 100644 arch/efi/lib/crt0-efi-ia32.S
create mode 100644 arch/efi/lib/crt0-efi-x86_64.S
create mode 100644 arch/efi/lib/elf_ia32_efi.lds.S
create mode 100644 arch/efi/lib/elf_x86_64_efi.lds.S
create mode 100644 arch/efi/lib/reloc_ia32.c
create mode 100644 arch/efi/lib/reloc_x86_64.c
create mode 100644 common/efi-devicepath.c
create mode 100644 common/efi-guid.c
create mode 100644 drivers/net/efi-snp.c
create mode 100644 drivers/serial/efi-stdio.c
create mode 100644 fs/efi.c
create mode 100644 fs/efivarfs.c
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/7] Documentation: Add EFI documentation
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
2014-07-11 7:36 ` [PATCH 3/7] net: Add EFI Simple Network Protocol Driver Sascha Hauer
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
This adds documentation for the upcoming barebox on EFI support.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/boards/efi.rst | 298 +++++++++++++++++++++++++++++++++++++++++++
Documentation/glossary.rst | 3 +
2 files changed, 301 insertions(+)
create mode 100644 Documentation/boards/efi.rst
diff --git a/Documentation/boards/efi.rst b/Documentation/boards/efi.rst
new file mode 100644
index 0000000..2147cb6
--- /dev/null
+++ b/Documentation/boards/efi.rst
@@ -0,0 +1,298 @@
+barebox on (U)EFI
+=================
+
+barebox can be built as an EFI application for X86 PCs. This makes
+barebox a bootloader running on PC type hardware. In EFI jargon barebox
+would be a EFI shell. Due to the barebox :ref:`bootloader_spec` support
+it can act as a replacement for gummiboot.
+
+For accessing hardware the EFI drivers and abstractions are used. barebox
+has several drivers which merely map to the underlying EFI layers. A plain
+barebox binary provides access to the screen and keyboard. The EFI System
+partition (:term:`ESP`) is available under ``/boot``, additional partitions may
+be available as ``/efi*``. Networking may be available if the BIOS provides
+the necessary drivers, but most likely you'll have to download/compile
+network drivers yourself, see below.
+
+Depending on the ``CONFIG_64BIT`` option either a ia32 binary or a x86_64
+binary is built. Due to the lack of 32bit UEFI testing hardware only the
+x86_64 binary currently is tested.
+
+Building barebox for EFI
+------------------------
+
+Use the following to build barebox for EFI:
+
+.. code-block:: sh
+
+ export ARCH=efi
+ make efi_defconfig
+ make
+
+The resulting EFI image is ``barebox.efi`` (or the barebox-flash-image link).
+
+Running barebox on EFI systems
+------------------------------
+
+The simplest way to run barebox on a USB memory stick. (U)EFI only supports
+FAT filesystems, so make sure you either have a FAT16 or FAT32 filesystem on
+the memory stick. Put ``barebox.efi`` into the ``EFI/BOOT/`` directory and
+name it ``BOOTx64.EFI`` on 64bit architectures and ``BOOTIA32.EFI`` on 32bit
+architectures. Switching to USB boot in the BIOS should then be enough to
+start barebox via USB. Some BIOSes allow to specify a path to a binary to
+be executed, others have a "start UEFI shell" entry which executes
+EFI/Shellx64.efi on the :term:`ESP`. This can be a barebox binary aswell.
+
+Running EFI barebox on qemu
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+barebox can be started in qemu with OVMF http://www.linux-kvm.org/page/OVMF.
+
+OVMF is part of several distributions and can be installed with the package
+management system. qemu needs the OVMF.fd from the OVMF package file as
+argument to the -pflash option. As qemu needs write access to that file it's
+necessary to make a copy first.
+
+To start it create a USB memory stick like above and execute:
+
+.. code-block:: sh
+
+ qemu-system-x86_64 -pflash OVMF.fd -nographic /dev/sdx
+
+A plain VFAT image will work aswell, but in this case the UEFI BIOS won't
+recognize it as ESP and ``/boot`` won't be mounted.
+
+Loading EFI applications
+------------------------
+
+EFI supports loading applications aswell as drivers. barebox does not differentiate
+between both. Both types can be simply executed by typing the path on the command
+line. When an application/driver returns barebox iterates over the handle database
+and will initialize all new devices.
+
+Applications
+^^^^^^^^^^^^
+
+barebox itself and also the Linux Kernel are EFI applications. This means both
+can be directly executed. On other architectures when barebox is executed from
+another barebox it means the barebox binary will be replaced. EFI behaves
+differently, here different barebox instances will be nested, so exiting barebox
+means passing control to the calling instance. Note that currently the :ref:`command_reset`
+command will pass the control to the calling instance rather than resetting
+the CPU. This may change in the future.
+
+Although the Linux Kernel can be directly executed one should use the :ref:`command_bootm`
+command. Only the bootm command passes the Kernel commandline to the Kernel.
+
+Drivers
+^^^^^^^
+
+EFI is modular and drivers can be loaded during runtime. Many drivers are
+included in the BIOS already, but some have to be loaded during runtime,
+for example it's common that network drivers are not included in the BIOS.
+
+Drivers can be loaded under barebox simply by executing them:
+
+.. code-block:: sh
+
+ barebox:/ /boot/network-drivers/0001-SnpDxe.efi
+
+Should the drivers instanciate new devices these are automatically registered
+after the driver has been loaded.
+
+Simple Network Protocol (SNP)
+-----------------------------
+
+The Simple Network Protocol provides a raw packet interface to the EFI
+network drivers. Each device which supports SNP shows up as a regular
+network device under barebox. To use SNP the BIOS must have the SNP
+protocol and the network driver installed. For getting the SNP protocol
+follow the instruction in :ref:`efi_building_edk2`. Network drivers for
+the common Intel Network devices can be found here:
+
+https://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&DwnldID=19186
+
+Once instantiated the EFI drivers take some time to bring up the link, so
+it's best to only load the network drivers when needed. This can be
+archieved with the following script to put under ``/env/network/eth0-discover``:
+
+.. code-block:: sh
+
+ #!/bin/sh
+
+ for i in /boot/network-drivers/*; do
+ $i;
+ done
+
+This script will load the drivers in ``/boot/network-drivers/`` in alphabetical
+order.
+
+**NOTE** Loading the network drivers only works when loaded in the
+correct order. First the SNP driver must be loaded and then the network device
+driver. Otherwise the drivers will load without errors, but no devices will be
+instantiated. For making the order sure the driver names can be prepended with
+a number:
+
+.. code-block:: sh
+
+ /boot/network-drivers/0001-SnpDxe.efi
+ /boot/network-drivers/0002-E6208X3.EFI
+
+It is currently not known whether this is a limitation in EFI or a bug in
+barebox.
+
+EFI File IO Interface
+---------------------
+
+EFI itself has filesystem support. At least the :term:`ESP` will be mounted by the
+EFI core already. The :term:`ESP` is mounted to ``/boot`` under barebox, other devices
+are mounted to ``/efi<no>`` in no particular order.
+
+Block IO Protocol
+-----------------
+
+EFI provides access to block devices with the Block IO Protocol. This can
+be used to access raw block devices under barebox and also to access filesystems
+not supported by EFI. The block devices will show up as ``/dev/disk<diskno>.<partno>``
+under barebox and can be accessed like any other device:
+
+.. code-block:: sh
+
+ mount /dev/disk0.1 -text4 /mnt
+
+Care must be taken that a partition is only accessed either via the Block IO Protocol *or*
+the File IO Interface. Doing both at the same time will most likely result in data
+corruption on the partition
+
+EFI device pathes
+-----------------
+
+In EFI each device can be pointed to using a device path. Device pathes have multiple
+components. The toplevel component on X86 systems will be the PCI root complex, on
+other systems this can be the physical memory space. Each component will now descrive
+how to find the child component on the parent bus. Additional device path nodes can
+describe network addresses or filenames on partitions. Device pathes have a binary
+representation and a clearly defined string representation. These characteristics make
+device pathes suitable for describing boot entries. barebox could use device pathes
+to store the reference to kernels on boot media. Also device pathes could be used to
+pass a root filesystem to the Kernel.
+
+Currently device pathes are only integrated into barebox in a way that each EFI device
+has a device parameter ``devpath`` which contains its device path:
+
+.. code-block:: sh
+
+ barebox:/ echo ${handle-00000000d0012198.devpath}
+ pci_root(0)/Pci(0x1d,0x0)/Usb(0x1,0x0)/Usb(0x2,0x0)
+
+
+EFI variables
+-------------
+
+EFI has support for variables which are exported via the EFI Variable Services. EFI variables
+are identified by a 64bit GUID and a name. EFI variables can have arbitrary binary values, so
+they are not compatible with barebox shell variables which can only have printable content.
+Support for these variables is not yet complete in barebox. barebox contains the efivarfs which
+has the same format as the Linux Kernels efivarfs. It can be mounted with:
+
+.. code-block:: sh
+
+ mkdir efivarfs
+ mount -tefivarfs none /efivarfs
+
+In efivarfs each variable is represented by a file named <varname>-<guid>. Access to EFI variables
+is currently readonly. Since the variables have binary content using :ref:`command_md` is often
+more suitable than :ref:`command_cat`.
+
+EFI driver model and barebox
+----------------------------
+
+The EFI driver model is based around handles and protocols. A handle is an opaque
+cookie that represents a hardware device or a software object. Each handle can have
+multiple protocols attached to it. A protocol is a callable interface and is defined
+by a C struct containing function pointers. A protocol is identified by a 64bit GUID.
+Common examples for protocols are DEVICE_PATH, DEVICE_IO, BLOCK_IO, DISK_IO,
+FILE_SYSTEM, SIMPLE_INPUT or SIMPLE_TEXT_OUTPUT. Every handle that implements the
+DEVICE_PATH protocol is registered as device in barebox. The structure can be best
+seen in the ``devinfo`` output of such a device:
+
+.. code-block:: sh
+
+ barebox:/ devinfo handle-00000000cfaed198
+ Driver: efi-snp
+ Bus: efi
+ Protocols:
+ 0: a19832b9-ac25-11d3-9a2d-0090273fc14d
+ 1: 330d4706-f2a0-4e4f-a369-b66fa8d54385
+ 2: e5dd1403-d622-c24e-8488-c71b17f5e802
+ 3: 34d59603-1428-4429-a414-e6b3b5fd7dc1
+ 4: 0e1ad94a-dcf4-11db-9705-00e08161165f
+ 5: 1aced566-76ed-4218-bc81-767f1f977a89
+ 6: e3161450-ad0f-11d9-9669-0800200c9a66
+ 7: 09576e91-6d3f-11d2-8e39-00a0c969723b
+ 8: 51dd8b21-ad8d-48e9-bc3f-24f46722c748
+ Parameters:
+ devpath: pci_root(0)/Pci(0x1c,0x3)/Pci(0x0,0x0)/Mac(e03f4914f157)
+
+The protocols section in the output shows the different protocols this
+handle implements. One of this Protocols (here the first) is the Simple
+Network Protocol GUID:
+
+.. code-block:: c
+
+ #define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \
+ EFI_GUID( 0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D )
+
+Matching between EFI devices and drivers is done based on the Protocol GUIDs, so
+whenever a driver GUID matches one of the GUIDs a device imeplements the drivers
+probe function is called.
+
+.. _efi_building_edk2:
+
+Building EDK2
+-------------
+
+Additional drivers may be needed from the EDK2 package. For example to
+use Networking in barebox not only the network device drivers are needed,
+but also the Simple Network Protocol driver, SnpDxe.efi. This is often
+not included in the BIOS, but can be compiled from the EDK2 package.
+
+Here is only a quick walkthrough for building edk2, there are more elaborated
+HOWTOs in the net, for example on http://tianocore.sourceforge.net/wiki/Using_EDK_II_with_Native_GCC.
+
+.. code-block:: sh
+
+ git clone git://github.com/tianocore/edk2.git
+ cd edk2
+ make -C BaseTools
+ . edksetup.sh
+
+At least the following lines in ``Conf/target.txt`` should be edited::
+
+ ACTIVE_PLATFORM = MdeModulePkg/MdeModulePkg.dsc
+ TARGET_ARCH = X64
+ TOOL_CHAIN_TAG = GCC48
+ MAX_CONCURRENT_THREAD_NUMBER = 4
+
+The actual build is started with invoking ``build``. After building
+``Build/MdeModule/DEBUG_GCC48/X64/SnpDxe.efi`` should exist.
+
+**NOTE** As of this writing (July 2014) the following patch was needed to
+compile EDK2.
+
+.. code-block:: diff
+
+ diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
+ index 9783ec6..13fc06c 100644
+ --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
+ +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
+ @@ -280,7 +280,7 @@ ExtraPushDone:
+
+ mov %ds, %rax
+ pushq %rax
+ - movw %es, %rax
+ + mov %es, %rax^M
+ pushq %rax
+ mov %fs, %rax
+ pushq %rax
+
diff --git a/Documentation/glossary.rst b/Documentation/glossary.rst
index 8bad7dc..106dce9 100644
--- a/Documentation/glossary.rst
+++ b/Documentation/glossary.rst
@@ -16,3 +16,6 @@ Glossary
PBL
Pre BootLoader image
+
+ ESP
+ EFI System Partition
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/7] net: Add EFI Simple Network Protocol Driver
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
2014-07-11 7:36 ` [PATCH 1/7] Documentation: Add EFI documentation Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
2014-07-11 7:36 ` [PATCH 4/7] serial: Add EFI stdio driver Sascha Hauer
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
This adds a network driver which uses the EFI Simple Network
Protocol to implement networking for barebox.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/Kconfig | 4 +
drivers/net/Makefile | 1 +
drivers/net/efi-snp.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 301 insertions(+)
create mode 100644 drivers/net/efi-snp.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5f0c41b..43409a8 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -170,6 +170,10 @@ config DRIVER_NET_TAP
bool "tap Ethernet driver"
depends on LINUX
+config DRIVER_NET_EFI_SNP
+ bool "EFI SNP ethernet driver"
+ depends on ARCH_EFI
+
config DRIVER_NET_TSE
depends on NIOS2
bool "Altera TSE ethernet driver"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 33bb5c8..1b85778 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_DRIVER_NET_SMC911X) += smc911x.o
obj-$(CONFIG_DRIVER_NET_SMC91111) += smc91111.o
obj-$(CONFIG_DRIVER_NET_TAP) += tap.o
obj-$(CONFIG_DRIVER_NET_TSE) += altera_tse.o
+obj-$(CONFIG_DRIVER_NET_EFI_SNP) += efi-snp.o
diff --git a/drivers/net/efi-snp.c b/drivers/net/efi-snp.c
new file mode 100644
index 0000000..5b96fbf
--- /dev/null
+++ b/drivers/net/efi-snp.c
@@ -0,0 +1,296 @@
+/*
+ * efi-snp.c - Simple Network Protocol driver for EFI
+ *
+ * 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 <driver.h>
+#include <malloc.h>
+#include <net.h>
+#include <init.h>
+#include <efi.h>
+#include <mach/efi.h>
+#include <mach/efi-device.h>
+
+struct efi_network_statistics {
+ uint64_t RxTotalFrames;
+ uint64_t RxGoodFrames;
+ uint64_t RxUndersizeFrames;
+ uint64_t RxOversizeFrames;
+ uint64_t RxDroppedFrames;
+ uint64_t RxUnicastFrames;
+ uint64_t RxBroadcastFrames;
+ uint64_t RxMulticastFrames;
+ uint64_t RxCrcErrorFrames;
+ uint64_t RxTotalBytes;
+ uint64_t TxTotalFrames;
+ uint64_t TxGoodFrames;
+ uint64_t TxUndersizeFrames;
+ uint64_t TxOversizeFrames;
+ uint64_t TxDroppedFrames;
+ uint64_t TxUnicastFrames;
+ uint64_t TxBroadcastFrames;
+ uint64_t TxMulticastFrames;
+ uint64_t TxCrcErrorFrames;
+ uint64_t TxTotalBytes;
+ uint64_t Collisions;
+ uint64_t UnsupportedProtocol;
+};
+
+enum efi_simple_network_state {
+ EfiSimpleNetworkStopped,
+ EfiSimpleNetworkStarted,
+ EfiSimpleNetworkInitialized,
+ EfiSimpleNetworkMaxState
+};
+
+#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
+#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
+#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
+
+#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01
+#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02
+#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04
+#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08
+
+#define MAX_MCAST_FILTER_CNT 16
+struct efi_simple_network_mode {
+ uint32_t State;
+ uint32_t HwAddressSize;
+ uint32_t MediaHeaderSize;
+ uint32_t MaxPacketSize;
+ uint32_t NvRamSize;
+ uint32_t NvRamAccessSize;
+ uint32_t ReceiveFilterMask;
+ uint32_t ReceiveFilterSetting;
+ uint32_t MaxMCastFilterCount;
+ uint32_t MCastFilterCount;
+ efi_mac_address MCastFilter[MAX_MCAST_FILTER_CNT];
+ efi_mac_address CurrentAddress;
+ efi_mac_address BroadcastAddress;
+ efi_mac_address PermanentAddress;
+ uint8_t IfType;
+ bool MacAddressChangeable;
+ bool MultipleTxSupported;
+ bool MediaPresentSupported;
+ bool MediaPresent;
+};
+
+#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION 0x00010000
+
+struct efi_simple_network {
+ uint64_t Revision;
+ efi_status_t (EFIAPI *start) (struct efi_simple_network *This);
+ efi_status_t (EFIAPI *stop) (struct efi_simple_network *This);
+ efi_status_t (EFIAPI *initialize) (struct efi_simple_network *This,
+ unsigned long ExtraRxBufferSize, unsigned long ExtraTxBufferSize);
+ efi_status_t (EFIAPI *reset) (struct efi_simple_network *This, bool ExtendedVerification);
+ efi_status_t (EFIAPI *shutdown) (struct efi_simple_network *This);
+ efi_status_t (EFIAPI *receive_filters) (struct efi_simple_network *This,
+ uint32_t Enable, uint32_t Disable, bool ResetMCastFilter,
+ unsigned long MCastFilterCnt, efi_mac_address *MCastFilter);
+ efi_status_t (EFIAPI *station_address) (struct efi_simple_network *This,
+ bool Reset, efi_mac_address *New);
+ efi_status_t (EFIAPI *statistics) (struct efi_simple_network *This,
+ bool Reset, unsigned long *StatisticsSize,
+ struct efi_network_statistics *StatisticsTable);
+ efi_status_t (EFIAPI *mcast_ip_to_mac) (struct efi_simple_network *This,
+ bool IPv6, efi_ip_address *IP, efi_mac_address *MAC);
+ efi_status_t (EFIAPI *nvdata) (struct efi_simple_network *This,
+ bool ReadWrite, unsigned long Offset, unsigned long BufferSize,
+ void *Buffer);
+ efi_status_t (EFIAPI *get_status) (struct efi_simple_network *This,
+ uint32_t *InterruptStatus, void **TxBuf);
+ efi_status_t (EFIAPI *transmit) (struct efi_simple_network *This,
+ unsigned long HeaderSize, unsigned long BufferSize, void *Buffer,
+ efi_mac_address *SrcAddr, efi_mac_address *DestAddr,
+ uint16_t *Protocol);
+ efi_status_t (EFIAPI *receive) (struct efi_simple_network *This,
+ unsigned long *HeaderSize, unsigned long *BufferSize, void *Buffer,
+ efi_mac_address *SrcAddr, efi_mac_address *DestAddr, uint16_t *Protocol);
+ void *WaitForPacket;
+ struct efi_simple_network_mode *Mode;
+};
+
+struct efi_snp_priv {
+ struct device_d *dev;
+ struct eth_device edev;
+ struct efi_simple_network *snp;
+};
+
+static inline struct efi_snp_priv *to_priv(struct eth_device *edev)
+{
+ return container_of(edev, struct efi_snp_priv, edev);
+}
+
+static int efi_snp_eth_send(struct eth_device *edev, void *packet, int length)
+{
+ struct efi_snp_priv *priv = to_priv(edev);
+ efi_status_t efiret;
+ void *txbuf;
+ uint64_t start;
+
+ efiret = priv->snp->transmit(priv->snp, 0, length, packet, NULL, NULL, NULL);
+ if (EFI_ERROR(efiret)) {
+ dev_err(priv->dev, "failed to send: %s\n", efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ start = get_time_ns();
+
+ while (!is_timeout(start, SECOND)) {
+ uint32_t irq;
+ priv->snp->get_status(priv->snp, &irq, &txbuf);
+ if (txbuf)
+ return 0;
+ }
+
+ dev_err(priv->dev, "tx time out\n");
+
+ return -ETIMEDOUT;
+}
+
+static int efi_snp_eth_rx(struct eth_device *edev)
+{
+ struct efi_snp_priv *priv = to_priv(edev);
+ long bufsize = PKTSIZE;
+ efi_status_t efiret;
+
+ efiret = priv->snp->receive(priv->snp, NULL, &bufsize, NetRxPackets[0], NULL, NULL, NULL);
+ if (efiret == EFI_NOT_READY)
+ return 0;
+
+ if (EFI_ERROR(efiret)) {
+ dev_err(priv->dev, "failed to receive: %s\n", efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ net_receive(edev, NetRxPackets[0], bufsize);
+
+ return 0;
+}
+
+static int efi_snp_eth_open(struct eth_device *edev)
+{
+ struct efi_snp_priv *priv = to_priv(edev);
+ uint32_t mask;
+ efi_status_t efiret;
+
+ priv->snp->shutdown(priv->snp);
+ priv->snp->stop(priv->snp);
+ priv->snp->start(priv->snp);
+ efiret = priv->snp->initialize(priv->snp, 0, 0);
+ if (EFI_ERROR(efiret)) {
+ dev_err(priv->dev, "Initialize failed with: %s\n", efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ efiret = priv->snp->station_address(priv->snp, false,
+ (efi_mac_address *)priv->snp->Mode->PermanentAddress.Addr );
+ if (EFI_ERROR(efiret)) {
+ dev_err(priv->dev, "failed to set MAC address: %s\n",
+ efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
+ EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |
+ EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
+ efiret = priv->snp->receive_filters(priv->snp, mask, 0, 0, 0, 0);
+ if (EFI_ERROR(efiret)) {
+ dev_err(priv->dev, "failed to set receive filters: %s\n",
+ efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ return 0;
+}
+
+static void efi_snp_eth_halt(struct eth_device *edev)
+{
+ struct efi_snp_priv *priv = to_priv(edev);
+
+ priv->snp->stop(priv->snp);
+}
+
+static int efi_snp_get_ethaddr(struct eth_device *edev, unsigned char *adr)
+{
+ struct efi_snp_priv *priv = to_priv(edev);
+
+ memcpy(adr, priv->snp->Mode->PermanentAddress.Addr, 6);
+
+ return 0;
+}
+
+static int efi_snp_set_ethaddr(struct eth_device *edev, unsigned char *adr)
+{
+ return 0;
+}
+
+int efi_snp_probe(struct efi_device *efidev)
+{
+ struct eth_device *edev;
+ struct efi_snp_priv *priv;
+ int ret;
+
+ dev_dbg(&efidev->dev, "efi_snp_probe\n");
+
+ priv = xzalloc(sizeof(struct efi_snp_priv));
+ priv->snp = efidev->protocol;
+ priv->dev = &efidev->dev;
+
+ dev_dbg(&efidev->dev, "perm: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ priv->snp->Mode->PermanentAddress.Addr[0],
+ priv->snp->Mode->PermanentAddress.Addr[1],
+ priv->snp->Mode->PermanentAddress.Addr[2],
+ priv->snp->Mode->PermanentAddress.Addr[3],
+ priv->snp->Mode->PermanentAddress.Addr[4],
+ priv->snp->Mode->PermanentAddress.Addr[5]);
+ dev_dbg(&efidev->dev, "curr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ priv->snp->Mode->CurrentAddress.Addr[0],
+ priv->snp->Mode->CurrentAddress.Addr[1],
+ priv->snp->Mode->CurrentAddress.Addr[2],
+ priv->snp->Mode->CurrentAddress.Addr[3],
+ priv->snp->Mode->CurrentAddress.Addr[4],
+ priv->snp->Mode->CurrentAddress.Addr[5]);
+
+ edev = &priv->edev;
+ edev->priv = priv;
+ edev->parent = &efidev->dev;
+
+ edev->open = efi_snp_eth_open;
+ edev->send = efi_snp_eth_send;
+ edev->recv = efi_snp_eth_rx;
+ edev->halt = efi_snp_eth_halt;
+ edev->get_ethaddr = efi_snp_get_ethaddr;
+ edev->set_ethaddr = efi_snp_set_ethaddr;
+
+ ret = eth_register(edev);
+
+ return ret;
+}
+
+static struct efi_driver efi_snp_driver = {
+ .driver = {
+ .name = "efi-snp",
+ },
+ .probe = efi_snp_probe,
+ .guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID,
+};
+device_efi_driver(efi_snp_driver);
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 4/7] serial: Add EFI stdio driver
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
2014-07-11 7:36 ` [PATCH 1/7] Documentation: Add EFI documentation Sascha Hauer
2014-07-11 7:36 ` [PATCH 3/7] net: Add EFI Simple Network Protocol Driver Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
2014-07-11 7:36 ` [PATCH 5/7] fs: implement EFI filesystem driver Sascha Hauer
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
This adds a driver which uses the EFI stdin/stdout interfaces to
implement a barebox console. Keyboard input should be fairly complete,
but not all vt100 needed by barebox work properly. The clear-to-eol
escape is missing causing garbled output in the editor.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/edit.c | 11 +-
drivers/serial/Kconfig | 4 +
drivers/serial/Makefile | 1 +
drivers/serial/efi-stdio.c | 367 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 382 insertions(+), 1 deletion(-)
create mode 100644 drivers/serial/efi-stdio.c
diff --git a/commands/edit.c b/commands/edit.c
index 5a2da7d..98af583 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -379,7 +379,16 @@ static int do_edit(int argc, char *argv[])
return COMMAND_ERROR_USAGE;
screenwidth = 80;
- screenheight = 25;
+
+ /*
+ * The EFI simple text output protocol wraps to the next line and scrolls
+ * down when we write to the right bottom screen position. Reduce the number
+ * of rows by one to work around this.
+ */
+ if (IS_ENABLED(CONFIG_ARCH_EFI))
+ screenheight = 24;
+ else
+ screenheight = 25;
/* check if we are called as "sedit" instead of "edit" */
if (*argv[0] == 's') {
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f51c6e6..5698c2f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -45,6 +45,10 @@ config DRIVER_SERIAL_LINUX_CONSOLE
default y
bool "linux console driver"
+config DRIVER_SERIAL_EFI_STDIO
+ depends on ARCH_EFI
+ bool "EFI stdio driver"
+
config DRIVER_SERIAL_MPC5XXX
depends on MPC5200
default y
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index e1865f7..2c0176d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_DRIVER_SERIAL_PXA) += serial_pxa.o
obj-$(CONFIG_DRIVER_SERIAL_OMAP4_USBBOOT) += serial_omap4_usbboot.o
obj-$(CONFIG_DRIVER_SERIAL_AUART) += serial_auart.o
obj-$(CONFIG_DRIVER_SERIAL_CADENCE) += serial_cadence.o
+obj-$(CONFIG_DRIVER_SERIAL_EFI_STDIO) += efi-stdio.o
diff --git a/drivers/serial/efi-stdio.c b/drivers/serial/efi-stdio.c
new file mode 100644
index 0000000..bf14c5e
--- /dev/null
+++ b/drivers/serial/efi-stdio.c
@@ -0,0 +1,367 @@
+/*
+ * efi_console.c - EFI console 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 WITHOUT ANY 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 <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <console.h>
+#include <xfuncs.h>
+#include <efi.h>
+#include <readkey.h>
+#include <linux/ctype.h>
+#include <mach/efi.h>
+
+#define EFI_SHIFT_STATE_VALID 0x80000000
+#define EFI_RIGHT_CONTROL_PRESSED 0x00000004
+#define EFI_LEFT_CONTROL_PRESSED 0x00000008
+#define EFI_RIGHT_ALT_PRESSED 0x00000010
+#define EFI_LEFT_ALT_PRESSED 0x00000020
+
+#define EFI_CONTROL_PRESSED (EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)
+#define EFI_ALT_PRESSED (EFI_RIGHT_ALT_PRESSED | EFI_LEFT_ALT_PRESSED)
+#define KEYPRESS(keys, scan, uni) ((((uint64_t)keys) << 32) | ((scan) << 16) | (uni))
+#define KEYCHAR(k) ((k) & 0xffff)
+#define CHAR_CTRL(c) ((c) - 'a' + 1)
+
+#define EFI_BLACK 0x00
+#define EFI_BLUE 0x01
+#define EFI_GREEN 0x02
+#define EFI_CYAN (EFI_BLUE | EFI_GREEN)
+#define EFI_RED 0x04
+#define EFI_MAGENTA (EFI_BLUE | EFI_RED)
+#define EFI_BROWN (EFI_GREEN | EFI_RED)
+#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED)
+#define EFI_BRIGHT 0x08
+#define EFI_DARKGRAY (EFI_BRIGHT)
+#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT)
+#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT)
+#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT)
+#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT)
+#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT)
+#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT)
+#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
+
+#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4))
+
+#define EFI_BACKGROUND_BLACK 0x00
+#define EFI_BACKGROUND_BLUE 0x10
+#define EFI_BACKGROUND_GREEN 0x20
+#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)
+#define EFI_BACKGROUND_RED 0x40
+#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+
+struct efi_console_priv {
+ struct efi_simple_text_output_protocol *out;
+ struct efi_simple_input_interface *in;
+ struct console_device cdev;
+ int lastkey;
+ u16 efi_console_buffer[CONFIG_CBSIZE];
+
+ unsigned long columns, rows;
+
+ int current_color;
+ s16 *blank_line;
+};
+
+static inline struct efi_console_priv *to_efi(struct console_device *cdev)
+{
+ return container_of(cdev, struct efi_console_priv, cdev);
+}
+
+struct efi_ctrlkey {
+ u8 scan_code;
+ u8 bb_key;
+};
+
+static struct efi_ctrlkey ctrlkeys[] = {
+ { 0x01, BB_KEY_UP },
+ { 0x02, BB_KEY_DOWN },
+ { 0x03, BB_KEY_RIGHT },
+ { 0x04, BB_KEY_LEFT },
+ { 0x05, BB_KEY_HOME },
+ { 0x06, BB_KEY_END },
+ { 0x07, BB_KEY_INSERT },
+ { 0x08, BB_KEY_DEL },
+ { 0x09, BB_KEY_PAGEUP },
+ { 0x0a, BB_KEY_PAGEDOWN },
+};
+
+static int efi_read_key(struct efi_console_priv *priv, bool wait)
+{
+ unsigned long index;
+ efi_status_t efiret;
+ struct efi_input_key k;
+ int i;
+
+ /* wait until key is pressed */
+ if (wait)
+ BS->wait_for_event(1, priv->in->wait_for_key, &index);
+
+ efiret = priv->in->read_key_stroke(efi_sys_table->con_in, &k);
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+
+ /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
+ for (i = 0; i < ARRAY_SIZE(ctrlkeys); i++) {
+ if (ctrlkeys[i].scan_code == k.scan_code)
+ return ctrlkeys[i].bb_key;
+
+ }
+
+ return k.unicode_char & 0xff;
+}
+
+static void efi_console_putc(struct console_device *cdev, 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);
+}
+
+static void clear_to_eol(struct efi_console_priv *priv)
+{
+ int pos = priv->out->mode->cursor_column;
+
+ priv->out->output_string(priv->out, priv->blank_line + pos);
+}
+
+static int efi_process_square_bracket(struct efi_console_priv *priv, const char *inp)
+{
+ int x, y;
+ char *endp;
+
+ inp++;
+
+ switch (*inp) {
+ case 'A':
+ /* Cursor up */
+ case 'B':
+ /* Cursor down */
+ case 'C':
+ /* Cursor right */
+ case 'D':
+ /* Cursor left */
+ case 'H':
+ /* home */
+ case 'F':
+ /* end */
+ return 3;
+ case 'K':
+ clear_to_eol(priv);
+ return 3;
+ }
+
+ if (*inp == '2' && *(inp + 1) == 'J') {
+ priv->out->clear_screen(priv->out);
+ return 4;
+ }
+
+ if (*inp == '0' && *(inp + 1) == 'm') {
+ priv->out->set_attribute(priv->out,
+ EFI_TEXT_ATTR(EFI_WHITE, EFI_BLACK));
+ return 4;
+ }
+
+ if (*inp == '7' && *(inp + 1) == 'm') {
+ priv->out->set_attribute(priv->out,
+ EFI_TEXT_ATTR(EFI_BLACK, priv->current_color));
+ return 4;
+ }
+
+ if (*inp == '1' &&
+ *(inp + 1) == ';' &&
+ *(inp + 2) == '3' &&
+ *(inp + 3) &&
+ *(inp + 4) == 'm') {
+ int color;
+ switch (*(inp + 3)) {
+ case '1': color = EFI_RED; break;
+ case '4': color = EFI_BLUE; break;
+ case '2': color = EFI_GREEN; break;
+ case '6': color = EFI_CYAN; break;
+ case '3': color = EFI_YELLOW; break;
+ case '5': color = EFI_MAGENTA; break;
+ case '7': color = EFI_WHITE; break;
+ default: color = EFI_WHITE; break;
+ }
+
+ priv->current_color = color;
+
+ priv->out->set_attribute(priv->out,
+ EFI_TEXT_ATTR(color, EFI_BLACK));
+ return 7;
+ }
+
+ y = simple_strtoul(inp, &endp, 10);
+ if (*endp == ';') {
+ x = simple_strtoul(endp + 1, &endp, 10);
+ if (*endp == 'H') {
+ priv->out->set_cursor_position(priv->out, x - 1, y - 1);
+ return endp - inp + 3;
+ }
+ }
+
+ return 8;
+}
+
+static int efi_process_key(struct efi_console_priv *priv, const char *inp)
+{
+ char c;
+
+ c = *inp;
+
+ if (c != 27)
+ return 0;
+
+ inp++;
+
+ if (*inp == '[')
+ return efi_process_square_bracket(priv, inp);
+
+ return 1;
+}
+
+static int efi_console_puts(struct console_device *cdev, const char *s)
+{
+ struct efi_console_priv *priv = to_efi(cdev);
+ int n = 0;
+
+ while (*s) {
+ if (*s == 27) {
+ priv->efi_console_buffer[n] = 0;
+ priv->out->output_string(priv->out,
+ priv->efi_console_buffer);
+ n = 0;
+ s += efi_process_key(priv, s);
+ continue;
+ }
+
+ if (*s == '\n')
+ priv->efi_console_buffer[n++] = '\r';
+ priv->efi_console_buffer[n] = *s;
+ s++;
+ n++;
+ }
+
+ priv->efi_console_buffer[n] = 0;
+
+ priv->out->output_string(priv->out, priv->efi_console_buffer);
+
+ return n;
+}
+
+static int efi_console_tstc(struct console_device *cdev)
+{
+ struct efi_console_priv *priv = to_efi(cdev);
+ int key;
+
+ if (priv->lastkey > 0)
+ return 1;
+
+ key = efi_read_key(priv, 0);
+ if (key < 0)
+ return 0;
+
+ priv->lastkey = key;
+
+ return 1;
+}
+
+static int efi_console_getc(struct console_device *cdev)
+{
+ struct efi_console_priv *priv = to_efi(cdev);
+ int key;
+
+ if (priv->lastkey > 0) {
+ key = priv->lastkey;
+ priv->lastkey = -1;
+ return key;
+ }
+
+ return efi_read_key(priv, 1);
+}
+
+static void efi_set_mode(struct efi_console_priv *priv)
+{
+#if 0
+ int i;
+ unsigned long rows, columns, best = 0, mode = 0;
+ efi_status_t efiret;
+
+ for (i = 0; i < priv->out->mode->max_mode; i++) {
+ priv->out->query_mode(priv->out, i, &columns, &rows);
+ printf("%d: %ld %ld\n", i, columns, rows);
+ if (rows * columns > best) {
+ best = rows * columns;
+ mode = i;
+ }
+ }
+
+ /*
+ * Setting the mode doesn't work as expected. set_mode succeeds, but
+ * the graphics resolution is not changed.
+ */
+ priv->out->set_mode(priv->out, mode);
+#endif
+ priv->out->query_mode(priv->out, priv->out->mode->mode, &priv->columns, &priv->rows);
+}
+
+static int efi_console_probe(struct device_d *dev)
+{
+ struct console_device *cdev;
+ struct efi_console_priv *priv;
+ int i;
+
+ priv = xzalloc(sizeof(*priv));
+
+ priv->out = efi_sys_table->con_out;
+ priv->in = efi_sys_table->con_in;
+
+ priv->current_color = EFI_WHITE;
+
+ efi_set_mode(priv);
+
+ priv->out->enable_cursor(priv->out, 1);
+
+ priv->blank_line = xzalloc((priv->columns + 1) * sizeof(s16));
+ for (i = 0; i < priv->columns; i++)
+ priv->blank_line[i] = ' ';
+
+ cdev = &priv->cdev;
+ cdev->dev = dev;
+ cdev->tstc = efi_console_tstc;
+ cdev->getc = efi_console_getc;
+ cdev->putc = efi_console_putc;
+ cdev->puts = efi_console_puts;
+
+ priv->lastkey = -1;
+
+ return console_register(cdev);
+}
+
+static struct driver_d efi_console_driver = {
+ .name = "efi-stdio",
+ .probe = efi_console_probe,
+};
+console_platform_driver(efi_console_driver);
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 5/7] fs: implement EFI filesystem driver
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
` (2 preceding siblings ...)
2014-07-11 7:36 ` [PATCH 4/7] serial: Add EFI stdio driver Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
2014-07-11 7:36 ` [PATCH 6/7] fs: implement EFI variable " Sascha Hauer
2014-07-11 7:36 ` [PATCH 7/7] EFI: introduce efi_strguid to convert GUID to human readable names Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
This implements a filesystem driver which uses the EFI Simple File
System Protocol to provide files from EFI to barebox.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
fs/Kconfig | 8 +
fs/Makefile | 1 +
fs/efi.c | 563 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 572 insertions(+)
create mode 100644 fs/efi.c
diff --git a/fs/Kconfig b/fs/Kconfig
index 3724b34..21690de 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -41,6 +41,14 @@ config FS_NFS
bool
prompt "nfs support"
+config FS_EFI
+ depends on ARCH_EFI
+ bool
+ prompt "EFI filesystem support"
+ help
+ This filesystem driver provides access to the filesystems provided
+ by the EFI Firmware via the EFI Simple File System Protocol.
+
source fs/fat/Kconfig
source fs/ubifs/Kconfig
diff --git a/fs/Makefile b/fs/Makefile
index d3465ed..f027851 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_FS_OMAP4_USBBOOT) += omap4_usbbootfs.o
obj-$(CONFIG_FS_NFS) += nfs.o parseopt.o
obj-$(CONFIG_FS_BPKFS) += bpkfs.o
obj-$(CONFIG_FS_UIMAGEFS) += uimagefs.o
+obj-$(CONFIG_FS_EFI) += efi.o
diff --git a/fs/efi.c b/fs/efi.c
new file mode 100644
index 0000000..f096f91
--- /dev/null
+++ b/fs/efi.c
@@ -0,0 +1,563 @@
+/*
+ * efi.c - EFI filesystem mirror driver
+ *
+ * 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 WITHOUT ANY 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 <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 <wchar.h>
+#include <efi.h>
+#include <mach/efi.h>
+#include <mach/efi-device.h>
+
+/* Open modes */
+#define EFI_FILE_MODE_READ 0x0000000000000001
+#define EFI_FILE_MODE_WRITE 0x0000000000000002
+#define EFI_FILE_MODE_CREATE 0x8000000000000000
+
+/* File attributes */
+#define EFI_FILE_READ_ONLY 0x0000000000000001
+#define EFI_FILE_HIDDEN 0x0000000000000002
+#define EFI_FILE_SYSTEM 0x0000000000000004
+#define EFI_FILE_RESERVIED 0x0000000000000008
+#define EFI_FILE_DIRECTORY 0x0000000000000010
+#define EFI_FILE_ARCHIVE 0x0000000000000020
+#define EFI_FILE_VALID_ATTR 0x0000000000000037
+
+#define EFI_FILE_HANDLE_REVISION 0x00010000
+struct efi_file_handle {
+ uint64_t Revision;
+ efi_status_t(EFIAPI *open)(struct efi_file_handle *File,
+ struct efi_file_handle **NewHandle, s16 *FileName,
+ uint64_t OpenMode, uint64_t Attributes);
+ efi_status_t(EFIAPI *close)(struct efi_file_handle *File);
+ efi_status_t(EFIAPI *delete)(struct efi_file_handle *File);
+ efi_status_t(EFIAPI *read)(struct efi_file_handle *File, unsigned long *BufferSize,
+ void *Buffer);
+ efi_status_t(EFIAPI *write)(struct efi_file_handle *File,
+ unsigned long *BufferSize, void *Buffer);
+ efi_status_t(EFIAPI *get_position)(struct efi_file_handle *File,
+ uint64_t *Position);
+ efi_status_t(EFIAPI *set_position)(struct efi_file_handle *File,
+ uint64_t Position);
+ efi_status_t(EFIAPI *get_info)(struct efi_file_handle *File,
+ efi_guid_t *InformationType, unsigned long *BufferSize,
+ void *Buffer);
+ efi_status_t(EFIAPI *set_info)(struct efi_file_handle *File,
+ efi_guid_t *InformationType, unsigned long BufferSize,
+ void *Buffer);
+ efi_status_t(EFIAPI *flush)(struct efi_file_handle *File);
+};
+
+#define EFI_FILE_IO_INTERFACE_REVISION 0x00010000
+
+struct efi_file_io_interface {
+ uint64_t Revision;
+ efi_status_t(EFIAPI *open_volume)(
+ struct efi_file_io_interface *This,
+ struct efi_file_handle **Root);
+};
+
+struct efi_file_info {
+ uint64_t Size;
+ uint64_t FileSize;
+ uint64_t PhysicalSize;
+ efi_time_t CreateTime;
+ efi_time_t LastAccessTime;
+ efi_time_t ModificationTime;
+ uint64_t Attribute;
+ s16 FileName[1];
+};
+
+typedef unsigned short wchar_t;
+
+struct efifs_priv {
+ struct efi_file_handle *root_dir;
+ struct efi_file_io_interface *protocol;
+};
+
+struct efifs_file {
+ struct efi_file_handle *entry;
+};
+
+struct efifs_dir {
+ DIR dir;
+ struct efi_file_handle *entries;
+};
+
+static wchar_t *path_to_efi(const char *path)
+{
+ wchar_t *dst;
+ wchar_t *ret;
+
+ if (!*path)
+ return strdup_char_to_wchar("\\");
+
+ dst = strdup_char_to_wchar(path);
+ if (!dst)
+ return NULL;
+
+ ret = dst;
+
+ while (*dst) {
+ if (*dst == '/')
+ *dst = '\\';
+ dst++;
+ }
+
+ return ret;
+}
+
+static int efifs_create(struct device_d *dev, const char *pathname, mode_t mode)
+{
+ struct efifs_priv *priv = dev->priv;
+ wchar_t *efi_path = path_to_efi(pathname);
+ struct efi_file_handle *entry;
+ efi_status_t efiret;
+
+ efiret = priv->root_dir->open(priv->root_dir, &entry, efi_path,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+ 0ULL);
+
+ free(efi_path);
+
+ if (EFI_ERROR(efiret)) {
+ printf("%s %s: %s\n", __func__, pathname, efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ entry->close(entry);
+
+ return 0;
+}
+
+static int efifs_unlink(struct device_d *dev, const char *pathname)
+{
+ struct efifs_priv *priv = dev->priv;
+ wchar_t *efi_path = path_to_efi(pathname);
+ struct efi_file_handle *entry;
+ efi_status_t efiret;
+
+ efiret = priv->root_dir->open(priv->root_dir, &entry, efi_path,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0ULL);
+
+ free(efi_path);
+
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+
+ efiret = entry->delete(entry);
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+
+ return 0;
+}
+
+static int efifs_mkdir(struct device_d *dev, const char *pathname)
+{
+ struct efifs_priv *priv = dev->priv;
+ wchar_t *efi_path = path_to_efi(pathname);
+ struct efi_file_handle *entry;
+ efi_status_t efiret;
+
+ efiret = priv->root_dir->open(priv->root_dir, &entry, efi_path,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+ EFI_FILE_DIRECTORY);
+
+ free(efi_path);
+
+ if (EFI_ERROR(efiret)) {
+ printf("%s %s: %s\n", __func__, pathname, efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ entry->close(entry);
+
+ return 0;
+}
+
+static int efifs_rmdir(struct device_d *dev, const char *pathname)
+{
+ return efifs_unlink(dev, pathname);
+}
+
+static int efifs_open(struct device_d *dev, FILE *f, const char *filename)
+{
+ struct efifs_priv *priv = dev->priv;
+ efi_status_t efiret;
+ struct efifs_file *ufile;
+ wchar_t *efi_path = path_to_efi(filename);
+ struct efi_file_info *info;
+ unsigned long bufsize = 1024;
+ uint64_t efimode = EFI_FILE_MODE_READ;
+ int ret;
+
+ ufile = xzalloc(sizeof(*ufile));
+
+ if (f->flags & O_ACCMODE)
+ efimode |= EFI_FILE_MODE_WRITE;
+
+ efiret = priv->root_dir->open(priv->root_dir, &ufile->entry, efi_path,
+ efimode, 0ULL);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to Open %s: %s\n", __func__,
+ filename, efi_strerror(efiret));
+ free(ufile);
+ return -efi_errno(efiret);
+ }
+
+ free(efi_path);
+
+ info = xzalloc(1024);
+ efiret = ufile->entry->get_info(ufile->entry, &efi_file_info_id, &bufsize, info);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to GetInfo %s: %s\n", __func__,
+ filename, efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ f->size = info->FileSize;
+
+ free(info);
+ f->inode = ufile;
+
+ return 0;
+out:
+ free(info);
+ free(ufile);
+ return ret;
+}
+
+static int efifs_close(struct device_d *dev, FILE *f)
+{
+ struct efifs_file *ufile = f->inode;
+
+ ufile->entry->close(ufile->entry);
+
+ free(ufile);
+
+ return 0;
+}
+
+static int efifs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
+{
+ struct efifs_file *ufile = f->inode;
+ efi_status_t efiret;
+ unsigned long bufsize = insize;
+
+ efiret = ufile->entry->read(ufile->entry, &bufsize, buf);
+ if (EFI_ERROR(efiret)) {
+ return -efi_errno(efiret);
+ }
+
+ return bufsize;
+}
+
+static int efifs_write(struct device_d *_dev, FILE *f, const void *buf, size_t insize)
+{
+ struct efifs_file *ufile = f->inode;
+ efi_status_t efiret;
+ unsigned long bufsize = insize;
+
+ efiret = ufile->entry->write(ufile->entry, &bufsize, (void *)buf);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to write: %s\n", __func__, efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ return bufsize;
+}
+
+static loff_t efifs_lseek(struct device_d *dev, FILE *f, loff_t pos)
+{
+ struct efifs_file *ufile = f->inode;
+ efi_status_t efiret;
+
+ f->pos = pos;
+
+ efiret = ufile->entry->set_position(ufile->entry, pos);
+ if (EFI_ERROR(efiret)) {
+ return -efi_errno(efiret);
+ }
+
+ return f->pos;
+}
+
+static int efifs_truncate(struct device_d *dev, FILE *f, unsigned long size)
+{
+ struct efifs_file *ufile = f->inode;
+ efi_status_t efiret;
+ struct efi_file_info *info;
+ unsigned long bufsize = 1024;
+ int ret;
+
+ info = xzalloc(1024);
+
+ efiret = ufile->entry->get_info(ufile->entry, &efi_file_info_id, &bufsize, info);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to GetInfo: %s\n", __func__, efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ if (size > info->FileSize)
+ return 0;
+
+ info->FileSize = size;
+
+ efiret = ufile->entry->set_info(ufile->entry, &efi_file_info_id, bufsize, info);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to SetInfo: %s\n", __func__, efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ return 0;
+out:
+ return ret;
+}
+
+static DIR *efifs_opendir(struct device_d *dev, const char *pathname)
+{
+ struct efifs_priv *priv = dev->priv;
+ efi_status_t efiret;
+ struct efifs_dir *udir;
+ wchar_t *efi_path = path_to_efi(pathname);
+
+ udir = xzalloc(sizeof(*udir));
+
+ efiret = priv->root_dir->open(priv->root_dir, &udir->entries, efi_path, EFI_FILE_MODE_READ, 0ULL);
+ if (EFI_ERROR(efiret)) {
+ free(udir);
+ return NULL;
+ }
+
+ free(efi_path);
+
+ return &udir->dir;
+}
+
+static struct dirent *efifs_readdir(struct device_d *dev, DIR *dir)
+{
+ struct efifs_dir *udir = container_of(dir, struct efifs_dir, dir);
+ efi_status_t efiret;
+ unsigned long bufsize = 256;
+ s16 buf[256];
+ struct efi_file_info *f;
+
+ efiret = udir->entries->read(udir->entries, &bufsize, buf);
+ if (EFI_ERROR(efiret) || bufsize == 0)
+ return NULL;
+
+ f = (struct efi_file_info *)buf;
+
+ strcpy_wchar_to_char(dir->d.d_name, f->FileName);
+
+ return &dir->d;
+}
+
+static int efifs_closedir(struct device_d *dev, DIR *dir)
+{
+ struct efifs_dir *udir = container_of(dir, struct efifs_dir, dir);
+
+ udir->entries->close(udir->entries);
+
+ free(dir);
+
+ return 0;
+}
+
+static int efifs_stat(struct device_d *dev, const char *filename, struct stat *s)
+{
+ struct efifs_priv *priv = dev->priv;
+ wchar_t *efi_path;
+ efi_status_t efiret;
+ struct efi_file_handle *entry;
+ struct efi_file_info *info;
+ unsigned long bufsize = 1024;
+ int ret;
+
+ info = xzalloc(1024);
+
+ efi_path = path_to_efi(filename);
+
+ efiret = priv->root_dir->open(priv->root_dir, &entry, efi_path, EFI_FILE_MODE_READ, 0ULL);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to Open %s: %s\n", __func__, filename,
+ efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ goto out_free;
+ }
+
+ efiret = entry->get_info(entry, &efi_file_info_id, &bufsize, info);
+ if (EFI_ERROR(efiret)) {
+ pr_err("%s: unable to GetInfo %s: %s\n", __func__, filename,
+ efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ s->st_size = info->FileSize;
+ s->st_mode = 00555;
+
+ if (!info->Attribute & EFI_FILE_READ_ONLY)
+ s->st_mode |= 00222;
+
+ if (info->Attribute & EFI_FILE_DIRECTORY)
+ s->st_mode |= S_IFDIR;
+ else
+ s->st_mode |= S_IFREG;
+
+ ret = 0;
+out:
+ entry->close(entry);
+out_free:
+ free(efi_path);
+ free(info);
+
+ return ret;
+}
+
+static int efifs_symlink(struct device_d *dev, const char *pathname,
+ const char *newpath)
+{
+ return -EROFS;
+}
+
+static int efifs_readlink(struct device_d *dev, const char *pathname,
+ char *buf, size_t bufsiz)
+{
+ return -ENOENT;
+}
+
+static int efifs_probe(struct device_d *dev)
+{
+ struct fs_device_d *fsdev = dev_to_fs_device(dev);
+ struct efifs_priv *priv;
+ efi_status_t efiret;
+ struct efi_file_handle *file;
+ struct device_d *efi = get_device_by_name(fsdev->backingstore);
+ struct efi_device *udev = container_of(efi, struct efi_device, dev);
+
+ priv = xzalloc(sizeof(struct efifs_priv));
+ priv->protocol = udev->protocol;
+ dev->priv = priv;
+ dev->parent = &udev->dev;
+
+ efiret = priv->protocol->open_volume(priv->protocol, &file);
+ if (EFI_ERROR(efiret)) {
+ dev_err(dev, "failed to open volume: %s\n", efi_strerror(efiret));
+ return -efi_errno(efiret);
+ }
+
+ priv->root_dir = file;
+
+ return 0;
+}
+
+static void efifs_remove(struct device_d *dev)
+{
+ free(dev->priv);
+}
+
+static struct fs_driver_d efifs_driver = {
+ .create = efifs_create,
+ .unlink = efifs_unlink,
+ .open = efifs_open,
+ .close = efifs_close,
+ .truncate = efifs_truncate,
+ .read = efifs_read,
+ .write = efifs_write,
+ .lseek = efifs_lseek,
+ .mkdir = efifs_mkdir,
+ .rmdir = efifs_rmdir,
+ .opendir = efifs_opendir,
+ .readdir = efifs_readdir,
+ .closedir = efifs_closedir,
+ .stat = efifs_stat,
+ .symlink = efifs_symlink,
+ .readlink = efifs_readlink,
+ .drv = {
+ .probe = efifs_probe,
+ .remove = efifs_remove,
+ .name = "efifs",
+ }
+};
+
+static int efifs_init(void)
+{
+ return register_fs_driver(&efifs_driver);
+}
+
+coredevice_initcall(efifs_init);
+
+static int index;
+
+int efi_fs_probe(struct efi_device *efidev)
+{
+ char *path, *device;
+ int ret;
+ struct efi_file_io_interface *volume;
+
+ if (efi_loaded_image)
+ BS->handle_protocol(efi_loaded_image->device_handle,
+ &efi_simple_file_system_protocol_guid, (void*)&volume);
+
+ if (efidev->protocol == volume)
+ path = xstrdup("/boot");
+ else
+ path = asprintf("/efi%d", index);
+ device = asprintf("%s", dev_name(&efidev->dev));
+
+ ret = make_directory(path);
+ if (ret)
+ goto out;
+
+ ret = mount(device, "efifs", path, NULL);
+ if (ret)
+ goto out;
+
+ index++;
+
+ dev_info(&efidev->dev, "mounted on %s\n", path);
+
+ ret = 0;
+out:
+ free(path);
+ free(device);
+
+ return ret;
+}
+
+static struct efi_driver efi_fs_driver = {
+ .driver = {
+ .name = "efi-fs",
+ },
+ .probe = efi_fs_probe,
+ .guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
+};
+device_efi_driver(efi_fs_driver);
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 6/7] fs: implement EFI variable filesystem driver
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
` (3 preceding siblings ...)
2014-07-11 7:36 ` [PATCH 5/7] fs: implement EFI filesystem driver Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
2014-07-11 7:36 ` [PATCH 7/7] EFI: introduce efi_strguid to convert GUID to human readable names Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
This implements a filesystem for accessing EFI variables.
It is compatible to the Linux Kernel efivarfs filesystem.
Currently the variables can only be accessed readonly.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
fs/Kconfig | 7 ++
fs/Makefile | 1 +
fs/efivarfs.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 348 insertions(+)
create mode 100644 fs/efivarfs.c
diff --git a/fs/Kconfig b/fs/Kconfig
index 21690de..64fc117 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -49,6 +49,13 @@ config FS_EFI
This filesystem driver provides access to the filesystems provided
by the EFI Firmware via the EFI Simple File System Protocol.
+config FS_EFIVARFS
+ depends on ARCH_EFI
+ bool
+ prompt "EFI variable filesystem support (efivarfs)"
+ help
+ This filesystem driver provides access to EFI variables.
+
source fs/fat/Kconfig
source fs/ubifs/Kconfig
diff --git a/fs/Makefile b/fs/Makefile
index f027851..f5aae91 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_FS_NFS) += nfs.o parseopt.o
obj-$(CONFIG_FS_BPKFS) += bpkfs.o
obj-$(CONFIG_FS_UIMAGEFS) += uimagefs.o
obj-$(CONFIG_FS_EFI) += efi.o
+obj-$(CONFIG_FS_EFIVARFS) += efivarfs.o
diff --git a/fs/efivarfs.c b/fs/efivarfs.c
new file mode 100644
index 0000000..58c637e
--- /dev/null
+++ b/fs/efivarfs.c
@@ -0,0 +1,340 @@
+/*
+ * ramfs.c - a malloc based filesystem
+ *
+ * Copyright (c) 2007 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 WITHOUT ANY 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 <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <fs.h>
+#include <string.h>
+#include <errno.h>
+#include <linux/stat.h>
+#include <xfuncs.h>
+#include <fcntl.h>
+#include <efi.h>
+#include <wchar.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <mach/efi.h>
+#include <mach/efi-device.h>
+
+struct efivarfs_priv {
+ struct efi_file_handle *root_dir;
+ struct efi_file_io_interface *protocol;
+};
+
+static int char_to_nibble(char c)
+{
+ int ret = tolower(c);
+
+ return ret <= '9' ? ret - '0' : ret - 'a' + 10;
+}
+
+static int read_byte_str(const char *str, u8 *out)
+{
+ if (!isxdigit(*str) || !isxdigit(*(str + 1)))
+ return -EINVAL;
+
+ *out = (char_to_nibble(*str) << 4) | char_to_nibble(*(str + 1));
+
+ return 0;
+}
+
+int efi_guid_parse(const char *str, efi_guid_t *guid)
+{
+ int i, ret;
+ u8 idx[] = { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ for (i = 0; i < 16; i++) {
+ ret = read_byte_str(str, &guid->b[idx[i]]);
+ if (ret)
+ return ret;
+ str += 2;
+
+ switch (i) {
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ if (*str != '-')
+ return -EINVAL;
+ str++;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int efivarfs_parse_filename(const char *filename, efi_guid_t *vendor, s16 **name)
+{
+ int len, ret;
+ const char *guidstr;
+ s16 *varname;
+ int i;
+
+ if (*filename == '/')
+ filename++;
+
+ len = strlen(filename);
+
+ if (len < sizeof("-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"))
+ return -EINVAL;
+
+ guidstr = filename + len - sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
+ if (*guidstr != '-')
+ return -EINVAL;
+
+ guidstr++;
+
+ ret = efi_guid_parse(guidstr, vendor);
+
+ varname = xzalloc((guidstr - filename) * sizeof(s16));
+
+ for (i = 0; i < guidstr - filename - 1; i++)
+ varname[i] = filename[i];
+
+ *name = varname;
+
+ return 0;
+}
+
+struct efivars_file {
+ void *buf;
+ unsigned long size;
+ efi_guid_t vendor;
+ s16 *name;
+};
+
+static int efivarfs_open(struct device_d *dev, FILE *f, const char *filename)
+{
+ struct efivars_file *efile;
+ efi_status_t efiret;
+ int ret;
+ uint32_t attributes;
+
+ efile = xzalloc(sizeof(*efile));
+
+ ret = efivarfs_parse_filename(filename, &efile->vendor, &efile->name);
+ if (ret)
+ return -ENOENT;
+
+ efiret = RT->get_variable(efile->name, &efile->vendor, &attributes, &efile->size, NULL);
+ if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) {
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ efile->buf = malloc(efile->size + sizeof(uint32_t));
+ if (!efile->buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ efiret = RT->get_variable(efile->name, &efile->vendor, NULL, &efile->size,
+ efile->buf + sizeof(uint32_t));
+ if (EFI_ERROR(efiret)) {
+ ret = -efi_errno(efiret);
+ goto out;
+ }
+
+ *(uint32_t *)efile->buf = attributes;
+
+ f->size = efile->size + sizeof(uint32_t);
+ f->inode = efile;
+
+ return 0;
+
+out:
+ free(efile->buf);
+ free(efile);
+
+ return ret;
+}
+
+static int efivarfs_close(struct device_d *dev, FILE *f)
+{
+ struct efivars_file *efile = f->inode;
+
+ free(efile->buf);
+ free(efile);
+
+ return 0;
+}
+
+static int efivarfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
+{
+ struct efivars_file *efile = f->inode;
+
+ memcpy(buf, efile->buf + f->pos, insize);
+
+ return insize;
+}
+
+static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
+{
+ f->pos = pos;
+
+ return f->pos;
+}
+
+struct efivarfs_dir_entry {
+ char *name;
+ struct efivarfs_dir_entry *next;
+};
+
+struct efivarfs_dir {
+ struct efivarfs_dir_entry *first;
+ struct efivarfs_dir_entry *current;
+ DIR dir;
+};
+
+static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
+{
+ efi_status_t efiret;
+ efi_guid_t vendor;
+ s16 name[1024];
+ struct efivarfs_dir *edir;
+ unsigned long size;
+ unsigned char *name8;
+
+ name[0] = 0;
+
+ edir = xzalloc(sizeof(*edir));
+
+ while (1) {
+ struct efivarfs_dir_entry *entry;
+
+ size = sizeof(name);
+ efiret = RT->get_next_variable(&size, name, &vendor);
+ if (EFI_ERROR(efiret))
+ break;
+
+ entry = xzalloc(sizeof(*entry));
+ name8 = strdup_wchar_to_char(name);
+
+ entry->name = asprintf("%s-%pUl", name8, &vendor);
+
+ free(name8);
+
+ if (!edir->first)
+ edir->first = entry;
+
+ if (edir->current)
+ edir->current->next = entry;
+
+ edir->current = entry;
+ }
+
+ edir->current = edir->first;
+
+ return &edir->dir;
+}
+
+static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
+{
+ struct efivarfs_dir *edir = container_of(dir, struct efivarfs_dir, dir);
+
+ if (!edir->current)
+ return NULL;
+
+ strcpy(dir->d.d_name, edir->current->name);
+
+ edir->current = edir->current->next;
+
+ return &dir->d;
+}
+
+static int efivarfs_closedir(struct device_d *dev, DIR *dir)
+{
+ struct efivarfs_dir *edir = container_of(dir, struct efivarfs_dir, dir);
+ struct efivarfs_dir_entry *entry;
+
+ entry = edir->first;
+
+ while (entry) {
+ struct efivarfs_dir_entry *tmp;
+ free(entry->name);
+ tmp = entry->next;
+ free(entry);
+ entry = tmp;
+ }
+
+ free(edir);
+
+ return 0;
+}
+
+static int efivarfs_stat(struct device_d *dev, const char *filename, struct stat *s)
+{
+ efi_guid_t vendor;
+ s16 *name;
+ efi_status_t efiret;
+ unsigned long size = 0;
+ int ret;
+
+ ret = efivarfs_parse_filename(filename, &vendor, &name);
+ if (ret)
+ return -ENOENT;
+
+ efiret = RT->get_variable(name, &vendor, NULL, &size, NULL);
+
+ free(name);
+
+ if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL)
+ return -efi_errno(efiret);
+
+ s->st_mode = 00666 | S_IFREG;
+ s->st_size = size;
+
+ return 0;
+}
+
+static int efivarfs_probe(struct device_d *dev)
+{
+ return 0;
+}
+
+static void efivarfs_remove(struct device_d *dev)
+{
+ free(dev->priv);
+}
+
+static struct fs_driver_d efivarfs_driver = {
+ .open = efivarfs_open,
+ .close = efivarfs_close,
+ .read = efivarfs_read,
+ .lseek = efivarfs_lseek,
+ .opendir = efivarfs_opendir,
+ .readdir = efivarfs_readdir,
+ .closedir = efivarfs_closedir,
+ .stat = efivarfs_stat,
+ .drv = {
+ .probe = efivarfs_probe,
+ .remove = efivarfs_remove,
+ .name = "efivarfs",
+ }
+};
+
+static int efivarfs_init(void)
+{
+ return register_fs_driver(&efivarfs_driver);
+}
+
+coredevice_initcall(efivarfs_init);
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 7/7] EFI: introduce efi_strguid to convert GUID to human readable names
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
` (4 preceding siblings ...)
2014-07-11 7:36 ` [PATCH 6/7] fs: implement EFI variable " Sascha Hauer
@ 2014-07-11 7:36 ` Sascha Hauer
5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2014-07-11 7:36 UTC (permalink / raw)
To: barebox
From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
use in devinfo Protocols
Tested today on qemu with all the GUID translated
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/efi/efi/efi-device.c | 3 +-
arch/efi/efi/efi.c | 5 ++-
common/efi-guid.c | 73 +++++++++++++++++++++++++++++++
include/efi.h | 108 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 186 insertions(+), 3 deletions(-)
diff --git a/arch/efi/efi/efi-device.c b/arch/efi/efi/efi-device.c
index 71526b9..1c9553d 100644
--- a/arch/efi/efi/efi-device.c
+++ b/arch/efi/efi/efi-device.c
@@ -86,7 +86,8 @@ static void efi_devinfo(struct device_d *dev)
printf("Protocols:\n");
for (i = 0; i < efidev->num_guids; i++)
- printf(" %d: %pUl\n", i, &efidev->guids[i]);
+ printf(" %d: %pUl: %s\n", i, &efidev->guids[i],
+ efi_guid_string(&efidev->guids[i]));
}
static efi_handle_t *efi_find_parent(efi_handle_t *handle)
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index 48b7d9a..ff97783 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -36,6 +36,7 @@
#include <binfmt.h>
#include <wchar.h>
#include <envfs.h>
+#include <efi.h>
#include <mach/efi.h>
#include <mach/efi-device.h>
@@ -233,6 +234,8 @@ static struct NS16550_plat ns16550_plat = {
static int efi_console_init(void)
{
+ barebox_set_model("barebox EFI payload");
+
add_generic_device("efi-stdio", DEVICE_ID_SINGLE, NULL, 0 , 0, 0, NULL);
if (IS_ENABLED(CONFIG_ARCH_EFI_REGISTER_COM1))
@@ -296,8 +299,6 @@ static void fixup_tables(void)
static int efi_init(void)
{
- barebox_set_model("barebox EFI payload");
-
defaultenv_append_directory(env_efi);
return 0;
diff --git a/common/efi-guid.c b/common/efi-guid.c
index 5109b5d..f6b0404 100644
--- a/common/efi-guid.c
+++ b/common/efi-guid.c
@@ -9,3 +9,76 @@ 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;
+
+#define EFI_GUID_STRING(guid, short, long) do { \
+ if (!efi_guidcmp(guid, *g)) \
+ return long; \
+ } while(0)
+
+const char *efi_guid_string(efi_guid_t *g)
+{
+ EFI_GUID_STRING(EFI_NULL_GUID, "NULL", "NULL GUID");
+ EFI_GUID_STRING(EFI_MPS_TABLE_GUID, "MPS Table", "MPS Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_ACPI_TABLE_GUID, "ACPI Table", "ACPI 1.0 Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_ACPI_20_TABLE_GUID, "ACPI 2.0 Table", "ACPI 2.0 Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_SMBIOS_TABLE_GUID, "SMBIOS Table", "SMBIOS Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_SAL_SYSTEM_TABLE_GUID, "SAL System Table", "SAL System Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_HCDP_TABLE_GUID, "HDCP Table", "HDCP Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_UGA_IO_PROTOCOL_GUID, "UGA Protocol", "EFI 1.1 UGA Protocol");
+ EFI_GUID_STRING(EFI_GLOBAL_VARIABLE_GUID, "Efi", "Efi Variable GUID");
+ EFI_GUID_STRING(EFI_UV_SYSTEM_TABLE_GUID, "SAL System Table", "SAL System Table GUID in EFI System Table");
+ EFI_GUID_STRING(EFI_LINUX_EFI_CRASH_GUID, "Linux EFI Crash", "Linux EFI Crash GUID");
+ EFI_GUID_STRING(EFI_LOADED_IMAGE_PROTOCOL_GUID, "LoadedImage Protocol", "EFI 1.0 Loaded Image Protocol");
+ EFI_GUID_STRING(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, "EFI Graphics Output Protocol", "UEFI Graphics Output Protocol");
+ EFI_GUID_STRING(EFI_UGA_PROTOCOL_GUID, "UGA Draw Protocol", "EFI 1.1 UGA Draw Protocol");
+ EFI_GUID_STRING(EFI_UGA_IO_PROTOCOL_GUID, "UGA Protocol", "EFI 1.1 UGA Protocol");
+ EFI_GUID_STRING(EFI_PCI_IO_PROTOCOL_GUID, "PCI IO Protocol", "EFI 1.1 PCI IO Protocol");
+ EFI_GUID_STRING(EFI_FILE_INFO_GUID, "File Info", "EFI File Infom");
+ EFI_GUID_STRING(EFI_SIMPLE_FILE_SYSTEM_GUID, "Filesystem", "EFI 1.0 Simple FileSystem");
+ EFI_GUID_STRING(EFI_DEVICE_TREE_GUID, "Device Tree", "EFI Device Tree GUID");
+ EFI_GUID_STRING(EFI_DEVICE_PATH_PROTOCOL_GUID, "Device Path Protocol", "EFI 1.0 Device Path protocol");
+ EFI_GUID_STRING(EFI_SIMPLE_NETWORK_PROTOCOL_GUID, "Simple Network Protocol", "EFI 1.0 Simple Network Protocol");
+ EFI_GUID_STRING(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "Filesystem Protocol", "EFI 1.0 Simple FileSystem Protocol");
+ EFI_GUID_STRING(EFI_UNKNOWN_DEVICE_GUID, "Efi Unknown Device", "Efi Unknown Device GUID");
+ EFI_GUID_STRING(EFI_BLOCK_IO_PROTOCOL_GUID, "BlockIo Protocol", "EFI 1.0 Block IO protocol");
+
+ EFI_GUID_STRING(EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID, "FirmwareVolume2Protocol", "Efi FirmwareVolume2Protocol");
+ EFI_GUID_STRING(EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID, "FirmwareVolumeBlock Protocol", "Firmware Volume Block protocol");
+ EFI_GUID_STRING(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID, "PciRootBridgeIo Protocol", "EFI 1.1 Pci Root Bridge IO Protocol");
+ EFI_GUID_STRING(EFI_ISA_ACPI_PROTOCOL_GUID, "ISA Acpi Protocol", "ISA Acpi Protocol");
+ EFI_GUID_STRING(EFI_ISA_IO_PROTOCOL_GUID, "ISA IO Protocol", "ISA IO Protocol");
+ EFI_GUID_STRING(EFI_STANDARD_ERROR_DEVICE_GUID, "Standard Error Device Guid", "EFI Standard Error Device Guid");
+ EFI_GUID_STRING(EFI_CONSOLE_OUT_DEVICE_GUID, "Console Out Device Guid", "EFI Console Out Device Guid");
+ EFI_GUID_STRING(EFI_CONSOLE_IN_DEVICE_GUID, "Console In Device Guid", "EFI Conosle In Device Guid");
+ EFI_GUID_STRING(EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID, "Simple Text Out Protocol", "EFI 1.0 Simple Text Out Protocol");
+ EFI_GUID_STRING(EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID, "Simple Text Input Ex Protocol", "UEFI 2.1 Simple Text Input Ex Protocol");
+ EFI_GUID_STRING(EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID, "Simple Text In Protocol", "EFI 1.0 Simple Text In Protocol");
+ EFI_GUID_STRING(EFI_DISK_IO_PROTOCOL_GUID, "DiskIo Protocol", "EFI 1.0 Disk IO Protocol");
+ EFI_GUID_STRING(EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID, "IDE Controller Init Protocol", "Platform IDE Init Protocol");
+ EFI_GUID_STRING(EFI_DISK_INFO_PROTOCOL_GUID, "Disk Info Protocol", "Disk Info Protocol");
+ EFI_GUID_STRING(EFI_SERIAL_IO_PROTOCOL_GUID, "SerialIo Protocol", "EFI 1.0 Serial IO Protocol");
+ EFI_GUID_STRING(EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID, "Bus Specific Driver Override Protocol", "EFI 1.1 Bus Specific Driver Override Protocol");
+ EFI_GUID_STRING(EFI_LOAD_FILE2_PROTOCOL_GUID, "LoadFile2 Protocol", "EFI Load File 2 Protocol");
+ EFI_GUID_STRING(EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID, "MTFTP4 Service Binding Protocol", "MTFTP4 Service Binding Protocol");
+ EFI_GUID_STRING(EFI_DHCP4_PROTOCOL_GUID, "DHCP4 Protocol", "DHCP4 Protocol");
+ EFI_GUID_STRING(EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID, "UDP4 Service Binding Protocol", "UDP4 Service Binding Protocol");
+ EFI_GUID_STRING(EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, "TCP4 Service Binding Protocol", "TCP4 Service Binding Protocol");
+ EFI_GUID_STRING(EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID, "IP4 Service Binding Protocol", "IP4 Service Binding Protocol");
+ EFI_GUID_STRING(EFI_IP4_CONFIG_PROTOCOL_GUID, "Ip4Config Protocol", "Ip4Config Protocol");
+ EFI_GUID_STRING(EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID, "ARP Service Binding Protocol", "ARP Service Binding Protocol");
+ EFI_GUID_STRING(EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID, "Managed Network Service Binding Protocol", "Managed Network Service Binding Protocol");
+ EFI_GUID_STRING(EFI_VLAN_CONFIG_PROTOCOL_GUID, "VlanConfig Protocol", "VlanConfig Protocol");
+ EFI_GUID_STRING(EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID, "HII Config Access Protocol", "HII Config Access 2.1 protocol");
+ EFI_GUID_STRING(LOAD_FILE_PROTOCOL_GUID, "LoadFile Protocol", "EFI 1.0 Load File Protocol");
+ EFI_GUID_STRING(EFI_COMPONENT_NAME2_PROTOCOL_GUID, "Component Name2 Protocol", "UEFI 2.0 Component Name2 Protocol");
+ EFI_GUID_STRING(EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31, "Network Interface Identifier Protocol_31", "EFI1.1 Network Interface Identifier Protocol");
+ EFI_GUID_STRING(EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID, "Network Interface Identifier Protocol", "EFI Network Interface Identifier Protocol");
+
+ /* File */
+ EFI_GUID_STRING(EFI_IDEBUSDXE_INF_GUID, "IdeBusDxe.inf", "EFI IdeBusDxe.inf File GUID");
+ EFI_GUID_STRING(EFI_TERMINALDXE_INF_GUID, "TerminalDxe.inf", "EFI TerminalDxe.inf File GUID");
+ EFI_GUID_STRING(EFI_ISCSIDXE_INF_GUID, "IScsiDxe.inf", "EFI IScsiDxe.inf File GUID");
+ EFI_GUID_STRING(EFI_VLANCONFIGDXE_INF_GUID, "VlanConfigDxe.inf", "EFI VlanConfigDxe.inf File GUID");
+
+ return "unknown";
+}
diff --git a/include/efi.h b/include/efi.h
index c624eb3..597dc74 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -354,6 +354,112 @@ extern efi_runtime_services_t *RT;
#define EFI_BLOCK_IO_PROTOCOL_GUID \
EFI_GUID(0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+/* additional GUID from EDK2 */
+#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \
+ EFI_GUID(0x220e73b6, 0x6bdb, 0x4413, 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a)
+
+#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \
+ EFI_GUID(0x8f644fa9, 0xe850, 0x4db1, 0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4)
+
+#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \
+ EFI_GUID(0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define EFI_ISA_ACPI_PROTOCOL_GUID \
+ EFI_GUID(0x64a892dc, 0x5561, 0x4536, 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55)
+
+#define EFI_ISA_IO_PROTOCOL_GUID \
+ EFI_GUID(0x7ee2bd44, 0x3da0, 0x11d4, 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define EFI_STANDARD_ERROR_DEVICE_GUID \
+ EFI_GUID(0xd3b36f2d, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define EFI_CONSOLE_OUT_DEVICE_GUID \
+ EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define EFI_CONSOLE_IN_DEVICE_GUID \
+ EFI_GUID(0xd3b36f2b, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID \
+ EFI_GUID(0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+ EFI_GUID(0xdd9e7534, 0x7762, 0x4698, 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa)
+
+#define EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID \
+ EFI_GUID(0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_DISK_IO_PROTOCOL_GUID \
+ EFI_GUID(0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \
+ EFI_GUID(0xa1e37052, 0x80d9, 0x4e65, 0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9)
+
+#define EFI_DISK_INFO_PROTOCOL_GUID \
+ EFI_GUID(0xd432a67f, 0x14dc, 0x484b, 0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27)
+
+#define EFI_SERIAL_IO_PROTOCOL_GUID \
+ EFI_GUID(0xbb25cf6f, 0xf1d4, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd)
+
+#define EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID \
+ EFI_GUID(0x3bc1b285, 0x8a15, 0x4a82, 0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65)
+
+#define EFI_LOAD_FILE2_PROTOCOL_GUID \
+ EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
+
+#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x2fe800be, 0x8f01, 0x4aa6, 0x94, 0x6b, 0xd7, 0x13, 0x88, 0xe1, 0x83, 0x3f)
+
+#define EFI_DHCP4_PROTOCOL_GUID \
+ EFI_GUID(0x9d9a39d8, 0xbd42, 0x4a73, 0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80)
+
+#define EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x83f01464, 0x99bd, 0x45e5, 0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6)
+
+#define EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x00720665, 0x67EB, 0x4a99, 0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9)
+
+#define EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0xc51711e7, 0xb4bf, 0x404a, 0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4)
+
+#define EFI_IP4_CONFIG_PROTOCOL_GUID \
+ EFI_GUID(0x3b95aa31, 0x3793, 0x434b, 0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e)
+
+#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID\
+ EFI_GUID(0xf44c00ee, 0x1f2c, 0x4a00, 0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3)
+
+#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0xf36ff770, 0xa7e1, 0x42cf, 0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c)
+
+#define EFI_VLAN_CONFIG_PROTOCOL_GUID \
+ EFI_GUID(0x9e23d768, 0xd2f3, 0x4366, 0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74)
+
+#define EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID \
+ EFI_GUID(0x330d4706, 0xf2a0, 0x4e4f, 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85)
+
+#define LOAD_FILE_PROTOCOL_GUID \
+ EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \
+ EFI_GUID(0x6a7a5cff, 0xe8d9, 0x4f70, 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14)
+
+#define EFI_IDEBUSDXE_INF_GUID \
+ EFI_GUID(0x69fd8e47, 0xa161, 0x4550, 0xb0, 0x1a, 0x55, 0x94, 0xce, 0xb2, 0xb2, 0xb2)
+
+#define EFI_TERMINALDXE_INF_GUID \
+ EFI_GUID(0x9e863906, 0xa40f, 0x4875, 0x97, 0x7f, 0x5b, 0x93, 0xff, 0x23, 0x7f, 0xc6)
+
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31 \
+ EFI_GUID(0x1aced566, 0x76ed, 0x4218, 0xbc, 0x81, 0x76, 0x7f, 0x1f, 0x97, 0x7a, 0x89)
+
+#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID \
+ EFI_GUID(0xe18541cd, 0xf755, 0x4f73, 0x92, 0x8d, 0x64, 0x3c, 0x8a, 0x79, 0xb2, 0x29)
+
+#define EFI_ISCSIDXE_INF_GUID \
+ EFI_GUID(0x4579b72d, 0x7ec4, 0x4dd4, 0x84, 0x86, 0x08, 0x3c, 0x86, 0xb1, 0x82, 0xa7)
+
+#define EFI_VLANCONFIGDXE_INF_GUID \
+ EFI_GUID(0xe4f61863, 0xfe2c, 0x4b56, 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf)
+
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;
@@ -505,4 +611,6 @@ static inline int efi_compare_guid(efi_guid_t *a, efi_guid_t *b)
char *device_path_to_str(struct efi_device_path *dev_path);
+const char *efi_guid_string(efi_guid_t *g);
+
#endif /* _LINUX_EFI_H */
--
2.0.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-07-11 7:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-11 7:36 [PATCH v2] Initial EFI support Sascha Hauer
2014-07-11 7:36 ` [PATCH 1/7] Documentation: Add EFI documentation Sascha Hauer
2014-07-11 7:36 ` [PATCH 3/7] net: Add EFI Simple Network Protocol Driver Sascha Hauer
2014-07-11 7:36 ` [PATCH 4/7] serial: Add EFI stdio driver Sascha Hauer
2014-07-11 7:36 ` [PATCH 5/7] fs: implement EFI filesystem driver Sascha Hauer
2014-07-11 7:36 ` [PATCH 6/7] fs: implement EFI variable " Sascha Hauer
2014-07-11 7:36 ` [PATCH 7/7] EFI: introduce efi_strguid to convert GUID to human readable names Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox