mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* Initial EFI Support
@ 2014-07-08  8:49 Sascha Hauer
  2014-07-08  8:49 ` [PATCH 01/21] Make IPaddr_t a 32bit type Sascha Hauer
                   ` (23 more replies)
  0 siblings, 24 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:49 UTC (permalink / raw)
  To: barebox

The following adds initial support for running barebox as an EFI
payload on X86 PCs.

Several things are implemented already to make it useful and
to look around in an EFI system:

- Simple Network Protocol for networking
- Start applications for installing drivers and starting Linux
- Access EFI provided filesystems
- Block device access

The EFI Port still has some rough edges. The screen output is limited
to 80x25 and the keyboard driver doesn't recognize ctrl-C. I couldn't
get find a proper UEFI serial driver yet, so the serial port is accessed
via inb/outb on ioport 0x3f8 and not via UEFI.

For those interested in EFI and X86 hardware this port still offers
some interesting insights in EFI.

There's also even Documentation available, see Patch 16/21.

Sascha

----------------------------------------------------------------
Sascha Hauer (21):
      Make IPaddr_t a 32bit type
      oftree command: Use size_t for size
      fat: Use correct format specifier
      readkey: keys are unsugned char
      of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources
      console: Add puts callback to console devices
      Add hex_byte_pack and hex_byte_pack_upper from kernel
      vsprintf: Support pU for printing UUIDs
      Add beginning wchar support
      block: Add flush callback
      Move efi.h to include/
      filetype: Add DOS EXE file detection support
      efi: Add more error codes
      serial: ns16550: Add mmiobase to private data
      serial: ns16550: Add register read/write function pointers to private data
      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

 Documentation/boards/efi.rst               |  279 ++++++
 Documentation/glossary.rst                 |    3 +
 arch/efi/Kconfig                           |   47 +
 arch/efi/Makefile                          |   41 +
 arch/efi/configs/efi_defconfig             |   73 ++
 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                  |  348 +++++++
 arch/efi/efi/efi-image.c                   |  105 +++
 arch/efi/efi/efi.c                         |  342 +++++++
 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 +-
 commands/oftree.c                          |    2 +-
 common/Kconfig                             |    8 +
 common/Makefile                            |    4 +-
 common/block.c                             |    3 +
 common/console.c                           |   29 +
 common/efi-devicepath.c                    | 1370 ++++++++++++++++++++++++++++
 common/efi-guid.c                          |   11 +
 common/filetype.c                          |    4 +
 common/memory.c                            |    2 +-
 common/partitions/efi.c                    |    2 +-
 common/partitions/efi.h                    |    2 +-
 drivers/net/Kconfig                        |    4 +
 drivers/net/Makefile                       |    1 +
 drivers/net/efi-snp.c                      |  296 ++++++
 drivers/of/Kconfig                         |    2 +-
 drivers/of/platform.c                      |    3 +-
 drivers/serial/Kconfig                     |    4 +
 drivers/serial/Makefile                    |    1 +
 drivers/serial/efi-stdio.c                 |  367 ++++++++
 drivers/serial/serial_ns16550.c            |  237 ++---
 fs/Kconfig                                 |   15 +
 fs/Makefile                                |    2 +
 fs/efi.c                                   |  559 ++++++++++++
 fs/efivarfs.c                              |  340 +++++++
 fs/fat/fat.c                               |    4 +-
 include/block.h                            |    1 +
 include/console.h                          |    1 +
 include/efi.h                              |  508 +++++++++++
 include/filetype.h                         |    1 +
 include/linux/efi.h                        |  547 -----------
 include/linux/kernel.h                     |   23 +-
 include/param.h                            |    2 +-
 include/wchar.h                            |   16 +
 lib/Kconfig                                |    3 +
 lib/Makefile                               |    1 +
 lib/misc.c                                 |    3 +
 lib/readkey.c                              |    2 +-
 lib/vsprintf.c                             |   62 ++
 lib/wchar.c                                |   80 ++
 76 files changed, 6319 insertions(+), 676 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
 create mode 100644 include/efi.h
 delete mode 100644 include/linux/efi.h
 create mode 100644 include/wchar.h
 create mode 100644 lib/wchar.c


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 01/21] Make IPaddr_t a 32bit type
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
@ 2014-07-08  8:49 ` Sascha Hauer
  2014-07-08  8:49 ` [PATCH 02/21] oftree command: Use size_t for size Sascha Hauer
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:49 UTC (permalink / raw)
  To: barebox

unsigned long is 64bit wide on some architectures. Make IPaddr_t a
typedef to uint32_t to make sure it's 32bit wide.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/param.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/param.h b/include/param.h
index 24827c5..8f200df 100644
--- a/include/param.h
+++ b/include/param.h
@@ -7,7 +7,7 @@
 #define PARAM_FLAG_RO	(1 << 0)
 
 struct device_d;
-typedef unsigned long          IPaddr_t;
+typedef uint32_t          IPaddr_t;
 
 struct param_d {
 	const char* (*get)(struct device_d *, struct param_d *param);
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 02/21] oftree command: Use size_t for size
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
  2014-07-08  8:49 ` [PATCH 01/21] Make IPaddr_t a 32bit type Sascha Hauer
@ 2014-07-08  8:49 ` Sascha Hauer
  2014-07-08  8:49 ` [PATCH 03/21] fat: Use correct format specifier Sascha Hauer
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:49 UTC (permalink / raw)
  To: barebox

read_file takes a size_t argument as size, so use this type for the
size variable.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/oftree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/commands/oftree.c b/commands/oftree.c
index 983a0a5..49976bc 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -42,7 +42,7 @@
 static int do_oftree(int argc, char *argv[])
 {
 	struct fdt_header *fdt = NULL;
-	int size;
+	size_t size;
 	int opt;
 	int probe = 0;
 	char *load = NULL;
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 03/21] fat: Use correct format specifier
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
  2014-07-08  8:49 ` [PATCH 01/21] Make IPaddr_t a 32bit type Sascha Hauer
  2014-07-08  8:49 ` [PATCH 02/21] oftree command: Use size_t for size Sascha Hauer
@ 2014-07-08  8:49 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 04/21] readkey: keys are unsugned char Sascha Hauer
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:49 UTC (permalink / raw)
  To: barebox

Use %zd to print size_t arguments.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fat/fat.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index e65ef58..f8094d0 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -167,7 +167,7 @@ static int fat_write(struct device_d *_dev, FILE *f, const void *buf, size_t ins
 
 	ret = f_write(f_file, buf, insize, &outsize);
 
-	debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);
+	debug("%s: %d %zd %d %p\n", __func__, ret, insize, outsize, f_file);
 
 	if (ret)
 		return ret;
@@ -260,7 +260,7 @@ static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
 
 	ret = f_read(f_file, buf, insize, &outsize);
 
-	debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);
+	debug("%s: %d %zd %d %p\n", __func__, ret, insize, outsize, f_file);
 
 	if (ret)
 		return ret;
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 04/21] readkey: keys are unsugned char
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (2 preceding siblings ...)
  2014-07-08  8:49 ` [PATCH 03/21] fat: Use correct format specifier Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 05/21] of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources Sascha Hauer
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

We have keys with values > 127, so it must be an unsigned char.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 lib/readkey.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/readkey.c b/lib/readkey.c
index 7b38110..2073a73 100644
--- a/lib/readkey.c
+++ b/lib/readkey.c
@@ -25,7 +25,7 @@
 
 struct esc_cmds {
 	const char *seq;
-	char val;
+	unsigned char val;
 };
 
 static const struct esc_cmds esccmds[] = {
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 05/21] of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (3 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 04/21] readkey: keys are unsugned char Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 06/21] console: Add puts callback to console devices Sascha Hauer
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Avoids compiler warnings about wrong format specifiers

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 72e75cc..c417cfd 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -183,7 +183,8 @@ static struct device_d *of_platform_device_create(struct device_node *np,
 	dev->num_resources = num_reg;
 	of_device_make_bus_id(dev);
 
-	debug("%s: register device %s, io=0x%08x\n", __func__, dev_name(dev),
+	debug("%s: register device %s, io=" PRINTF_CONVERSION_RESOURCE "\n",
+			__func__, dev_name(dev),
 		(num_reg) ? dev->resource[0].start : (-1));
 
 	ret = platform_device_register(dev);
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 06/21] console: Add puts callback to console devices
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (4 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 05/21] of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 07/21] Add hex_byte_pack and hex_byte_pack_upper from kernel Sascha Hauer
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Some devices may have a much more efficient way to output strings
rather than single characters. Let console devices implement a
callback for this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/console.c  | 29 +++++++++++++++++++++++++++++
 include/console.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/common/console.c b/common/console.c
index aa9e3ce..b319835 100644
--- a/common/console.c
+++ b/common/console.c
@@ -162,6 +162,22 @@ static void console_set_stdoutpath(struct console_device *cdev)
 	free(str);
 }
 
+static int __console_puts(struct console_device *cdev, const char *s)
+{
+	int n = 0;
+
+	while (*s) {
+		if (*s == '\n') {
+			cdev->putc(cdev, '\r');
+			n++;
+		}
+		cdev->putc(cdev, *s);
+		n++;
+		s++;
+	}
+	return n;
+}
+
 int console_register(struct console_device *newcdev)
 {
 	struct device_d *dev = &newcdev->class_dev;
@@ -182,6 +198,9 @@ int console_register(struct console_device *newcdev)
 			NULL, &newcdev->baudrate, "%u", newcdev);
 	}
 
+	if (newcdev->putc && !newcdev->puts)
+		newcdev->puts = __console_puts;
+
 	dev_add_param(dev, "active", console_std_set, NULL, 0);
 
 	if (IS_ENABLED(CONFIG_CONSOLE_ACTIVATE_FIRST)) {
@@ -342,9 +361,19 @@ EXPORT_SYMBOL(console_putc);
 
 int console_puts(unsigned int ch, const char *str)
 {
+	struct console_device *cdev;
 	const char *s = str;
 	int n = 0;
 
+	if (initialized == CONSOLE_INIT_FULL) {
+		for_each_console(cdev) {
+			if (cdev->f_active & ch) {
+				n = cdev->puts(cdev, str);
+			}
+		}
+		return n;
+	}
+
 	while (*s) {
 		if (*s == '\n') {
 			console_putc(ch, '\r');
diff --git a/include/console.h b/include/console.h
index 6da0199..6372cfe 100644
--- a/include/console.h
+++ b/include/console.h
@@ -39,6 +39,7 @@ struct console_device {
 
 	int (*tstc)(struct console_device *cdev);
 	void (*putc)(struct console_device *cdev, char c);
+	int (*puts)(struct console_device *cdev, const char *s);
 	int  (*getc)(struct console_device *cdev);
 	int (*setbrg)(struct console_device *cdev, int baudrate);
 	void (*flush)(struct console_device *cdev);
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 07/21] Add hex_byte_pack and hex_byte_pack_upper from kernel
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (5 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 06/21] console: Add puts callback to console devices Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 08/21] vsprintf: Support pU for printing UUIDs Sascha Hauer
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Utility functions needed by the UUID/GUID printf support.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/kernel.h | 23 ++++++++++++++++++++++-
 lib/misc.c             |  2 ++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4322f01..c5ba99f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -117,5 +117,26 @@
 }							\
 )
 
-#endif /* _LINUX_KERNEL_H */
+extern const char hex_asc[];
+#define hex_asc_lo(x)	hex_asc[((x) & 0x0f)]
+#define hex_asc_hi(x)	hex_asc[((x) & 0xf0) >> 4]
+
+static inline char *hex_byte_pack(char *buf, u8 byte)
+{
+	*buf++ = hex_asc_hi(byte);
+	*buf++ = hex_asc_lo(byte);
+	return buf;
+}
+
+extern const char hex_asc_upper[];
+#define hex_asc_upper_lo(x)	hex_asc_upper[((x) & 0x0f)]
+#define hex_asc_upper_hi(x)	hex_asc_upper[((x) & 0xf0) >> 4]
 
+static inline char *hex_byte_pack_upper(char *buf, u8 byte)
+{
+	*buf++ = hex_asc_upper_hi(byte);
+	*buf++ = hex_asc_upper_lo(byte);
+	return buf;
+}
+
+#endif /* _LINUX_KERNEL_H */
diff --git a/lib/misc.c b/lib/misc.c
index 0f3eb9a..9f2067c 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -113,3 +113,5 @@ int parse_area_spec(const char *str, loff_t *start, loff_t *size)
 	return -1;
 }
 EXPORT_SYMBOL(parse_area_spec);
+
+const char hex_asc[] = "0123456789abcdef";
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 08/21] vsprintf: Support pU for printing UUIDs
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (6 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 07/21] Add hex_byte_pack and hex_byte_pack_upper from kernel Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 09/21] Add beginning wchar support Sascha Hauer
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

With EFI 16byte UUIDs/GUIDs are common. Add support for printing them.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 lib/Kconfig    |  3 +++
 lib/vsprintf.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/lib/Kconfig b/lib/Kconfig
index d9ad4aa..09a1674 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -54,4 +54,7 @@ source lib/gui/Kconfig
 
 source lib/bootstrap/Kconfig
 
+config PRINTF_UUID
+	bool
+
 endmenu
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 066338b..512c882 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -253,6 +253,53 @@ static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int
 #endif
 }
 
+static noinline_for_stack
+char *uuid_string(char *buf, char *end, const u8 *addr, int field_width,
+		int precision, int flags, const char *fmt)
+{
+	char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+	char *p = uuid;
+	int i;
+	static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+	static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
+	const u8 *index = be;
+	bool uc = false;
+
+	switch (*(++fmt)) {
+	case 'L':
+		uc = true;		/* fall-through */
+	case 'l':
+		index = le;
+		break;
+	case 'B':
+		uc = true;
+		break;
+	}
+
+	for (i = 0; i < 16; i++) {
+		p = hex_byte_pack(p, addr[index[i]]);
+		switch (i) {
+		case 3:
+		case 5:
+		case 7:
+		case 9:
+			*p++ = '-';
+			break;
+		}
+	}
+
+	*p = 0;
+
+	if (uc) {
+		p = uuid;
+		do {
+			*p = toupper(*p);
+		} while (*(++p));
+	}
+
+	return string(buf, end, uuid, field_width, precision, flags);
+}
+
 /*
  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  * by an extra set of alphanumeric characters that are extended format
@@ -261,6 +308,17 @@ static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int
  * Right now we handle:
  *
  * - 'S' For symbolic direct pointers
+ * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
+ *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ *       Options for %pU are:
+ *         b big endian lower case hex (default)
+ *         B big endian UPPER case hex
+ *         l little endian lower case hex
+ *         L little endian UPPER case hex
+ *           big endian output byte order is:
+ *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
+ *           little endian output byte order is:
+ *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
  *
  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  * function pointers are really function descriptors, which contain a
@@ -271,6 +329,10 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
 	switch (*fmt) {
 	case 'S':
 		return symbol_string(buf, end, ptr, field_width, precision, flags);
+	case 'U':
+		if (IS_ENABLED(CONFIG_PRINTF_UUID))
+			return uuid_string(buf, end, ptr, field_width, precision, flags, fmt);
+		break;
 	}
 	flags |= SMALL;
 	if (field_width == -1) {
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 09/21] Add beginning wchar support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (7 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 08/21] vsprintf: Support pU for printing UUIDs Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-11 12:35   ` Antony Pavlov
  2014-07-08  8:50 ` [PATCH 10/21] block: Add flush callback Sascha Hauer
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

EFI uses 16 bit character strings. Add beginning support for this.
Since barebox uses 8 bit strings internally we need conversion functions
to convert between 16 bit and 8 bit strings.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/wchar.h | 16 ++++++++++++
 lib/Makefile    |  1 +
 lib/misc.c      |  1 +
 lib/wchar.c     | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+)
 create mode 100644 include/wchar.h
 create mode 100644 lib/wchar.c

diff --git a/include/wchar.h b/include/wchar.h
new file mode 100644
index 0000000..278a189
--- /dev/null
+++ b/include/wchar.h
@@ -0,0 +1,16 @@
+#ifndef __WCHAR_H
+#define __WCHAR_H
+
+#include <linux/types.h>
+
+typedef u16 wchar_t;
+
+char *strcpy_wchar_to_char(char *dst, const wchar_t *src);
+
+wchar_t *strcpy_char_to_wchar(wchar_t *dst, const char *src);
+
+wchar_t *strdup_char_to_wchar(const char *src);
+
+char *strdup_wchar_to_char(const wchar_t *src);
+
+#endif /* __WCHAR_H */
diff --git a/lib/Makefile b/lib/Makefile
index e8769a9..48c953d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,3 +44,4 @@ obj-y			+= gui/
 obj-$(CONFIG_XYMODEM)	+= xymodem.o
 obj-y			+= unlink-recursive.o
 obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
+obj-y			+= wchar.o
diff --git a/lib/misc.c b/lib/misc.c
index 9f2067c..87626c1 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -21,6 +21,7 @@
 #include <malloc.h>
 #include <errno.h>
 #include <fs.h>
+#include <string.h>
 #include <linux/ctype.h>
 
 /*
diff --git a/lib/wchar.c b/lib/wchar.c
new file mode 100644
index 0000000..6368a01
--- /dev/null
+++ b/lib/wchar.c
@@ -0,0 +1,80 @@
+/*
+ * wchar.c - wide character 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 <wchar.h>
+#include <malloc.h>
+#include <string.h>
+
+size_t wcslen(const wchar_t *s)
+{
+	size_t len = 0;
+
+	while (*s++)
+		len++;
+
+	return len;
+}
+
+char *strcpy_wchar_to_char(char *dst, const wchar_t *src)
+{
+	char *ret = dst;
+
+	while (*src)
+		*dst++ = *src++ & 0xff;
+
+	*dst = 0;
+
+	return ret;
+}
+
+wchar_t *strcpy_char_to_wchar(wchar_t *dst, const char *src)
+{
+	wchar_t *ret = dst;
+
+	while (*src)
+		*dst++ = *src++;
+
+	*dst = 0;
+
+	return ret;
+}
+
+wchar_t *strdup_char_to_wchar(const char *src)
+{
+	wchar_t *dst = malloc((strlen(src) + 1) * sizeof(wchar_t));
+
+	if (!dst)
+		return NULL;
+
+	strcpy_char_to_wchar(dst, src);
+
+	return dst;
+}
+
+char *strdup_wchar_to_char(const wchar_t *src)
+{
+	char *dst = malloc((wcslen(src) + 1));
+
+	if (!dst)
+		return NULL;
+
+	strcpy_wchar_to_char(dst, src);
+
+	return dst;
+}
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 10/21] block: Add flush callback
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (8 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 09/21] Add beginning wchar support Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 11/21] Move efi.h to include/ Sascha Hauer
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Some block devices need an explicit callback for flushing written
blocks. Add this callback.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/block.c  | 3 +++
 include/block.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/common/block.c b/common/block.c
index e522ee4..0edc861 100644
--- a/common/block.c
+++ b/common/block.c
@@ -55,6 +55,9 @@ static int writebuffer_flush(struct block_device *blk)
 		}
 	}
 
+	if (blk->ops->flush)
+		return blk->ops->flush(blk);
+
 	return 0;
 }
 
diff --git a/include/block.h b/include/block.h
index 872a4c1..9137767 100644
--- a/include/block.h
+++ b/include/block.h
@@ -9,6 +9,7 @@ struct block_device;
 struct block_device_ops {
 	int (*read)(struct block_device *, void *buf, int block, int num_blocks);
 	int (*write)(struct block_device *, const void *buf, int block, int num_blocks);
+	int (*flush)(struct block_device *);
 };
 
 struct chunk;
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 11/21] Move efi.h to include/
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (9 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 10/21] block: Add flush callback Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 12/21] filetype: Add DOS EXE file detection support Sascha Hauer
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

With upcoming EFI payload support the efi.h file will diverge
from the kernel, so move it from include/linux/ to include/

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/partitions/efi.h |   2 +-
 include/efi.h           | 547 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/efi.h     | 547 ------------------------------------------------
 3 files changed, 548 insertions(+), 548 deletions(-)
 create mode 100644 include/efi.h
 delete mode 100644 include/linux/efi.h

diff --git a/common/partitions/efi.h b/common/partitions/efi.h
index 703ecca..a9b10c1 100644
--- a/common/partitions/efi.h
+++ b/common/partitions/efi.h
@@ -21,7 +21,7 @@
 #ifndef FS_PART_EFI_H_INCLUDED
 #define FS_PART_EFI_H_INCLUDED
 
-#include <linux/efi.h>
+#include <efi.h>
 
 #define MSDOS_MBR_SIGNATURE 0xaa55
 #define EFI_PMBR_OSTYPE_EFI 0xEF
diff --git a/include/efi.h b/include/efi.h
new file mode 100644
index 0000000..570eff7
--- /dev/null
+++ b/include/efi.h
@@ -0,0 +1,547 @@
+#ifndef _LINUX_EFI_H
+#define _LINUX_EFI_H
+
+/*
+ * Extensible Firmware Interface
+ * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999, 2002-2003 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ */
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define EFI_SUCCESS		0
+#define EFI_LOAD_ERROR          ( 1 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_INVALID_PARAMETER	( 2 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_UNSUPPORTED		( 3 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_BAD_BUFFER_SIZE     ( 4 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_BUFFER_TOO_SMALL	( 5 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NOT_FOUND		(14 | (1UL << (BITS_PER_LONG-1)))
+
+typedef unsigned long efi_status_t;
+typedef u8 efi_bool_t;
+typedef u16 efi_char16_t;		/* UNICODE character */
+
+
+typedef struct {
+	u8 b[16];
+} efi_guid_t;
+
+#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, \
+  (c) & 0xff, ((c) >> 8) & 0xff, \
+  (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
+/*
+ * Generic EFI table header
+ */
+typedef	struct {
+	u64 signature;
+	u32 revision;
+	u32 headersize;
+	u32 crc32;
+	u32 reserved;
+} efi_table_hdr_t;
+
+/*
+ * Memory map descriptor:
+ */
+
+/* Memory types: */
+#define EFI_RESERVED_TYPE		 0
+#define EFI_LOADER_CODE			 1
+#define EFI_LOADER_DATA			 2
+#define EFI_BOOT_SERVICES_CODE		 3
+#define EFI_BOOT_SERVICES_DATA		 4
+#define EFI_RUNTIME_SERVICES_CODE	 5
+#define EFI_RUNTIME_SERVICES_DATA	 6
+#define EFI_CONVENTIONAL_MEMORY		 7
+#define EFI_UNUSABLE_MEMORY		 8
+#define EFI_ACPI_RECLAIM_MEMORY		 9
+#define EFI_ACPI_MEMORY_NVS		10
+#define EFI_MEMORY_MAPPED_IO		11
+#define EFI_MEMORY_MAPPED_IO_PORT_SPACE	12
+#define EFI_PAL_CODE			13
+#define EFI_MAX_MEMORY_TYPE		14
+
+/* Attribute values: */
+#define EFI_MEMORY_UC		((u64)0x0000000000000001ULL)	/* uncached */
+#define EFI_MEMORY_WC		((u64)0x0000000000000002ULL)	/* write-coalescing */
+#define EFI_MEMORY_WT		((u64)0x0000000000000004ULL)	/* write-through */
+#define EFI_MEMORY_WB		((u64)0x0000000000000008ULL)	/* write-back */
+#define EFI_MEMORY_WP		((u64)0x0000000000001000ULL)	/* write-protect */
+#define EFI_MEMORY_RP		((u64)0x0000000000002000ULL)	/* read-protect */
+#define EFI_MEMORY_XP		((u64)0x0000000000004000ULL)	/* execute-protect */
+#define EFI_MEMORY_RUNTIME	((u64)0x8000000000000000ULL)	/* range requires runtime mapping */
+#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;
+
+/*
+ * Allocation types for calls to boottime->allocate_pages.
+ */
+#define EFI_ALLOCATE_ANY_PAGES		0
+#define EFI_ALLOCATE_MAX_ADDRESS	1
+#define EFI_ALLOCATE_ADDRESS		2
+#define EFI_MAX_ALLOCATE_TYPE		3
+
+typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
+
+/*
+ * Types and defines for Time Services
+ */
+#define EFI_TIME_ADJUST_DAYLIGHT 0x1
+#define EFI_TIME_IN_DAYLIGHT     0x2
+#define EFI_UNSPECIFIED_TIMEZONE 0x07ff
+
+typedef struct {
+	u16 year;
+	u8 month;
+	u8 day;
+	u8 hour;
+	u8 minute;
+	u8 second;
+	u8 pad1;
+	u32 nanosecond;
+	s16 timezone;
+	u8 daylight;
+	u8 pad2;
+} efi_time_t;
+
+typedef struct {
+	u32 resolution;
+	u32 accuracy;
+	u8 sets_to_zero;
+} efi_time_cap_t;
+
+/*
+ * EFI Boot Services table
+ */
+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;
+	void *create_event;
+	void *set_timer;
+	void *wait_for_event;
+	void *signal_event;
+	void *close_event;
+	void *check_event;
+	void *install_protocol_interface;
+	void *reinstall_protocol_interface;
+	void *uninstall_protocol_interface;
+	void *handle_protocol;
+	void *__reserved;
+	void *register_protocol_notify;
+	void *locate_handle;
+	void *locate_device_path;
+	void *install_configuration_table;
+	void *load_image;
+	void *start_image;
+	void *exit;
+	void *unload_image;
+	void *exit_boot_services;
+	void *get_next_monotonic_count;
+	void *stall;
+	void *set_watchdog_timer;
+	void *connect_controller;
+	void *disconnect_controller;
+	void *open_protocol;
+	void *close_protocol;
+	void *open_protocol_information;
+	void *protocols_per_handle;
+	void *locate_handle_buffer;
+	void *locate_protocol;
+	void *install_multiple_protocol_interfaces;
+	void *uninstall_multiple_protocol_interfaces;
+	void *calculate_crc32;
+	void *copy_mem;
+	void *set_mem;
+	void *create_event_ex;
+} efi_boot_services_t;
+
+/*
+ * Types and defines for EFI ResetSystem
+ */
+#define EFI_RESET_COLD 0
+#define EFI_RESET_WARM 1
+#define EFI_RESET_SHUTDOWN 2
+
+/*
+ * EFI Runtime Services table
+ */
+#define EFI_RUNTIME_SERVICES_SIGNATURE ((u64)0x5652453544e5552ULL)
+#define EFI_RUNTIME_SERVICES_REVISION  0x00010000
+
+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;
+} 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);
+
+/*
+ *  EFI Configuration Table and GUID definitions
+ */
+#define NULL_GUID \
+    EFI_GUID(  0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
+
+#define MPS_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define ACPI_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define ACPI_20_TABLE_GUID    \
+    EFI_GUID(  0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
+
+#define SMBIOS_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define SAL_SYSTEM_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define HCDP_TABLE_GUID	\
+    EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
+
+#define 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 \
+    EFI_GUID(  0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
+
+#define LINUX_EFI_CRASH_GUID \
+    EFI_GUID(  0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 )
+
+#define LOADED_IMAGE_PROTOCOL_GUID \
+    EFI_GUID(  0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+    EFI_GUID(  0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a )
+
+#define EFI_UGA_PROTOCOL_GUID \
+    EFI_GUID(  0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 )
+
+#define EFI_PCI_IO_PROTOCOL_GUID \
+    EFI_GUID(  0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a )
+
+#define EFI_FILE_INFO_ID \
+    EFI_GUID(  0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
+
+#define EFI_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;
+
+typedef struct {
+	efi_guid_t guid;
+	u32 table;
+} efi_config_table_32_t;
+
+typedef struct {
+	efi_guid_t guid;
+	unsigned long table;
+} efi_config_table_t;
+
+#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
+
+#define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
+
+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;
+	unsigned long con_out_handle;
+	unsigned long con_out;
+	unsigned long stderr_handle;
+	unsigned long _stderr;
+	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;
+	efi_system_table_t *system_table;
+	void *device_handle;
+	void *file_path;
+	void *reserved;
+	u32 load_options_size;
+	void *load_options;
+	void *image_base;
+	__aligned_u64 image_size;
+	unsigned int image_code_type;
+	unsigned int image_data_type;
+	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
+ */
+#define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
+#define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020
+#define EFI_VARIABLE_APPEND_WRITE	0x0000000000000040
+
+#define EFI_VARIABLE_MASK 	(EFI_VARIABLE_NON_VOLATILE | \
+				EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+				EFI_VARIABLE_RUNTIME_ACCESS | \
+				EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
+				EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
+				EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
+				EFI_VARIABLE_APPEND_WRITE)
+/*
+ * The type of search to perform when calling boottime->locate_handle
+ */
+#define EFI_LOCATE_ALL_HANDLES			0
+#define EFI_LOCATE_BY_REGISTER_NOTIFY		1
+#define EFI_LOCATE_BY_PROTOCOL			2
+
+/*
+ * 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
+
+#endif /* _LINUX_EFI_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
deleted file mode 100644
index 570eff7..0000000
--- a/include/linux/efi.h
+++ /dev/null
@@ -1,547 +0,0 @@
-#ifndef _LINUX_EFI_H
-#define _LINUX_EFI_H
-
-/*
- * Extensible Firmware Interface
- * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999, 2002-2003 Hewlett-Packard Co.
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *	Stephane Eranian <eranian@hpl.hp.com>
- */
-#include <linux/string.h>
-#include <linux/types.h>
-
-#define EFI_SUCCESS		0
-#define EFI_LOAD_ERROR          ( 1 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_INVALID_PARAMETER	( 2 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_UNSUPPORTED		( 3 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_BAD_BUFFER_SIZE     ( 4 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_BUFFER_TOO_SMALL	( 5 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_NOT_FOUND		(14 | (1UL << (BITS_PER_LONG-1)))
-
-typedef unsigned long efi_status_t;
-typedef u8 efi_bool_t;
-typedef u16 efi_char16_t;		/* UNICODE character */
-
-
-typedef struct {
-	u8 b[16];
-} efi_guid_t;
-
-#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, \
-  (c) & 0xff, ((c) >> 8) & 0xff, \
-  (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
-
-/*
- * Generic EFI table header
- */
-typedef	struct {
-	u64 signature;
-	u32 revision;
-	u32 headersize;
-	u32 crc32;
-	u32 reserved;
-} efi_table_hdr_t;
-
-/*
- * Memory map descriptor:
- */
-
-/* Memory types: */
-#define EFI_RESERVED_TYPE		 0
-#define EFI_LOADER_CODE			 1
-#define EFI_LOADER_DATA			 2
-#define EFI_BOOT_SERVICES_CODE		 3
-#define EFI_BOOT_SERVICES_DATA		 4
-#define EFI_RUNTIME_SERVICES_CODE	 5
-#define EFI_RUNTIME_SERVICES_DATA	 6
-#define EFI_CONVENTIONAL_MEMORY		 7
-#define EFI_UNUSABLE_MEMORY		 8
-#define EFI_ACPI_RECLAIM_MEMORY		 9
-#define EFI_ACPI_MEMORY_NVS		10
-#define EFI_MEMORY_MAPPED_IO		11
-#define EFI_MEMORY_MAPPED_IO_PORT_SPACE	12
-#define EFI_PAL_CODE			13
-#define EFI_MAX_MEMORY_TYPE		14
-
-/* Attribute values: */
-#define EFI_MEMORY_UC		((u64)0x0000000000000001ULL)	/* uncached */
-#define EFI_MEMORY_WC		((u64)0x0000000000000002ULL)	/* write-coalescing */
-#define EFI_MEMORY_WT		((u64)0x0000000000000004ULL)	/* write-through */
-#define EFI_MEMORY_WB		((u64)0x0000000000000008ULL)	/* write-back */
-#define EFI_MEMORY_WP		((u64)0x0000000000001000ULL)	/* write-protect */
-#define EFI_MEMORY_RP		((u64)0x0000000000002000ULL)	/* read-protect */
-#define EFI_MEMORY_XP		((u64)0x0000000000004000ULL)	/* execute-protect */
-#define EFI_MEMORY_RUNTIME	((u64)0x8000000000000000ULL)	/* range requires runtime mapping */
-#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;
-
-/*
- * Allocation types for calls to boottime->allocate_pages.
- */
-#define EFI_ALLOCATE_ANY_PAGES		0
-#define EFI_ALLOCATE_MAX_ADDRESS	1
-#define EFI_ALLOCATE_ADDRESS		2
-#define EFI_MAX_ALLOCATE_TYPE		3
-
-typedef int (*efi_freemem_callback_t) (u64 start, u64 end, void *arg);
-
-/*
- * Types and defines for Time Services
- */
-#define EFI_TIME_ADJUST_DAYLIGHT 0x1
-#define EFI_TIME_IN_DAYLIGHT     0x2
-#define EFI_UNSPECIFIED_TIMEZONE 0x07ff
-
-typedef struct {
-	u16 year;
-	u8 month;
-	u8 day;
-	u8 hour;
-	u8 minute;
-	u8 second;
-	u8 pad1;
-	u32 nanosecond;
-	s16 timezone;
-	u8 daylight;
-	u8 pad2;
-} efi_time_t;
-
-typedef struct {
-	u32 resolution;
-	u32 accuracy;
-	u8 sets_to_zero;
-} efi_time_cap_t;
-
-/*
- * EFI Boot Services table
- */
-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;
-	void *create_event;
-	void *set_timer;
-	void *wait_for_event;
-	void *signal_event;
-	void *close_event;
-	void *check_event;
-	void *install_protocol_interface;
-	void *reinstall_protocol_interface;
-	void *uninstall_protocol_interface;
-	void *handle_protocol;
-	void *__reserved;
-	void *register_protocol_notify;
-	void *locate_handle;
-	void *locate_device_path;
-	void *install_configuration_table;
-	void *load_image;
-	void *start_image;
-	void *exit;
-	void *unload_image;
-	void *exit_boot_services;
-	void *get_next_monotonic_count;
-	void *stall;
-	void *set_watchdog_timer;
-	void *connect_controller;
-	void *disconnect_controller;
-	void *open_protocol;
-	void *close_protocol;
-	void *open_protocol_information;
-	void *protocols_per_handle;
-	void *locate_handle_buffer;
-	void *locate_protocol;
-	void *install_multiple_protocol_interfaces;
-	void *uninstall_multiple_protocol_interfaces;
-	void *calculate_crc32;
-	void *copy_mem;
-	void *set_mem;
-	void *create_event_ex;
-} efi_boot_services_t;
-
-/*
- * Types and defines for EFI ResetSystem
- */
-#define EFI_RESET_COLD 0
-#define EFI_RESET_WARM 1
-#define EFI_RESET_SHUTDOWN 2
-
-/*
- * EFI Runtime Services table
- */
-#define EFI_RUNTIME_SERVICES_SIGNATURE ((u64)0x5652453544e5552ULL)
-#define EFI_RUNTIME_SERVICES_REVISION  0x00010000
-
-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;
-} 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);
-
-/*
- *  EFI Configuration Table and GUID definitions
- */
-#define NULL_GUID \
-    EFI_GUID(  0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
-
-#define MPS_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
-
-#define ACPI_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
-
-#define ACPI_20_TABLE_GUID    \
-    EFI_GUID(  0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
-
-#define SMBIOS_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
-
-#define SAL_SYSTEM_TABLE_GUID    \
-    EFI_GUID(  0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
-
-#define HCDP_TABLE_GUID	\
-    EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
-
-#define 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 \
-    EFI_GUID(  0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
-
-#define LINUX_EFI_CRASH_GUID \
-    EFI_GUID(  0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 )
-
-#define LOADED_IMAGE_PROTOCOL_GUID \
-    EFI_GUID(  0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
-
-#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
-    EFI_GUID(  0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a )
-
-#define EFI_UGA_PROTOCOL_GUID \
-    EFI_GUID(  0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 )
-
-#define EFI_PCI_IO_PROTOCOL_GUID \
-    EFI_GUID(  0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a )
-
-#define EFI_FILE_INFO_ID \
-    EFI_GUID(  0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
-
-#define EFI_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;
-
-typedef struct {
-	efi_guid_t guid;
-	u32 table;
-} efi_config_table_32_t;
-
-typedef struct {
-	efi_guid_t guid;
-	unsigned long table;
-} efi_config_table_t;
-
-#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
-
-#define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
-#define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
-#define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
-#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
-#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
-#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
-
-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;
-	unsigned long con_out_handle;
-	unsigned long con_out;
-	unsigned long stderr_handle;
-	unsigned long _stderr;
-	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;
-	efi_system_table_t *system_table;
-	void *device_handle;
-	void *file_path;
-	void *reserved;
-	u32 load_options_size;
-	void *load_options;
-	void *image_base;
-	__aligned_u64 image_size;
-	unsigned int image_code_type;
-	unsigned int image_data_type;
-	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
- */
-#define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
-#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
-#define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
-#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008
-#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010
-#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020
-#define EFI_VARIABLE_APPEND_WRITE	0x0000000000000040
-
-#define EFI_VARIABLE_MASK 	(EFI_VARIABLE_NON_VOLATILE | \
-				EFI_VARIABLE_BOOTSERVICE_ACCESS | \
-				EFI_VARIABLE_RUNTIME_ACCESS | \
-				EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
-				EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
-				EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
-				EFI_VARIABLE_APPEND_WRITE)
-/*
- * The type of search to perform when calling boottime->locate_handle
- */
-#define EFI_LOCATE_ALL_HANDLES			0
-#define EFI_LOCATE_BY_REGISTER_NOTIFY		1
-#define EFI_LOCATE_BY_PROTOCOL			2
-
-/*
- * 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
-
-#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] 32+ messages in thread

* [PATCH 12/21] filetype: Add DOS EXE file detection support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (10 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 11/21] Move efi.h to include/ Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 13/21] efi: Add more error codes Sascha Hauer
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/filetype.c  | 4 ++++
 include/filetype.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/common/filetype.c b/common/filetype.c
index 508a2b5..a1640ff 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -53,6 +53,7 @@ static const struct filetype_str filetype_str[] = {
 	[filetype_gpt] = { "GUID Partition Table", "gpt" },
 	[filetype_bpk] = { "Binary PacKage", "bpk" },
 	[filetype_barebox_env] = { "barebox environment file", "bbenv" },
+	[filetype_dos] = { "MS-DOS executable", "dos" },
 };
 
 const char *file_type_to_string(enum filetype f)
@@ -231,6 +232,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize)
 	if (bufsize < 64)
 		return filetype_unknown;
 
+	if (buf8[0] == 'M' && buf8[1] == 'Z')
+		return filetype_dos;
+
 	if (is_barebox_arm_head(_buf))
 		return filetype_arm_barebox;
 	if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01)
diff --git a/include/filetype.h b/include/filetype.h
index c20a4f9..db2db35 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -30,6 +30,7 @@ enum filetype {
 	filetype_ubifs,
 	filetype_bpk,
 	filetype_barebox_env,
+	filetype_dos,
 	filetype_max,
 };
 
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 13/21] efi: Add more error codes
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (11 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 12/21] filetype: Add DOS EXE file detection support Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 14/21] serial: ns16550: Add mmiobase to private data Sascha Hauer
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/efi.h | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/include/efi.h b/include/efi.h
index 570eff7..9911fa1 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -14,13 +14,40 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
-#define EFI_SUCCESS		0
-#define EFI_LOAD_ERROR          ( 1 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_INVALID_PARAMETER	( 2 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_UNSUPPORTED		( 3 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_BAD_BUFFER_SIZE     ( 4 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_BUFFER_TOO_SMALL	( 5 | (1UL << (BITS_PER_LONG-1)))
-#define EFI_NOT_FOUND		(14 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_SUCCESS                             0
+#define EFI_LOAD_ERROR                  ( 1 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_INVALID_PARAMETER           ( 2 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_UNSUPPORTED                 ( 3 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_BAD_BUFFER_SIZE             ( 4 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_BUFFER_TOO_SMALL            ( 5 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NOT_READY                   ( 6 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_DEVICE_ERROR                ( 7 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_WRITE_PROTECTED             ( 8 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_OUT_OF_RESOURCES            ( 9 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_VOLUME_CORRUPTED            ( 10 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_VOLUME_FULL                 ( 11 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NO_MEDIA                    ( 12 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_MEDIA_CHANGED               ( 13 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NOT_FOUND                   ( 14 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_ACCESS_DENIED               ( 15 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NO_RESPONSE                 ( 16 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NO_MAPPING                  ( 17 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_TIMEOUT                     ( 18 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NOT_STARTED                 ( 19 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_ALREADY_STARTED             ( 20 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_ABORTED                     ( 21 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_ICMP_ERROR                  ( 22 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_TFTP_ERROR                  ( 23 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_PROTOCOL_ERROR              ( 24 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_INCOMPATIBLE_VERSION        ( 25 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_SECURITY_VIOLATION          ( 26 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_CRC_ERROR                   ( 27 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_END_OF_MEDIA                ( 28 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_END_OF_FILE                 ( 31 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_INVALID_LANGUAGE            ( 32 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_COMPROMISED_DATA            ( 33 | (1UL << (BITS_PER_LONG-1)))
+
+#define EFI_ERROR(a)	(((signed long) a) < 0)
 
 typedef unsigned long efi_status_t;
 typedef u8 efi_bool_t;
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 14/21] serial: ns16550: Add mmiobase to private data
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (12 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 13/21] efi: Add more error codes Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 15/21] serial: ns16550: Add register read/write function pointers " Sascha Hauer
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

We have a private data struct, so use it for storing the
base address instead of abusing the dev->priv field.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/serial/serial_ns16550.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 709f704..27fae9b 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -50,6 +50,7 @@ struct ns16550_priv {
 	int mmio;
 	struct clk *clk;
 	uint32_t fcrval;
+	void __iomem *mmiobase;
 };
 
 static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev)
@@ -157,7 +158,6 @@ static inline void ns16550_sys_writel(uint32_t val, void __iomem *addr,
 static uint32_t ns16550_read(struct console_device *cdev, uint32_t off)
 {
 	struct ns16550_priv *priv = to_ns16550_priv(cdev);
-	struct device_d *dev = cdev->dev;
 	struct NS16550_plat *plat = &priv->plat;
 	int width = priv->access_width;
 
@@ -165,11 +165,11 @@ static uint32_t ns16550_read(struct console_device *cdev, uint32_t off)
 
 	switch (width) {
 	case IORESOURCE_MEM_8BIT:
-		return ns16550_sys_readb(dev->priv + off, priv->mmio);
+		return ns16550_sys_readb(priv->mmiobase + off, priv->mmio);
 	case IORESOURCE_MEM_16BIT:
-		return ns16550_sys_readw(dev->priv + off, priv->mmio);
+		return ns16550_sys_readw(priv->mmiobase + off, priv->mmio);
 	case IORESOURCE_MEM_32BIT:
-		return ns16550_sys_readl(dev->priv + off, priv->mmio);
+		return ns16550_sys_readl(priv->mmiobase + off, priv->mmio);
 	}
 	return -1;
 }
@@ -185,7 +185,6 @@ static void ns16550_write(struct console_device *cdev, uint32_t val,
 			  uint32_t off)
 {
 	struct ns16550_priv *priv = to_ns16550_priv(cdev);
-	struct device_d *dev = cdev->dev;
 	struct NS16550_plat *plat = &priv->plat;
 	int width = priv->access_width;
 
@@ -193,13 +192,13 @@ static void ns16550_write(struct console_device *cdev, uint32_t val,
 
 	switch (width) {
 	case IORESOURCE_MEM_8BIT:
-		ns16550_sys_writeb(val & 0xff, dev->priv + off, priv->mmio);
+		ns16550_sys_writeb(val & 0xff, priv->mmiobase + off, priv->mmio);
 		break;
 	case IORESOURCE_MEM_16BIT:
-		ns16550_sys_writew(val & 0xffff, dev->priv + off, priv->mmio);
+		ns16550_sys_writew(val & 0xffff, priv->mmiobase + off, priv->mmio);
 		break;
 	case IORESOURCE_MEM_32BIT:
-		ns16550_sys_writel(val, dev->priv + off, priv->mmio);
+		ns16550_sys_writel(val, priv->mmiobase + off, priv->mmio);
 		break;
 	}
 }
@@ -395,7 +394,7 @@ static int ns16550_probe(struct device_d *dev)
 	}
 	if (!res)
 		goto err;
-	dev->priv = (void __force __iomem *) res->start;
+	priv->mmiobase = (void __force __iomem *) res->start;
 
 
 	if (plat)
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 15/21] serial: ns16550: Add register read/write function pointers to private data
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (13 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 14/21] serial: ns16550: Add mmiobase to private data Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 16/21] Documentation: Add EFI documentation Sascha Hauer
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Makes the code a bit cleaner. This also avoids casting from a pointer
to a 32bit integer which may produce compiler warnings.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/serial/serial_ns16550.c | 234 ++++++++++++++++++++--------------------
 1 file changed, 120 insertions(+), 114 deletions(-)

diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 27fae9b..09e6a6a 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -46,11 +46,17 @@
 struct ns16550_priv {
 	struct console_device cdev;
 	struct NS16550_plat plat;
-	int access_width;
-	int mmio;
 	struct clk *clk;
 	uint32_t fcrval;
 	void __iomem *mmiobase;
+	unsigned iobase;
+	void (*write_reg)(struct ns16550_priv *, uint8_t val, unsigned offset);
+	uint8_t (*read_reg)(struct ns16550_priv *, unsigned offset);
+};
+
+struct ns16550_drvdata {
+        void (*init_port)(struct console_device *cdev);
+        const char *linux_console_name;
 };
 
 static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev)
@@ -58,93 +64,64 @@ static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev)
 	return container_of(cdev, struct ns16550_priv, cdev);
 }
 
-struct ns16550_drvdata {
-	void (*init_port)(struct console_device *cdev);
-	const char *linux_console_name;
-};
+static uint8_t ns16550_read_reg_mmio_8(struct ns16550_priv *priv, unsigned offset)
+{
+	return readb(priv->mmiobase + offset);
+}
 
-/**
- * @brief read system i/o (byte)
- * @param[in] addr address to read
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline uint8_t ns16550_sys_readb(void __iomem *addr, int mmio)
+static void ns16550_write_reg_mmio_8(struct ns16550_priv *priv, uint8_t val, unsigned offset)
 {
-	if (mmio)
-		return readb(addr);
-	else
-		return (uint8_t) inb((int) addr);
+	writeb(val, priv->mmiobase + offset);
 }
 
-/**
- * @brief read system i/o (word)
- * @param[in] addr address to read
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline uint16_t ns16550_sys_readw(void __iomem *addr, int mmio)
+static uint8_t ns16550_read_reg_mmio_16(struct ns16550_priv *priv, unsigned offset)
 {
-	if (mmio)
-		return readw(addr);
-	else
-		return (uint16_t) inw((int) addr);
+	return readw(priv->mmiobase + offset);
 }
 
-/**
- * @brief read system i/o (dword)
- * @param[in] addr address to read
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline uint32_t ns16550_sys_readl(void __iomem *addr, int mmio)
+static void ns16550_write_reg_mmio_16(struct ns16550_priv *priv, uint8_t val, unsigned offset)
 {
-	if (mmio)
-		return readl(addr);
-	else
-		return (uint32_t) inl((int) addr);
+	writew(val, priv->mmiobase + offset);
 }
 
-/**
- * @brief write system i/o (byte)
- * @param[in] val data to write
- * @param[in] addr address to write to
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline void ns16550_sys_writeb(uint8_t val, void __iomem *addr,
-				      int mmio)
+static uint8_t ns16550_read_reg_mmio_32(struct ns16550_priv *priv, unsigned offset)
 {
-	if (mmio)
-		writeb(val, addr);
-	else
-		outb(val, (int) addr);
+	return readl(priv->mmiobase + offset);
 }
 
-/**
- * @brief read system i/o (word)
- * @param[in] val data to write
- * @param[in] addr address to write to
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline void ns16550_sys_writew(uint16_t val, void __iomem *addr,
-				      int mmio)
+static void ns16550_write_reg_mmio_32(struct ns16550_priv *priv, uint8_t val, unsigned offset)
 {
-	if (mmio)
-		writew(val, addr);
-	else
-		outw(val, (int) addr);
+	writel(val, priv->mmiobase + offset);
 }
 
-/**
- * @brief read system i/o (dword)
- * @param[in] val data to write
- * @param[in] addr address to write to
- * @param[in] mmio memory i/o space or i/o port space
- */
-static inline void ns16550_sys_writel(uint32_t val, void __iomem *addr,
-				      int mmio)
+static uint8_t ns16550_read_reg_ioport_8(struct ns16550_priv *priv, unsigned offset)
 {
-	if (mmio)
-		writel(val, addr);
-	else
-		outl(val, (int) addr);
+	return inb(priv->iobase + offset);
+}
+
+static void ns16550_write_reg_ioport_8(struct ns16550_priv *priv, uint8_t val, unsigned offset)
+{
+	outb(val, priv->iobase + offset);
+}
+
+static uint8_t ns16550_read_reg_ioport_16(struct ns16550_priv *priv, unsigned offset)
+{
+	return inw(priv->iobase + offset);
+}
+
+static void ns16550_write_reg_ioport_16(struct ns16550_priv *priv, uint8_t val, unsigned offset)
+{
+	outw(val, priv->iobase + offset);
+}
+
+static uint8_t ns16550_read_reg_ioport_32(struct ns16550_priv *priv, unsigned offset)
+{
+	return inl(priv->iobase + offset);
+}
+
+static void ns16550_write_reg_ioport_32(struct ns16550_priv *priv, uint8_t val, unsigned offset)
+{
+	outl(val, priv->iobase + offset);
 }
 
 /**
@@ -159,19 +136,8 @@ static uint32_t ns16550_read(struct console_device *cdev, uint32_t off)
 {
 	struct ns16550_priv *priv = to_ns16550_priv(cdev);
 	struct NS16550_plat *plat = &priv->plat;
-	int width = priv->access_width;
-
-	off <<= plat->shift;
 
-	switch (width) {
-	case IORESOURCE_MEM_8BIT:
-		return ns16550_sys_readb(priv->mmiobase + off, priv->mmio);
-	case IORESOURCE_MEM_16BIT:
-		return ns16550_sys_readw(priv->mmiobase + off, priv->mmio);
-	case IORESOURCE_MEM_32BIT:
-		return ns16550_sys_readl(priv->mmiobase + off, priv->mmio);
-	}
-	return -1;
+	return priv->read_reg(priv, off << plat->shift);
 }
 
 /**
@@ -186,21 +152,8 @@ static void ns16550_write(struct console_device *cdev, uint32_t val,
 {
 	struct ns16550_priv *priv = to_ns16550_priv(cdev);
 	struct NS16550_plat *plat = &priv->plat;
-	int width = priv->access_width;
-
-	off <<= plat->shift;
 
-	switch (width) {
-	case IORESOURCE_MEM_8BIT:
-		ns16550_sys_writeb(val & 0xff, priv->mmiobase + off, priv->mmio);
-		break;
-	case IORESOURCE_MEM_16BIT:
-		ns16550_sys_writew(val & 0xffff, priv->mmiobase + off, priv->mmio);
-		break;
-	case IORESOURCE_MEM_32BIT:
-		ns16550_sys_writel(val, priv->mmiobase + off, priv->mmio);
-		break;
-	}
+	priv->write_reg(priv, val, off << plat->shift);
 }
 
 /**
@@ -358,6 +311,70 @@ static __maybe_unused struct ns16550_drvdata jz_drvdata = {
 	.init_port = ns16550_jz_init_port,
 };
 
+static int ns16550_init_iomem(struct device_d *dev, struct ns16550_priv *priv)
+{
+	struct resource *res;
+	int width;
+
+	res = dev_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	priv->mmiobase = dev_request_mem_region(dev, 0);
+
+	width = res->flags & IORESOURCE_MEM_TYPE_MASK;
+	switch (width) {
+	case IORESOURCE_MEM_8BIT:
+		priv->read_reg = ns16550_read_reg_mmio_8;
+		priv->write_reg = ns16550_write_reg_mmio_8;
+		break;
+	case IORESOURCE_MEM_16BIT:
+		priv->read_reg = ns16550_read_reg_mmio_16;
+		priv->write_reg = ns16550_write_reg_mmio_16;
+		break;
+	case IORESOURCE_MEM_32BIT:
+		priv->read_reg = ns16550_read_reg_mmio_32;
+		priv->write_reg = ns16550_write_reg_mmio_32;
+		break;
+	}
+
+	return 0;
+}
+
+static int ns16550_init_ioport(struct device_d *dev, struct ns16550_priv *priv)
+{
+	struct resource *res;
+	int width;
+
+	res = dev_get_resource(dev, IORESOURCE_IO, 0);
+	if (!res)
+		return -ENODEV;
+
+	res = request_ioport_region(dev_name(dev), res->start, res->end);
+	if (!res)
+		return -ENODEV;
+
+	priv->iobase = res->start;
+
+	width = res->flags & IORESOURCE_MEM_TYPE_MASK;
+	switch (width) {
+	case IORESOURCE_MEM_8BIT:
+		priv->read_reg = ns16550_read_reg_ioport_8;
+		priv->write_reg = ns16550_write_reg_ioport_8;
+		break;
+	case IORESOURCE_MEM_16BIT:
+		priv->read_reg = ns16550_read_reg_ioport_16;
+		priv->write_reg = ns16550_write_reg_ioport_16;
+		break;
+	case IORESOURCE_MEM_32BIT:
+		priv->read_reg = ns16550_read_reg_ioport_32;
+		priv->write_reg = ns16550_write_reg_ioport_32;
+		break;
+	}
+
+	return 0;
+}
+
 /**
  * @brief Probe entry point -called on the first match for device
  *
@@ -373,7 +390,6 @@ static int ns16550_probe(struct device_d *dev)
 	struct console_device *cdev;
 	struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data;
 	struct ns16550_drvdata *devtype;
-	struct resource *res;
 	int ret;
 
 	ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
@@ -382,20 +398,12 @@ static int ns16550_probe(struct device_d *dev)
 
 	priv = xzalloc(sizeof(*priv));
 
-	res = dev_get_resource(dev, IORESOURCE_MEM, 0);
-	priv->mmio = (res != NULL);
-	if (res) {
-		res = request_iomem_region(dev_name(dev), res->start, res->end);
-	} else {
-		res = dev_get_resource(dev, IORESOURCE_IO, 0);
-		if (res)
-			res = request_ioport_region(dev_name(dev), res->start,
-						    res->end);
-	}
-	if (!res)
-		goto err;
-	priv->mmiobase = (void __force __iomem *) res->start;
+	ret = ns16550_init_iomem(dev, priv);
+	if (ret)
+		ret = ns16550_init_ioport(dev, priv);
 
+	if (ret)
+		return ret;
 
 	if (plat)
 		priv->plat = *plat;
@@ -423,8 +431,6 @@ static int ns16550_probe(struct device_d *dev)
 		goto err;
 	}
 
-	priv->access_width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK;
-
 	cdev = &priv->cdev;
 	cdev->dev = dev;
 	cdev->tstc = ns16550_tstc;
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 16/21] Documentation: Add EFI documentation
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (14 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 15/21] serial: ns16550: Add register read/write function pointers " Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  9:04   ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-08  8:50 ` [PATCH 17/21] Add initial EFI architecture support Sascha Hauer
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 Documentation/boards/efi.rst | 279 +++++++++++++++++++++++++++++++++++++++++++
 Documentation/glossary.rst   |   3 +
 2 files changed, 282 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..a8f3a09
--- /dev/null
+++ b/Documentation/boards/efi.rst
@@ -0,0 +1,279 @@
+barebox EFI support
+===================
+
+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.
+
+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] 32+ messages in thread

* [PATCH 17/21] Add initial EFI architecture support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (15 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 16/21] Documentation: Add EFI documentation Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 18/21] net: Add EFI Simple Network Protocol Driver Sascha Hauer
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 UTC (permalink / raw)
  To: barebox

This adds support for running barebox in an EFI environment
on X86 PC hardware.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/efi/Kconfig                           |   47 +
 arch/efi/Makefile                          |   41 +
 arch/efi/configs/efi_defconfig             |   73 ++
 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                  |  348 +++++++
 arch/efi/efi/efi-image.c                   |  105 +++
 arch/efi/efi/efi.c                         |  342 +++++++
 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 ++
 common/Kconfig                             |    8 +
 common/Makefile                            |    4 +-
 common/efi-devicepath.c                    | 1370 ++++++++++++++++++++++++++++
 common/efi-guid.c                          |   11 +
 common/memory.c                            |    2 +-
 common/partitions/efi.c                    |    2 +-
 drivers/of/Kconfig                         |    2 +-
 include/efi.h                              |  464 ++++------
 42 files changed, 3774 insertions(+), 269 deletions(-)
 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

diff --git a/arch/efi/Kconfig b/arch/efi/Kconfig
new file mode 100644
index 0000000..f67ed9d
--- /dev/null
+++ b/arch/efi/Kconfig
@@ -0,0 +1,47 @@
+config ARCH_EFI
+	bool
+	default y
+	select HAS_DEBUG_LL
+	select HAS_KALLSYMS
+	select HAVE_DEFAULT_ENVIRONMENT_NEW
+	select EFI_GUID
+	select EFI_DEVICEPATH
+
+config ARCH_TEXT_BASE
+	hex
+	default 0x0
+
+menu "EFI specific settings"
+
+config 64BIT
+	bool "64-bit binary"
+	help
+	  Say yes to build a 64-bit kernel - formerly known as x86_64
+	  Say no to build a 32-bit kernel - formerly known as i386
+
+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
diff --git a/arch/efi/Makefile b/arch/efi/Makefile
new file mode 100644
index 0000000..af28085
--- /dev/null
+++ b/arch/efi/Makefile
@@ -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/
diff --git a/arch/efi/configs/efi_defconfig b/arch/efi/configs/efi_defconfig
new file mode 100644
index 0000000..253d7e8
--- /dev/null
+++ b/arch/efi/configs/efi_defconfig
@@ -0,0 +1,73 @@
+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_NS16550=y
+# CONFIG_SPI is not set
+CONFIG_DISK=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
diff --git a/arch/efi/efi/Makefile b/arch/efi/efi/Makefile
new file mode 100644
index 0000000..a856e59
--- /dev/null
+++ b/arch/efi/efi/Makefile
@@ -0,0 +1,2 @@
+obj-y += efi.o clocksource.o efi-block-io.o efi-device.o efi-image.o
+bbenv-y += env-efi
diff --git a/arch/efi/efi/clocksource.c b/arch/efi/efi/clocksource.c
new file mode 100644
index 0000000..2f33b43
--- /dev/null
+++ b/arch/efi/efi/clocksource.c
@@ -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;
+}
diff --git a/arch/efi/efi/efi-block-io.c b/arch/efi/efi/efi-block-io.c
new file mode 100644
index 0000000..0011531
--- /dev/null
+++ b/arch/efi/efi/efi-block-io.c
@@ -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);
diff --git a/arch/efi/efi/efi-device.c b/arch/efi/efi/efi-device.c
new file mode 100644
index 0000000..71526b9
--- /dev/null
+++ b/arch/efi/efi/efi-device.c
@@ -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);
diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
new file mode 100644
index 0000000..5cbc5df
--- /dev/null
+++ b/arch/efi/efi/efi-image.c
@@ -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_dos,
+};
+
+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_dos,
+	.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);
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
new file mode 100644
index 0000000..48b7d9a
--- /dev/null
+++ b/arch/efi/efi/efi.c
@@ -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;
+}
diff --git a/arch/efi/efi/env-efi/network/eth0-discover b/arch/efi/efi/env-efi/network/eth0-discover
new file mode 100644
index 0000000..62c31a5
--- /dev/null
+++ b/arch/efi/efi/env-efi/network/eth0-discover
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+for i in /boot/network-drivers/*; do
+	$i;
+done
diff --git a/arch/efi/include/asm/barebox.h b/arch/efi/include/asm/barebox.h
new file mode 100644
index 0000000..2997587
--- /dev/null
+++ b/arch/efi/include/asm/barebox.h
@@ -0,0 +1 @@
+/* dummy */
diff --git a/arch/efi/include/asm/bitops.h b/arch/efi/include/asm/bitops.h
new file mode 100644
index 0000000..94646d4
--- /dev/null
+++ b/arch/efi/include/asm/bitops.h
@@ -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
diff --git a/arch/efi/include/asm/byteorder.h b/arch/efi/include/asm/byteorder.h
new file mode 100644
index 0000000..37316f2
--- /dev/null
+++ b/arch/efi/include/asm/byteorder.h
@@ -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 */
diff --git a/arch/efi/include/asm/common.h b/arch/efi/include/asm/common.h
new file mode 100644
index 0000000..b0e6b7f
--- /dev/null
+++ b/arch/efi/include/asm/common.h
@@ -0,0 +1,4 @@
+#ifndef ASM_COMMON_H
+#define ASM_COMMON_H
+
+#endif /* ASM_COMMON_H */
diff --git a/arch/efi/include/asm/dma.h b/arch/efi/include/asm/dma.h
new file mode 100644
index 0000000..4595367
--- /dev/null
+++ b/arch/efi/include/asm/dma.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 */
diff --git a/arch/efi/include/asm/elf.h b/arch/efi/include/asm/elf.h
new file mode 100644
index 0000000..ddde035
--- /dev/null
+++ b/arch/efi/include/asm/elf.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__ */
diff --git a/arch/efi/include/asm/io.h b/arch/efi/include/asm/io.h
new file mode 100644
index 0000000..ac8a9c1
--- /dev/null
+++ b/arch/efi/include/asm/io.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 */
diff --git a/arch/efi/include/asm/posix_types.h b/arch/efi/include/asm/posix_types.h
new file mode 100644
index 0000000..6985b8e
--- /dev/null
+++ b/arch/efi/include/asm/posix_types.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
diff --git a/arch/efi/include/asm/sections.h b/arch/efi/include/asm/sections.h
new file mode 100644
index 0000000..2b8c516
--- /dev/null
+++ b/arch/efi/include/asm/sections.h
@@ -0,0 +1 @@
+#include <asm-generic/sections.h>
diff --git a/arch/efi/include/asm/string.h b/arch/efi/include/asm/string.h
new file mode 100644
index 0000000..2997587
--- /dev/null
+++ b/arch/efi/include/asm/string.h
@@ -0,0 +1 @@
+/* dummy */
diff --git a/arch/efi/include/asm/swab.h b/arch/efi/include/asm/swab.h
new file mode 100644
index 0000000..60a9012
--- /dev/null
+++ b/arch/efi/include/asm/swab.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+/* nothing. use generic functions */
+
+#endif /* _ASM_SWAB_H */
diff --git a/arch/efi/include/asm/types.h b/arch/efi/include/asm/types.h
new file mode 100644
index 0000000..3204448
--- /dev/null
+++ b/arch/efi/include/asm/types.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
diff --git a/arch/efi/include/asm/unaligned.h b/arch/efi/include/asm/unaligned.h
new file mode 100644
index 0000000..d02da6e
--- /dev/null
+++ b/arch/efi/include/asm/unaligned.h
@@ -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 */
diff --git a/arch/efi/include/mach/debug_ll.h b/arch/efi/include/mach/debug_ll.h
new file mode 100644
index 0000000..0fb2cb8
--- /dev/null
+++ b/arch/efi/include/mach/debug_ll.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
diff --git a/arch/efi/include/mach/efi-device.h b/arch/efi/include/mach/efi-device.h
new file mode 100644
index 0000000..fe074a4
--- /dev/null
+++ b/arch/efi/include/mach/efi-device.h
@@ -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 */
diff --git a/arch/efi/include/mach/efi.h b/arch/efi/include/mach/efi.h
new file mode 100644
index 0000000..1e9782a
--- /dev/null
+++ b/arch/efi/include/mach/efi.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 */
diff --git a/arch/efi/lib/.gitignore b/arch/efi/lib/.gitignore
new file mode 100644
index 0000000..847e317
--- /dev/null
+++ b/arch/efi/lib/.gitignore
@@ -0,0 +1,2 @@
+elf_x86_64_efi.lds
+elf_ia32_efi.lds
diff --git a/arch/efi/lib/Makefile b/arch/efi/lib/Makefile
new file mode 100644
index 0000000..c8a97ba
--- /dev/null
+++ b/arch/efi/lib/Makefile
@@ -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
diff --git a/arch/efi/lib/crt0-efi-ia32.S b/arch/efi/lib/crt0-efi-ia32.S
new file mode 100644
index 0000000..6f0f2e8
--- /dev/null
+++ b/arch/efi/lib/crt0-efi-ia32.S
@@ -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 */
diff --git a/arch/efi/lib/crt0-efi-x86_64.S b/arch/efi/lib/crt0-efi-x86_64.S
new file mode 100644
index 0000000..aa03106
--- /dev/null
+++ b/arch/efi/lib/crt0-efi-x86_64.S
@@ -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 */
diff --git a/arch/efi/lib/elf_ia32_efi.lds.S b/arch/efi/lib/elf_ia32_efi.lds.S
new file mode 100644
index 0000000..a5f6287
--- /dev/null
+++ b/arch/efi/lib/elf_ia32_efi.lds.S
@@ -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) }
+}
diff --git a/arch/efi/lib/elf_x86_64_efi.lds.S b/arch/efi/lib/elf_x86_64_efi.lds.S
new file mode 100644
index 0000000..d48432d
--- /dev/null
+++ b/arch/efi/lib/elf_x86_64_efi.lds.S
@@ -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) }
+}
diff --git a/arch/efi/lib/reloc_ia32.c b/arch/efi/lib/reloc_ia32.c
new file mode 100644
index 0000000..4692963
--- /dev/null
+++ b/arch/efi/lib/reloc_ia32.c
@@ -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;
+}
diff --git a/arch/efi/lib/reloc_x86_64.c b/arch/efi/lib/reloc_x86_64.c
new file mode 100644
index 0000000..1db72f5
--- /dev/null
+++ b/arch/efi/lib/reloc_x86_64.c
@@ -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;
+}
diff --git a/common/Kconfig b/common/Kconfig
index bba7f15..8b36126 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -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
diff --git a/common/Makefile b/common/Makefile
index 204241c..4220e15 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -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
diff --git a/common/efi-devicepath.c b/common/efi-devicepath.c
new file mode 100644
index 0000000..2b1d916
--- /dev/null
+++ b/common/efi-devicepath.c
@@ -0,0 +1,1370 @@
+#include <common.h>
+#include <efi.h>
+#include <malloc.h>
+#include <string.h>
+#include <wchar.h>
+
+struct string {
+	char *str;
+	int len;
+};
+
+char *cprintf(struct string *str, const char *fmt, ...)
+    __attribute__ ((format(__printf__, 2, 3)));
+
+char *cprintf(struct string *str, const char *fmt, ...)
+{
+	va_list args;
+	int len;
+
+	va_start(args, fmt);
+	if (str->str)
+		len = vsprintf(str->str + str->len, fmt, args);
+	else
+		len = vsnprintf(NULL, 0, fmt, args);
+	va_end(args);
+
+	str->len += len;
+
+	return NULL;
+}
+
+#define MIN_ALIGNMENT_SIZE  8	/* FIXME: X86_64 specific */
+#define ALIGN_SIZE(a)   ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
+
+#define EFI_DP_TYPE_MASK			0x7f
+#define EFI_DP_TYPE_UNPACKED			0x80
+
+#define END_DEVICE_PATH_TYPE			0x7f
+
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE		0xff
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE	0x01
+#define END_DEVICE_PATH_LENGTH			(sizeof(struct efi_device_path))
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a)        ( ((a)->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define device_path_type(a)           ( ((a)->type) & EFI_DP_TYPE_MASK )
+#define next_device_path_node(a)       ( (struct efi_device_path *) ( ((u8 *) (a)) + (a)->length))
+#define is_device_path_end_type(a)      ( device_path_type(a) == END_DEVICE_PATH_TYPE )
+#define is_device_path_end_sub_type(a)   ( (a)->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define is_device_path_end(a)          ( is_device_path_end_type(a) && is_device_path_end_sub_type(a) )
+#define is_device_path_unpacked(a)     ( (a)->type & EFI_DP_TYPE_UNPACKED )
+
+#define set_device_path_end_node(a)  {                      \
+            (a)->type = END_DEVICE_PATH_TYPE;           \
+            (a)->sub_type = END_ENTIRE_DEVICE_PATH_SUBTYPE;     \
+            (a)->length = sizeof(struct efi_device_path);   \
+            }
+
+/*
+ * Hardware Device Path (UEFI 2.4 specification, version 2.4 § 9.3.2.)
+ */
+
+#define HARDWARE_DEVICE_PATH            0x01
+
+#define HW_PCI_DP                       0x01
+struct pci_device_path {
+	struct efi_device_path header;
+	u8 Function;
+	u8 Device;
+};
+
+#define HW_PCCARD_DP                    0x02
+struct pccard_device_path {
+	struct efi_device_path header;
+	u8 function_number;
+};
+
+#define HW_MEMMAP_DP                    0x03
+struct memmap_device_path {
+	struct efi_device_path header;
+	u32 memory_type;
+	efi_physical_addr_t starting_address;
+	efi_physical_addr_t ending_address;
+};
+
+#define HW_VENDOR_DP                    0x04
+struct vendor_device_path {
+	struct efi_device_path header;
+	efi_guid_t Guid;
+};
+
+struct unknown_device_vendor_device_path {
+	struct vendor_device_path device_path;
+	u8 legacy_drive_letter;
+};
+
+#define HW_CONTROLLER_DP            0x05
+struct controller_device_path {
+	struct efi_device_path header;
+	u32 Controller;
+};
+
+/*
+ * ACPI Device Path (UEFI 2.4 specification, version 2.4 § 9.3.3 and 9.3.4.)
+ */
+#define ACPI_DEVICE_PATH                 0x02
+
+#define ACPI_DP                         0x01
+struct acpi_hid_device_path {
+	struct efi_device_path header;
+	u32 HID;
+	u32 UID;
+};
+
+#define EXPANDED_ACPI_DP		0x02
+struct expanded_acpi_hid_device_path {
+	struct efi_device_path header;
+	u32 HID;
+	u32 UID;
+	u32 CID;
+	u8 hid_str[1];
+};
+
+#define ACPI_ADR_DP 3
+struct acpi_adr_device_path {
+	struct efi_device_path header;
+	u32 ADR;
+};
+
+/*
+ * EISA ID Macro
+ * EISA ID Definition 32-bits
+ *  bits[15:0] - three character compressed ASCII EISA ID.
+ *  bits[31:16] - binary number
+ *   Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+ */
+#define PNP_EISA_ID_CONST       0x41d0
+#define EISA_ID(_Name, _Num)    ((u32) ((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId)     (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK        0xffff
+#define EISA_ID_TO_NUM(_Id)     ((_Id) >> 16)
+
+/*
+ * Messaging Device Path (UEFI 2.4 specification, version 2.4 § 9.3.5.)
+ */
+#define MESSAGING_DEVICE_PATH           0x03
+
+#define MSG_ATAPI_DP                    0x01
+struct atapi_device_path {
+	struct efi_device_path header;
+	u8 primary_secondary;
+	u8 slave_master;
+	u16 Lun;
+};
+
+#define MSG_SCSI_DP                     0x02
+struct scsi_device_path {
+	struct efi_device_path header;
+	u16 Pun;
+	u16 Lun;
+};
+
+#define MSG_FIBRECHANNEL_DP             0x03
+struct fibrechannel_device_path {
+	struct efi_device_path header;
+	u32 Reserved;
+	u64 WWN;
+	u64 Lun;
+};
+
+/**
+ * Fibre Channel Ex sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.5.6.
+ */
+#define MSG_FIBRECHANNELEX_DP 21
+struct fibrechannelex_device_path {
+	struct efi_device_path header;
+	u32 Reserved;
+	u8 WWN[8];		/* World Wide Name */
+	u8 Lun[8];		/* Logical unit, T-10 SCSI Architecture Model 4 specification */
+};
+
+#define MSG_1394_DP                     0x04
+struct f1394_device_path {
+	struct efi_device_path header;
+	u32 Reserved;
+	u64 Guid;
+};
+
+#define MSG_USB_DP                      0x05
+struct usb_device_path {
+	struct efi_device_path header;
+	u8 Port;
+	u8 Endpoint;
+};
+
+/**
+ * SATA Device Path sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.5.6.
+ */
+#define MSG_SATA_DP 18
+struct sata_device_path {
+	struct efi_device_path header;
+	u16 HBAPort_number;
+	u16 port_multiplier_port_number;
+	u16 Lun;		/* Logical Unit Number */
+};
+
+/**
+ * USB WWID Device Path sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.5.7.
+ */
+#define MSG_USB_WWID_DP 16
+struct usb_wwid_device_path {
+	struct efi_device_path header;
+	u16 interface_number;
+	u16 vendor_id;
+	u16 product_id;
+	s16 serial_number[1];	/* UTF-16 characters of the USB serial number */
+};
+
+/**
+ * Device Logical Unit sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.5.8.
+ */
+#define MSG_DEVICE_LOGICAL_UNIT_DP 17
+struct device_logical_unit_device_path {
+	struct efi_device_path header;
+	u8 Lun;			/* Logical Unit Number */
+};
+
+#define MSG_USB_CLASS_DP                0x0_f
+struct usb_class_device_path {
+	struct efi_device_path header;
+	u16 vendor_id;
+	u16 product_id;
+	u8 device_class;
+	u8 device_subclass;
+	u8 device_protocol;
+};
+
+#define MSG_I2_o_DP                      0x06
+struct i2_o_device_path {
+	struct efi_device_path header;
+	u32 Tid;
+};
+
+#define MSG_MAC_ADDR_DP                 0x0b
+struct mac_addr_device_path {
+	struct efi_device_path header;
+	efi_mac_address mac_address;
+	u8 if_type;
+};
+
+#define MSG_IPv4_DP                     0x0c
+struct ipv4_device_path {
+	struct efi_device_path header;
+	efi_ipv4_address local_ip_address;
+	efi_ipv4_address remote_ip_address;
+	u16 local_port;
+	u16 remote_port;
+	u16 Protocol;
+	bool static_ip_address;
+	/* new from UEFI version 2, code must check length field in header */
+	efi_ipv4_address gateway_ip_address;
+	efi_ipv4_address subnet_mask;
+};
+
+#define MSG_IPv6_DP                     0x0d
+struct ipv6_device_path {
+	struct efi_device_path header;
+	efi_ipv6_address local_ip_address;
+	efi_ipv6_address remote_ip_address;
+	u16 local_port;
+	u16 remote_port;
+	u16 Protocol;
+	bool IPAddress_origin;
+	/* new from UEFI version 2, code must check length field in header */
+	u8 prefix_length;
+	efi_ipv6_address gateway_ip_address;
+};
+
+/**
+ * Device Logical Unit sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.5.8.
+ */
+#define MSG_VLAN_DP 20
+struct vlan_device_path {
+	struct efi_device_path header;
+	u16 vlan_id;
+};
+
+#define MSG_INFINIBAND_DP               0x09
+struct infiniband_device_path {
+	struct efi_device_path header;
+	u32 resource_flags;
+	efi_guid_t port_gid;
+	u64 service_id;
+	u64 target_port_id;
+	u64 device_id;
+};
+
+#define MSG_UART_DP                     0x0e
+struct uart_device_path {
+	struct efi_device_path header;
+	u32 Reserved;
+	u64 baud_rate;
+	u8 data_bits;
+	u8 Parity;
+	u8 stop_bits;
+};
+
+#define MSG_VENDOR_DP                   0x0a
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI \
+    { 0xe0c14753, 0xf9be, 0x11d2,  {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}  }
+
+#define DEVICE_PATH_MESSAGING_VT_100 \
+    { 0xdfa66065, 0xb419, 0x11d3,  {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}  }
+
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS \
+    { 0x7baec70b , 0x57e0 , 0x4c76 , { 0x8e , 0x87 , 0x2f , 0x9e , 0x28 , 0x08 , 0x83 , 0x43 } }
+
+#define DEVICE_PATH_MESSAGING_VT_UTF8 \
+    { 0xad15a0d6 , 0x8bec , 0x4acf , { 0xa0 , 0x73 , 0xd0 , 0x1d , 0xe7 , 0x7e , 0x2d , 0x88 } }
+
+#define EFI_PC_ANSI_GUID \
+    { 0xe0c14753 , 0xf9be , 0x11d2 , 0x9a , 0x0c , 0x00 , 0x90 , 0x27 , 0x3f , 0xc1 , 0x4d }
+
+#define EFI_VT_100_GUID \
+    { 0xdfa66065 , 0xb419 , 0x11d3 , 0x9a , 0x2d , 0x00 , 0x90 , 0x27 , 0x3f , 0xc1 , 0x4d }
+
+#define EFI_VT_100_PLUS_GUID \
+    { 0x7baec70b , 0x57e0 , 0x4c76 , 0x8e , 0x87 , 0x2f , 0x9e , 0x28 , 0x08 , 0x83 , 0x43 }
+
+#define EFI_VT_UTF8_GUID \
+    { 0xad15a0d6 , 0x8bec , 0x4acf , 0xa0 , 0x73 , 0xd0 , 0x1d , 0xe7 , 0x7e , 0x2d , 0x88 }
+
+/*
+ * Media Device Path (UEFI 2.4 specification, version 2.4 § 9.3.6.)
+ */
+#define MEDIA_DEVICE_PATH               0x04
+
+#define MEDIA_HARDDRIVE_DP              0x01
+struct harddrive_device_path {
+	struct efi_device_path header;
+	u32 partition_number;
+	u64 partition_start;
+	u64 partition_size;
+	u8 signature[16];
+	u8 mbr_type;
+	u8 signature_type;
+};
+
+#define MBR_TYPE_PCAT                       0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define SIGNATURE_TYPE_MBR                  0x01
+#define SIGNATURE_TYPE_GUID                 0x02
+
+#define MEDIA_CDROM_DP                  0x02
+struct cdrom_device_path {
+	struct efi_device_path header;
+	u32 boot_entry;
+	u64 partition_start;
+	u64 partition_size;
+};
+
+#define MEDIA_VENDOR_DP                 0x03
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define MEDIA_FILEPATH_DP               0x04
+struct filepath_device_path {
+	struct efi_device_path header;
+	s16 path_name[1];
+};
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH offsetof(FILEPATH_DEVICE_PATH,path_name)
+
+#define MEDIA_PROTOCOL_DP               0x05
+struct media_protocol_device_path {
+	struct efi_device_path header;
+	efi_guid_t Protocol;
+};
+
+/**
+ * PIWG Firmware File sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.6.6.
+ */
+#define MEDIA_PIWG_FW_FILE_DP 6
+struct media_fw_vol_filepath_device_path {
+	struct efi_device_path header;
+	efi_guid_t fv_file_name;
+};
+
+/**
+ * PIWG Firmware Volume Device Path sub_type.
+ * UEFI 2.0 specification version 2.4 § 9.3.6.7.
+ */
+#define MEDIA_PIWG_FW_VOL_DP 7
+struct media_fw_vol_device_path {
+	struct efi_device_path header;
+	efi_guid_t fv_name;
+};
+
+/**
+ * Media relative offset range device path.
+ * UEFI 2.0 specification version 2.4 § 9.3.6.8.
+ */
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 8
+struct media_relative_offset_range_device_path {
+	struct efi_device_path header;
+	u32 Reserved;
+	u64 starting_offset;
+	u64 ending_offset;
+};
+
+/*
+ * BIOS Boot Specification Device Path (UEFI 2.4 specification, version 2.4 § 9.3.7.)
+ */
+#define BBS_DEVICE_PATH                 0x05
+
+#define BBS_BBS_DP                      0x01
+struct bbs_bbs_device_path {
+	struct efi_device_path header;
+	u16 device_type;
+	u16 status_flag;
+	s8 String[1];
+};
+
+/* device_type definitions - from BBS specification */
+#define BBS_TYPE_FLOPPY                 0x01
+#define BBS_TYPE_HARDDRIVE              0x02
+#define BBS_TYPE_CDROM                  0x03
+#define BBS_TYPE_PCMCIA                 0x04
+#define BBS_TYPE_USB                    0x05
+#define BBS_TYPE_EMBEDDED_NETWORK       0x06
+#define BBS_TYPE_DEV                    0x80
+#define BBS_TYPE_UNKNOWN                0x_fF
+
+struct efi_device_path end_device_path = {
+	.type = END_DEVICE_PATH_TYPE,
+	.sub_type = END_ENTIRE_DEVICE_PATH_SUBTYPE,
+	.length = END_DEVICE_PATH_LENGTH,
+};
+
+struct efi_device_path end_instance_device_path = {
+	.type = END_DEVICE_PATH_TYPE,
+	.sub_type = END_INSTANCE_DEVICE_PATH_SUBTYPE,
+	.length = END_DEVICE_PATH_LENGTH,
+};
+
+unsigned long
+device_path_size(struct efi_device_path *dev_path)
+{
+	struct efi_device_path *Start;
+
+	Start = dev_path;
+	while (!is_device_path_end(dev_path))
+		dev_path = next_device_path_node(dev_path);
+
+	return ((unsigned long) dev_path - (unsigned long) Start) +
+	    sizeof (struct efi_device_path);
+}
+
+struct efi_device_path *
+duplicate_device_path(struct efi_device_path *dev_path)
+{
+	struct efi_device_path *new_dev_path;
+	unsigned long Size;
+
+	Size = device_path_size(dev_path);
+
+	new_dev_path = malloc(Size);
+	if (new_dev_path)
+		memcpy(new_dev_path, dev_path, Size);
+
+	return new_dev_path;
+}
+
+struct efi_device_path *
+device_path_from_handle(efi_handle_t Handle)
+{
+	efi_status_t Status;
+	struct efi_device_path *device_path;
+
+	Status = BS->handle_protocol(Handle, &efi_device_path_protocol_guid,
+				(void *) &device_path);
+	if (EFI_ERROR(Status))
+		device_path = NULL;
+
+	return device_path;
+}
+
+struct efi_device_path *
+device_path_instance(struct efi_device_path **device_path, unsigned long *Size)
+{
+	struct efi_device_path *Start, *Next, *dev_path;
+	unsigned long Count;
+
+	dev_path = *device_path;
+	Start = dev_path;
+
+	if (!dev_path)
+		return NULL;
+
+	for (Count = 0;; Count++) {
+		Next = next_device_path_node(dev_path);
+
+		if (is_device_path_end_type(dev_path))
+			break;
+
+		dev_path = Next;
+	}
+
+	if (dev_path->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE)
+		Next = NULL;
+
+	*device_path = Next;
+
+	*Size = ((u8 *) dev_path) - ((u8 *) Start);
+
+	return Start;
+}
+
+unsigned long
+device_path_instance_count(struct efi_device_path *device_path)
+{
+	unsigned long Count, Size;
+
+	Count = 0;
+	while (device_path_instance(&device_path, &Size)) {
+		Count += 1;
+	}
+
+	return Count;
+}
+
+struct efi_device_path *
+append_device_path(struct efi_device_path *Src1, struct efi_device_path *Src2)
+/*
+ * Src1 may have multiple "instances" and each instance is appended
+ * Src2 is appended to each instance is Src1.  (E.g., it's possible
+ * to append a new instance to the complete device path by passing
+ * it in Src2)
+ */
+{
+	unsigned long src1_size, src1_inst, src2_size, Size;
+	struct efi_device_path *Dst, *Inst;
+	u8 *dst_pos;
+
+	if (!Src1)
+		return duplicate_device_path(Src2);
+
+	if (!Src2) {
+		return duplicate_device_path(Src1);
+	}
+
+	src1_size = device_path_size(Src1);
+	src1_inst = device_path_instance_count(Src1);
+	src2_size = device_path_size(Src2);
+	Size = src1_size * src1_inst + src2_size;
+
+	Dst = malloc(Size);
+	if (Dst) {
+		dst_pos = (u8 *) Dst;
+
+		/* Copy all device path instances */
+
+		while ((Inst = device_path_instance(&Src1, &Size))) {
+
+			memcpy(dst_pos, Inst, Size);
+			dst_pos += Size;
+
+			memcpy(dst_pos, Src2, src2_size);
+			dst_pos += src2_size;
+
+			memcpy(dst_pos, &end_instance_device_path,
+			       sizeof (struct efi_device_path));
+			dst_pos += sizeof (struct efi_device_path);
+		}
+
+		/* Change last end marker */
+		dst_pos -= sizeof (struct efi_device_path);
+		memcpy(dst_pos, &end_device_path,
+		       sizeof (struct efi_device_path));
+	}
+
+	return Dst;
+}
+
+struct efi_device_path *
+append_device_path_node(struct efi_device_path *Src1,
+			struct efi_device_path *Src2)
+/*
+ * Src1 may have multiple "instances" and each instance is appended
+ * Src2 is a signal device path node (without a terminator) that is
+ * appended to each instance is Src1.
+ */
+{
+	struct efi_device_path *Temp, *Eop;
+	unsigned long length;
+
+	/* Build a Src2 that has a terminator on it */
+
+	length = Src2->length;
+	Temp = malloc(length + sizeof (struct efi_device_path));
+	if (!Temp)
+		return NULL;
+
+	memcpy(Temp, Src2, length);
+	Eop = next_device_path_node(Temp);
+	set_device_path_end_node(Eop);
+
+	/* Append device paths */
+
+	Src1 = append_device_path(Src1, Temp);
+	free(Temp);
+	return Src1;
+}
+
+struct efi_device_path *
+unpack_device_path(struct efi_device_path *dev_path)
+{
+	struct efi_device_path *Src, *Dest, *new_path;
+	unsigned long Size;
+
+	/* Walk device path and round sizes to valid boundries */
+
+	Src = dev_path;
+	Size = 0;
+	for (;;) {
+		Size += Src->length;
+		Size += ALIGN_SIZE(Size);
+
+		if (is_device_path_end(Src)) {
+			break;
+		}
+
+		Src = next_device_path_node(Src);
+	}
+
+	new_path = xzalloc(Size);
+
+	Src = dev_path;
+	Dest = new_path;
+	for (;;) {
+		Size = Src->length;
+		memcpy(Dest, Src, Size);
+		Size += ALIGN_SIZE(Size);
+		Dest->length = Size;
+		Dest->type |= EFI_DP_TYPE_UNPACKED;
+		Dest =
+		    (struct efi_device_path *) (((u8 *) Dest) + Size);
+
+		if (is_device_path_end(Src))
+			break;
+
+		Src = next_device_path_node(Src);
+	}
+
+	return new_path;
+}
+
+struct efi_device_path *
+append_device_path_instance(struct efi_device_path *Src,
+			    struct efi_device_path *Instance)
+{
+	u8 *Ptr;
+	struct efi_device_path *dev_path;
+	unsigned long src_size;
+	unsigned long instance_size;
+
+	if (Src == NULL)
+		return duplicate_device_path(Instance);
+
+	src_size = device_path_size(Src);
+	instance_size = device_path_size(Instance);
+	Ptr = malloc(src_size + instance_size);
+	dev_path = (struct efi_device_path *) Ptr;
+
+	memcpy(Ptr, Src, src_size);
+
+	while (!is_device_path_end(dev_path))
+		dev_path = next_device_path_node(dev_path);
+
+	/*
+	 * Convert the End to an End Instance, since we are
+	 *  appending another instacne after this one its a good
+	 *  idea.
+	 */
+	dev_path->sub_type = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+	dev_path = next_device_path_node(dev_path);
+	memcpy(dev_path, Instance, instance_size);
+
+	return (struct efi_device_path *) Ptr;
+}
+
+efi_status_t
+lib_device_path_to_interface(efi_guid_t * Protocol,
+			     struct efi_device_path *file_path,
+			     void **Interface)
+{
+	efi_status_t Status;
+	efi_handle_t Device;
+
+	Status = BS->locate_device_path(Protocol, &file_path, &Device);
+
+	if (!EFI_ERROR(Status)) {
+
+		/* If we didn't get a direct match return not found */
+		Status = EFI_NOT_FOUND;
+
+		if (is_device_path_end(file_path)) {
+
+			/* It was a direct match, lookup the protocol interface */
+
+			Status =
+			    BS->handle_protocol(Device, Protocol, Interface);
+		}
+	}
+
+	if (EFI_ERROR(Status))
+		*Interface = NULL;
+
+	return Status;
+}
+
+static void
+dev_path_pci(struct string *str, void *dev_path)
+{
+	struct pci_device_path *Pci;
+
+	Pci = dev_path;
+	cprintf(str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
+}
+
+static void
+dev_path_pccard(struct string *str, void *dev_path)
+{
+	struct pccard_device_path *Pccard;
+
+	Pccard = dev_path;
+	cprintf(str, "Pccard(0x%x)", Pccard->function_number);
+}
+
+static void
+dev_path_mem_map(struct string *str, void *dev_path)
+{
+	struct memmap_device_path *mem_map;
+
+	mem_map = dev_path;
+	cprintf(str, "mem_map(%d,0x%llx,0x%llx)",
+		mem_map->memory_type,
+		mem_map->starting_address, mem_map->ending_address);
+}
+
+static void
+dev_path_controller(struct string *str, void *dev_path)
+{
+	struct controller_device_path *Controller;
+
+	Controller = dev_path;
+	cprintf(str, "Ctrl(%d)", Controller->Controller);
+}
+
+static void
+dev_path_vendor(struct string *str, void *dev_path)
+{
+	struct vendor_device_path *Vendor;
+	char *type;
+	struct unknown_device_vendor_device_path *unknown_dev_path;
+
+	Vendor = dev_path;
+	switch (device_path_type(&Vendor->header)) {
+	case HARDWARE_DEVICE_PATH:
+		type = "Hw";
+		break;
+	case MESSAGING_DEVICE_PATH:
+		type = "Msg";
+		break;
+	case MEDIA_DEVICE_PATH:
+		type = "Media";
+		break;
+	default:
+		type = "?";
+		break;
+	}
+
+	cprintf(str, "Ven%s(%pU", type, &Vendor->Guid);
+	if (efi_compare_guid(&Vendor->Guid, &efi_unknown_device_guid) == 0) {
+		/* GUID used by EFI to enumerate an EDD 1.1 device */
+		unknown_dev_path =
+		    (struct unknown_device_vendor_device_path *) Vendor;
+		cprintf(str, ":%02x)", unknown_dev_path->legacy_drive_letter);
+	} else {
+		cprintf(str, ")");
+	}
+}
+
+/*
+  type: 2 (ACPI Device Path) sub_type: 1 (ACPI Device Path)
+ */
+static void
+dev_path_acpi(struct string *str, void *dev_path)
+{
+	struct acpi_hid_device_path *Acpi;
+
+	Acpi = dev_path;
+	if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+		switch (EISA_ID_TO_NUM(Acpi->HID)) {
+		case 0x301:
+			cprintf(str, "Keyboard(%d)", Acpi->UID);
+			break;
+
+		case 0x401:
+			cprintf(str, "parallel_port(%d)", Acpi->UID);
+			break;
+		case 0x501:
+			cprintf(str, "Serial(%d)", Acpi->UID);
+			break;
+		case 0x604:
+			cprintf(str, "Floppy(%d)", Acpi->UID);
+			break;
+		case 0xa03:
+			cprintf(str, "pci_root(%d)", Acpi->UID);
+			break;
+		case 0xa08:
+			cprintf(str, "pcie_root(%d)", Acpi->UID);
+			break;
+		default:
+			cprintf(str, "Acpi(PNP%04x",
+				EISA_ID_TO_NUM(Acpi->HID));
+			if (Acpi->UID)
+				cprintf(str, ",%d", Acpi->UID);
+			cprintf(str, ")");
+			break;
+		}
+	} else {
+		cprintf(str, "Acpi(0x%X", Acpi->HID);
+		if (Acpi->UID)
+			cprintf(str, ",%d", Acpi->UID);
+		cprintf(str, ")");
+	}
+}
+
+static void
+dev_path_atapi(struct string *str, void *dev_path)
+{
+	struct atapi_device_path *Atapi;
+
+	Atapi = dev_path;
+	cprintf(str, "Ata(%s,%s)",
+		Atapi->primary_secondary ? "Secondary" : "Primary",
+		Atapi->slave_master ? "Slave" : "Master");
+}
+
+static void
+dev_path_scsi(struct string *str, void *dev_path)
+{
+	struct scsi_device_path *Scsi;
+
+	Scsi = dev_path;
+	cprintf(str, "Scsi(%d,%d)", Scsi->Pun, Scsi->Lun);
+}
+
+static void
+dev_path_fibre(struct string *str, void *dev_path)
+{
+	struct fibrechannel_device_path *Fibre;
+
+	Fibre = dev_path;
+	cprintf(str, "Fibre%s(0x%016llx,0x%016llx)",
+		device_path_type(&Fibre->header) ==
+		MSG_FIBRECHANNEL_DP ? "" : "Ex", Fibre->WWN, Fibre->Lun);
+}
+
+static void
+dev_path1394(struct string *str, void *dev_path)
+{
+	struct f1394_device_path *F1394;
+
+	F1394 = dev_path;
+	cprintf(str, "1394(%pU)", &F1394->Guid);
+}
+
+static void
+dev_path_usb(struct string *str, void *dev_path)
+{
+	struct usb_device_path *Usb;
+
+	Usb = dev_path;
+	cprintf(str, "Usb(0x%x,0x%x)", Usb->Port, Usb->Endpoint);
+}
+
+static void
+dev_path_i2_o(struct string *str, void *dev_path)
+{
+	struct i2_o_device_path *i2_o;
+
+	i2_o = dev_path;
+	cprintf(str, "i2_o(0x%X)", i2_o->Tid);
+}
+
+static void
+dev_path_mac_addr(struct string *str, void *dev_path)
+{
+	struct mac_addr_device_path *MAC;
+	unsigned long hw_address_size;
+	unsigned long Index;
+
+	MAC = dev_path;
+
+	/* hw_address_size = sizeof(EFI_MAC_ADDRESS); */
+	hw_address_size = MAC->header.length;
+	hw_address_size -= sizeof (MAC->header);
+	hw_address_size -= sizeof (MAC->if_type);
+	if (MAC->if_type == 0x01 || MAC->if_type == 0x00)
+		hw_address_size = 6;
+
+	cprintf(str, "Mac(");
+
+	for (Index = 0; Index < hw_address_size; Index++)
+		cprintf(str, "%02x", MAC->mac_address.Addr[Index]);
+
+	if (MAC->if_type != 0)
+		cprintf(str, ",%d", MAC->if_type);
+
+	cprintf(str, ")");
+}
+
+static void
+cat_print_iPv4(struct string *str, efi_ipv4_address * address)
+{
+	cprintf(str, "%d.%d.%d.%d", address->Addr[0], address->Addr[1],
+		address->Addr[2], address->Addr[3]);
+}
+
+static bool
+is_not_null_iPv4(efi_ipv4_address * address)
+{
+	u8 val;
+
+	val = address->Addr[0] | address->Addr[1];
+	val |= address->Addr[2] | address->Addr[3];
+
+	return val != 0;
+}
+
+static void
+cat_print_network_protocol(struct string *str, u16 Proto)
+{
+	if (Proto == 6)
+		cprintf(str, "TCP");
+	else if (Proto == 17)
+		cprintf(str, "UDP");
+	else
+		cprintf(str, "%d", Proto);
+}
+
+static void
+dev_path_iPv4(struct string *str, void *dev_path)
+{
+	struct ipv4_device_path *ip;
+	bool show;
+
+	ip = dev_path;
+	cprintf(str, "IPv4(");
+	cat_print_iPv4(str, &ip->remote_ip_address);
+	cprintf(str, ",");
+	cat_print_network_protocol(str, ip->Protocol);
+	cprintf(str, ",%s", ip->static_ip_address ? "Static" : "DHCP");
+	show = is_not_null_iPv4(&ip->local_ip_address);
+	if (!show
+	    && ip->header.length ==
+	    sizeof (struct ipv4_device_path)) {
+		/* only version 2 includes gateway and netmask */
+		show |= is_not_null_iPv4(&ip->gateway_ip_address);
+		show |= is_not_null_iPv4(&ip->subnet_mask);
+	}
+	if (show) {
+		cprintf(str, ",");
+		cat_print_iPv4(str, &ip->local_ip_address);
+		if (ip->header.length ==
+		    sizeof (struct ipv4_device_path)) {
+			/* only version 2 includes gateway and netmask */
+			show = is_not_null_iPv4(&ip->gateway_ip_address);
+			show |= is_not_null_iPv4(&ip->subnet_mask);
+			if (show) {
+				cprintf(str, ",");
+				cat_print_iPv4(str, &ip->gateway_ip_address);
+				if (is_not_null_iPv4(&ip->subnet_mask)) {
+					cprintf(str, ",");
+					cat_print_iPv4(str, &ip->subnet_mask);
+				}
+			}
+		}
+	}
+	cprintf(str, ")");
+}
+
+#define cat_print_iPv6_ADD( x , y ) ( ( (u16) ( x ) ) << 8 | ( y ) )
+static void
+cat_print_ipv6(struct string *str, efi_ipv6_address * address)
+{
+	cprintf(str, "%x:%x:%x:%x:%x:%x:%x:%x",
+		cat_print_iPv6_ADD(address->Addr[0], address->Addr[1]),
+		cat_print_iPv6_ADD(address->Addr[2], address->Addr[3]),
+		cat_print_iPv6_ADD(address->Addr[4], address->Addr[5]),
+		cat_print_iPv6_ADD(address->Addr[6], address->Addr[7]),
+		cat_print_iPv6_ADD(address->Addr[8], address->Addr[9]),
+		cat_print_iPv6_ADD(address->Addr[10], address->Addr[11]),
+		cat_print_iPv6_ADD(address->Addr[12], address->Addr[13]),
+		cat_print_iPv6_ADD(address->Addr[14], address->Addr[15]));
+}
+
+static void
+dev_path_iPv6(struct string *str, void *dev_path)
+{
+	struct ipv6_device_path *ip;
+
+	ip = dev_path;
+	cprintf(str, "IPv6(");
+	cat_print_ipv6(str, &ip->remote_ip_address);
+	cprintf(str, ",");
+	cat_print_network_protocol(str, ip->Protocol);
+	cprintf(str, ",%s,", ip->IPAddress_origin ?
+		(ip->IPAddress_origin == 1 ? "stateless_auto_configure" :
+		 "stateful_auto_configure") : "Static");
+	cat_print_ipv6(str, &ip->local_ip_address);
+	if (ip->header.length ==
+	    sizeof (struct ipv6_device_path)) {
+		cprintf(str, ",");
+		cat_print_ipv6(str, &ip->gateway_ip_address);
+		cprintf(str, ",");
+		cprintf(str, "%d", ip->prefix_length);
+	}
+	cprintf(str, ")");
+}
+
+static void
+dev_path_infini_band(struct string *str, void *dev_path)
+{
+	struct infiniband_device_path *infini_band;
+
+	infini_band = dev_path;
+	cprintf(str, "Infiniband(0x%x,%pU,0x%llx,0x%llx,0x%llx)",
+		infini_band->resource_flags, &infini_band->port_gid,
+		infini_band->service_id, infini_band->target_port_id,
+		infini_band->device_id);
+}
+
+static void
+dev_path_uart(struct string *str, void *dev_path)
+{
+	struct uart_device_path *Uart;
+	s8 Parity;
+
+	Uart = dev_path;
+	switch (Uart->Parity) {
+	case 0:
+		Parity = 'D';
+		break;
+	case 1:
+		Parity = 'N';
+		break;
+	case 2:
+		Parity = 'E';
+		break;
+	case 3:
+		Parity = 'O';
+		break;
+	case 4:
+		Parity = 'M';
+		break;
+	case 5:
+		Parity = 'S';
+		break;
+	default:
+		Parity = 'x';
+		break;
+	}
+
+	if (Uart->baud_rate == 0)
+		cprintf(str, "Uart(DEFAULT %c", Parity);
+	else
+		cprintf(str, "Uart(%lld %c", Uart->baud_rate, Parity);
+
+	if (Uart->data_bits == 0)
+		cprintf(str, "D");
+	else
+		cprintf(str, "%d", Uart->data_bits);
+
+	switch (Uart->stop_bits) {
+	case 0:
+		cprintf(str, "D)");
+		break;
+	case 1:
+		cprintf(str, "1)");
+		break;
+	case 2:
+		cprintf(str, "1.5)");
+		break;
+	case 3:
+		cprintf(str, "2)");
+		break;
+	default:
+		cprintf(str, "x)");
+		break;
+	}
+}
+
+static void
+dev_path_sata(struct string *str, void *dev_path)
+{
+	struct sata_device_path *sata;
+
+	sata = dev_path;
+	cprintf(str, "Sata(0x%x,0x%x,0x%x)", sata->HBAPort_number,
+		sata->port_multiplier_port_number, sata->Lun);
+}
+
+static void
+dev_path_hard_drive(struct string *str, void *dev_path)
+{
+	struct harddrive_device_path *hd;
+
+	hd = dev_path;
+	switch (hd->signature_type) {
+	case SIGNATURE_TYPE_MBR:
+		cprintf(str, "HD(Part%d,Sig%08x)",
+			hd->partition_number, *((u32 *) (&(hd->signature[0])))
+		    );
+		break;
+	case SIGNATURE_TYPE_GUID:
+		cprintf(str, "HD(Part%d,Sig%pU)",
+			hd->partition_number,
+			(efi_guid_t *) & (hd->signature[0])
+		    );
+		break;
+	default:
+		cprintf(str, "HD(Part%d,mbr_type=%02x,sig_type=%02x)",
+			hd->partition_number, hd->mbr_type, hd->signature_type);
+		break;
+	}
+}
+
+static void
+dev_path_cdrom(struct string *str, void *dev_path)
+{
+	struct cdrom_device_path *cd;
+
+	cd = dev_path;
+	cprintf(str, "CDROM(0x%x)", cd->boot_entry);
+}
+
+static void
+dev_path_file_path(struct string *str, void *dev_path)
+{
+	struct filepath_device_path *Fp;
+	char *dst;
+
+	Fp = dev_path;
+
+	dst = strdup_wchar_to_char(Fp->path_name);
+
+	cprintf(str, "%s", dst);
+
+	free(dst);
+}
+
+static void
+dev_path_media_protocol(struct string *str, void *dev_path)
+{
+	struct media_protocol_device_path *media_prot;
+
+	media_prot = dev_path;
+	cprintf(str, "%pU", &media_prot->Protocol);
+}
+
+static void
+dev_path_bss_bss(struct string *str, void *dev_path)
+{
+	struct bbs_bbs_device_path *Bss;
+	char *type;
+
+	Bss = dev_path;
+	switch (Bss->device_type) {
+	case BBS_TYPE_FLOPPY:
+		type = "Floppy";
+		break;
+	case BBS_TYPE_HARDDRIVE:
+		type = "Harddrive";
+		break;
+	case BBS_TYPE_CDROM:
+		type = "CDROM";
+		break;
+	case BBS_TYPE_PCMCIA:
+		type = "PCMCIA";
+		break;
+	case BBS_TYPE_USB:
+		type = "Usb";
+		break;
+	case BBS_TYPE_EMBEDDED_NETWORK:
+		type = "Net";
+		break;
+	default:
+		type = "?";
+		break;
+	}
+
+	cprintf(str, "Bss-%s(%s)", type, Bss->String);
+}
+
+static void
+dev_path_end_instance(struct string *str, void *dev_path)
+{
+	cprintf(str, ",");
+}
+
+/**
+ * Print unknown device node.
+ * UEFI 2.4 § 9.6.1.6 table 89.
+ */
+
+static void
+dev_path_node_unknown(struct string *str, void *dev_path)
+{
+	struct efi_device_path *Path;
+	u8 *value;
+	int length, index;
+	Path = dev_path;
+	value = dev_path;
+	value += 4;
+	switch (Path->type) {
+	case HARDWARE_DEVICE_PATH:{
+			/* Unknown Hardware Device Path */
+			cprintf(str, "hardware_path(%d", Path->sub_type);
+			break;
+		}
+	case ACPI_DEVICE_PATH:{/* Unknown ACPI Device Path */
+			cprintf(str, "acpi_path(%d", Path->sub_type);
+			break;
+		}
+	case MESSAGING_DEVICE_PATH:{
+			/* Unknown Messaging Device Path */
+			cprintf(str, "Msg(%d", Path->sub_type);
+			break;
+		}
+	case MEDIA_DEVICE_PATH:{
+			/* Unknown Media Device Path */
+			cprintf(str, "media_path(%d", Path->sub_type);
+			break;
+		}
+	case BBS_DEVICE_PATH:{	/* Unknown BIOS Boot Specification Device Path */
+			cprintf(str, "bbs_path(%d", Path->sub_type);
+			break;
+		}
+	default:{		/* Unknown Device Path */
+			cprintf(str, "Path(%d,%d", Path->type, Path->sub_type);
+			break;
+		}
+	}
+	length = Path->length;
+	for (index = 0; index < length; index++) {
+		if (index == 0)
+			cprintf(str, ",0x");
+		cprintf(str, "%02x", *value);
+		value++;
+	}
+	cprintf(str, ")");
+}
+
+/*
+ * Table to convert "type" and "sub_type" to a "convert to text" function/
+ * Entries hold "type" and "sub_type" for know values.
+ * Special "sub_type" 0 is used as default for known type with unknown subtype.
+ */
+struct {
+	u8 type;
+	u8 sub_type;
+	void (*Function) (struct string *, void *);
+} dev_path_table[] = {
+	{
+	HARDWARE_DEVICE_PATH, HW_PCI_DP, dev_path_pci}, {
+	HARDWARE_DEVICE_PATH, HW_PCCARD_DP, dev_path_pccard}, {
+	HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, dev_path_mem_map}, {
+	HARDWARE_DEVICE_PATH, HW_VENDOR_DP, dev_path_vendor}, {
+	HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, dev_path_controller}, {
+	ACPI_DEVICE_PATH, ACPI_DP, dev_path_acpi}, {
+	MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, dev_path_atapi}, {
+	MESSAGING_DEVICE_PATH, MSG_SCSI_DP, dev_path_scsi}, {
+	MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, dev_path_fibre}, {
+	MESSAGING_DEVICE_PATH, MSG_1394_DP, dev_path1394}, {
+	MESSAGING_DEVICE_PATH, MSG_USB_DP, dev_path_usb}, {
+	MESSAGING_DEVICE_PATH, MSG_I2_o_DP, dev_path_i2_o}, {
+	MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, dev_path_mac_addr}, {
+	MESSAGING_DEVICE_PATH, MSG_IPv4_DP, dev_path_iPv4}, {
+	MESSAGING_DEVICE_PATH, MSG_IPv6_DP, dev_path_iPv6}, {
+	MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, dev_path_infini_band}, {
+	MESSAGING_DEVICE_PATH, MSG_UART_DP, dev_path_uart}, {
+	MESSAGING_DEVICE_PATH, MSG_SATA_DP, dev_path_sata}, {
+	MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, dev_path_vendor}, {
+	MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, dev_path_hard_drive}, {
+	MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, dev_path_cdrom}, {
+	MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, dev_path_vendor}, {
+	MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, dev_path_file_path}, {
+	MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, dev_path_media_protocol}, {
+	BBS_DEVICE_PATH, BBS_BBS_DP, dev_path_bss_bss}, {
+	END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE,
+		    dev_path_end_instance}, {
+	0, 0, NULL}
+};
+
+static int __device_path_to_str(struct string *str, struct efi_device_path *dev_path)
+{
+	struct efi_device_path *dev_path_node;
+	void (*dump_node) (struct string *, void *);
+	int i;
+
+	dev_path = unpack_device_path(dev_path);
+
+	dev_path_node = dev_path;
+	while (!is_device_path_end(dev_path_node)) {
+		dump_node = NULL;
+		for (i = 0; dev_path_table[i].Function; i += 1) {
+
+			if (device_path_type(dev_path_node) ==
+			    dev_path_table[i].type
+			    && dev_path_node->sub_type ==
+			    dev_path_table[i].sub_type) {
+				dump_node = dev_path_table[i].Function;
+				break;
+			}
+		}
+
+		if (!dump_node)
+			dump_node = dev_path_node_unknown;
+
+		if (str->len && dump_node != dev_path_end_instance)
+			cprintf(str, "/");
+
+		dump_node(str, dev_path_node);
+
+		dev_path_node = next_device_path_node(dev_path_node);
+	}
+
+	return 0;
+}
+
+char *device_path_to_str(struct efi_device_path *dev_path)
+{
+	struct string str = {};
+
+	__device_path_to_str(&str, dev_path);
+
+	str.str = malloc(str.len + 1);
+	if (!str.str)
+		return NULL;
+
+	str.len = 0;
+
+	__device_path_to_str(&str, dev_path);
+
+	return str.str;
+}
diff --git a/common/efi-guid.c b/common/efi-guid.c
new file mode 100644
index 0000000..5109b5d
--- /dev/null
+++ b/common/efi-guid.c
@@ -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;
diff --git a/common/memory.c b/common/memory.c
index 7dbd7f4..4a8fe28 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -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)
 {
 	/*
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index ee1326e..dcb9541 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -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;
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 45f77a7..2b28cf3 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -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
diff --git a/include/efi.h b/include/efi.h
index 9911fa1..c624eb3 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -14,6 +14,9 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
+#define EFIAPI __attribute__((ms_abi))
+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 +55,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 +114,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 +153,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 +173,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 +245,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 +262,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 +330,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)
 
@@ -356,63 +374,20 @@ typedef struct {
 
 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 +404,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 +429,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
+
+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;
+};
 
-/*
- * 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_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 */
-- 
2.0.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 18/21] net: Add EFI Simple Network Protocol Driver
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (16 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 17/21] Add initial EFI architecture support Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 19/21] serial: Add EFI stdio driver Sascha Hauer
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 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] 32+ messages in thread

* [PATCH 19/21] serial: Add EFI stdio driver
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (17 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 18/21] net: Add EFI Simple Network Protocol Driver Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 20/21] fs: implement EFI filesystem driver Sascha Hauer
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 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] 32+ messages in thread

* [PATCH 20/21] fs: implement EFI filesystem driver
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (18 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 19/21] serial: Add EFI stdio driver Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:50 ` [PATCH 21/21] fs: implement EFI variable " Sascha Hauer
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 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    | 559 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 568 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..cea1dda
--- /dev/null
+++ b/fs/efi.c
@@ -0,0 +1,559 @@
+/*
+ * 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 = strdup_char_to_wchar(path);
+	wchar_t *ret;
+
+	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] 32+ messages in thread

* [PATCH 21/21] fs: implement EFI variable filesystem driver
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (19 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 20/21] fs: implement EFI filesystem driver Sascha Hauer
@ 2014-07-08  8:50 ` Sascha Hauer
  2014-07-08  8:53 ` Initial EFI Support Jean-Christophe PLAGNIOL-VILLARD
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:50 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] 32+ messages in thread

* Re: Initial EFI Support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (20 preceding siblings ...)
  2014-07-08  8:50 ` [PATCH 21/21] fs: implement EFI variable " Sascha Hauer
@ 2014-07-08  8:53 ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-08  8:59   ` Sascha Hauer
  2014-07-08 10:04 ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-08 16:38 ` [PATCH 1/2] EFI: enable printf UUID support Jean-Christophe PLAGNIOL-VILLARD
  23 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-07-08  8:53 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox


On Jul 8, 2014, at 4:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:

> 
> The following adds initial support for running barebox as an EFI
> payload on X86 PCs.
> 
> Several things are implemented already to make it useful and
> to look around in an EFI system:
> 
> - Simple Network Protocol for networking
> - Start applications for installing drivers and starting Linux
> - Access EFI provided filesystems
> - Block device access
> 
> The EFI Port still has some rough edges. The screen output is limited
> to 80x25 and the keyboard driver doesn't recognize ctrl-C. I couldn't
> get find a proper UEFI serial driver yet, so the serial port is accessed
> via inb/outb on ioport 0x3f8 and not via UEFI.
> 
> For those interested in EFI and X86 hardware this port still offers
> some interesting insights in EFI.
> 
> There's also even Documentation available, see Patch 16/21.
> 
> Sascha

can you put on a git somewhere
> 
> ----------------------------------------------------------------
> Sascha Hauer (21):
>      Make IPaddr_t a 32bit type
>      oftree command: Use size_t for size
>      fat: Use correct format specifier
>      readkey: keys are unsugned char
>      of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources
>      console: Add puts callback to console devices
>      Add hex_byte_pack and hex_byte_pack_upper from kernel
>      vsprintf: Support pU for printing UUIDs
>      Add beginning wchar support
>      block: Add flush callback
>      Move efi.h to include/
>      filetype: Add DOS EXE file detection support
>      efi: Add more error codes
>      serial: ns16550: Add mmiobase to private data
>      serial: ns16550: Add register read/write function pointers to private data
>      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
> 
> Documentation/boards/efi.rst               |  279 ++++++
> Documentation/glossary.rst                 |    3 +
> arch/efi/Kconfig                           |   47 +
> arch/efi/Makefile                          |   41 +
> arch/efi/configs/efi_defconfig             |   73 ++
> 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                  |  348 +++++++
> arch/efi/efi/efi-image.c                   |  105 +++
> arch/efi/efi/efi.c                         |  342 +++++++
> 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 +-
> commands/oftree.c                          |    2 +-
> common/Kconfig                             |    8 +
> common/Makefile                            |    4 +-
> common/block.c                             |    3 +
> common/console.c                           |   29 +
> common/efi-devicepath.c                    | 1370 ++++++++++++++++++++++++++++
> common/efi-guid.c                          |   11 +
> common/filetype.c                          |    4 +
> common/memory.c                            |    2 +-
> common/partitions/efi.c                    |    2 +-
> common/partitions/efi.h                    |    2 +-
> drivers/net/Kconfig                        |    4 +
> drivers/net/Makefile                       |    1 +
> drivers/net/efi-snp.c                      |  296 ++++++
> drivers/of/Kconfig                         |    2 +-
> drivers/of/platform.c                      |    3 +-
> drivers/serial/Kconfig                     |    4 +
> drivers/serial/Makefile                    |    1 +
> drivers/serial/efi-stdio.c                 |  367 ++++++++
> drivers/serial/serial_ns16550.c            |  237 ++---
> fs/Kconfig                                 |   15 +
> fs/Makefile                                |    2 +
> fs/efi.c                                   |  559 ++++++++++++
> fs/efivarfs.c                              |  340 +++++++
> fs/fat/fat.c                               |    4 +-
> include/block.h                            |    1 +
> include/console.h                          |    1 +
> include/efi.h                              |  508 +++++++++++
> include/filetype.h                         |    1 +
> include/linux/efi.h                        |  547 -----------
> include/linux/kernel.h                     |   23 +-
> include/param.h                            |    2 +-
> include/wchar.h                            |   16 +
> lib/Kconfig                                |    3 +
> lib/Makefile                               |    1 +
> lib/misc.c                                 |    3 +
> lib/readkey.c                              |    2 +-
> lib/vsprintf.c                             |   62 ++
> lib/wchar.c                                |   80 ++
> 76 files changed, 6319 insertions(+), 676 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
> create mode 100644 include/efi.h
> delete mode 100644 include/linux/efi.h
> create mode 100644 include/wchar.h
> create mode 100644 lib/wchar.c
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Initial EFI Support
  2014-07-08  8:53 ` Initial EFI Support Jean-Christophe PLAGNIOL-VILLARD
@ 2014-07-08  8:59   ` Sascha Hauer
  2014-07-08  9:52     ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  8:59 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Tue, Jul 08, 2014 at 04:53:30PM +0800, Jean-Christophe PLAGNIOL-VILLARD wrote:
> 
> On Jul 8, 2014, at 4:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > 
> > The following adds initial support for running barebox as an EFI
> > payload on X86 PCs.
> > 
> > Several things are implemented already to make it useful and
> > to look around in an EFI system:
> > 
> > - Simple Network Protocol for networking
> > - Start applications for installing drivers and starting Linux
> > - Access EFI provided filesystems
> > - Block device access
> > 
> > The EFI Port still has some rough edges. The screen output is limited
> > to 80x25 and the keyboard driver doesn't recognize ctrl-C. I couldn't
> > get find a proper UEFI serial driver yet, so the serial port is accessed
> > via inb/outb on ioport 0x3f8 and not via UEFI.
> > 
> > For those interested in EFI and X86 hardware this port still offers
> > some interesting insights in EFI.
> > 
> > There's also even Documentation available, see Patch 16/21.
> > 
> > Sascha
> 
> can you put on a git somewhere

Just did that:

git://git.pengutronix.de/git efi

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 16/21] Documentation: Add EFI documentation
  2014-07-08  8:50 ` [PATCH 16/21] Documentation: Add EFI documentation Sascha Hauer
@ 2014-07-08  9:04   ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-07-08  9:04 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

> +  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
horrible windows stuff ;-)
> +                   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

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Initial EFI Support
  2014-07-08  8:59   ` Sascha Hauer
@ 2014-07-08  9:52     ` Sascha Hauer
  0 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-08  9:52 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Tue, Jul 08, 2014 at 10:59:24AM +0200, Sascha Hauer wrote:
> On Tue, Jul 08, 2014 at 04:53:30PM +0800, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > 
> > On Jul 8, 2014, at 4:49 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > 
> > > The following adds initial support for running barebox as an EFI
> > > payload on X86 PCs.
> > > 
> > > Several things are implemented already to make it useful and
> > > to look around in an EFI system:
> > > 
> > > - Simple Network Protocol for networking
> > > - Start applications for installing drivers and starting Linux
> > > - Access EFI provided filesystems
> > > - Block device access
> > > 
> > > The EFI Port still has some rough edges. The screen output is limited
> > > to 80x25 and the keyboard driver doesn't recognize ctrl-C. I couldn't
> > > get find a proper UEFI serial driver yet, so the serial port is accessed
> > > via inb/outb on ioport 0x3f8 and not via UEFI.
> > > 
> > > For those interested in EFI and X86 hardware this port still offers
> > > some interesting insights in EFI.
> > > 
> > > There's also even Documentation available, see Patch 16/21.
> > > 
> > > Sascha
> > 
> > can you put on a git somewhere
> 
> Just did that:
> 
> git://git.pengutronix.de/git efi

I meant:

git://git.pengutronix.de/barebox.git

The master repository.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Initial EFI Support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (21 preceding siblings ...)
  2014-07-08  8:53 ` Initial EFI Support Jean-Christophe PLAGNIOL-VILLARD
@ 2014-07-08 10:04 ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-08 16:38 ` [PATCH 1/2] EFI: enable printf UUID support Jean-Christophe PLAGNIOL-VILLARD
  23 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-07-08 10:04 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hi,

	as tested with Sascha

	you can run it from qemu (more easy to debug)

	first you will need an EFI binary
	you can use this one
	http://ufpr.dl.sourceforge.net/project/edk2/OVMF/OVMF-X64-r15214.zip

	and then you need to create a vfat FS

	dd if=/dev/zero bs=1M count=10 > dosfs; mkfs.vfat dosfs

	in the dosfs mounted copy the barebox.efi in /EFI/BOOT/ as BOOTx64.efi

	and finally the magic

	qemu-system-x86_64 -pflash OVMF.fd -nographic dosfs

Best Regards,
J.
On 10:49 Tue 08 Jul     , Sascha Hauer wrote:
> 
> The following adds initial support for running barebox as an EFI
> payload on X86 PCs.
> 
> Several things are implemented already to make it useful and
> to look around in an EFI system:
> 
> - Simple Network Protocol for networking
> - Start applications for installing drivers and starting Linux
> - Access EFI provided filesystems
> - Block device access
> 
> The EFI Port still has some rough edges. The screen output is limited
> to 80x25 and the keyboard driver doesn't recognize ctrl-C. I couldn't
> get find a proper UEFI serial driver yet, so the serial port is accessed
> via inb/outb on ioport 0x3f8 and not via UEFI.
> 
> For those interested in EFI and X86 hardware this port still offers
> some interesting insights in EFI.
> 
> There's also even Documentation available, see Patch 16/21.
> 
> Sascha
> 
> ----------------------------------------------------------------
> Sascha Hauer (21):
>       Make IPaddr_t a 32bit type
>       oftree command: Use size_t for size
>       fat: Use correct format specifier
>       readkey: keys are unsugned char
>       of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources
>       console: Add puts callback to console devices
>       Add hex_byte_pack and hex_byte_pack_upper from kernel
>       vsprintf: Support pU for printing UUIDs
>       Add beginning wchar support
>       block: Add flush callback
>       Move efi.h to include/
>       filetype: Add DOS EXE file detection support
>       efi: Add more error codes
>       serial: ns16550: Add mmiobase to private data
>       serial: ns16550: Add register read/write function pointers to private data
>       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
> 
>  Documentation/boards/efi.rst               |  279 ++++++
>  Documentation/glossary.rst                 |    3 +
>  arch/efi/Kconfig                           |   47 +
>  arch/efi/Makefile                          |   41 +
>  arch/efi/configs/efi_defconfig             |   73 ++
>  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                  |  348 +++++++
>  arch/efi/efi/efi-image.c                   |  105 +++
>  arch/efi/efi/efi.c                         |  342 +++++++
>  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 +-
>  commands/oftree.c                          |    2 +-
>  common/Kconfig                             |    8 +
>  common/Makefile                            |    4 +-
>  common/block.c                             |    3 +
>  common/console.c                           |   29 +
>  common/efi-devicepath.c                    | 1370 ++++++++++++++++++++++++++++
>  common/efi-guid.c                          |   11 +
>  common/filetype.c                          |    4 +
>  common/memory.c                            |    2 +-
>  common/partitions/efi.c                    |    2 +-
>  common/partitions/efi.h                    |    2 +-
>  drivers/net/Kconfig                        |    4 +
>  drivers/net/Makefile                       |    1 +
>  drivers/net/efi-snp.c                      |  296 ++++++
>  drivers/of/Kconfig                         |    2 +-
>  drivers/of/platform.c                      |    3 +-
>  drivers/serial/Kconfig                     |    4 +
>  drivers/serial/Makefile                    |    1 +
>  drivers/serial/efi-stdio.c                 |  367 ++++++++
>  drivers/serial/serial_ns16550.c            |  237 ++---
>  fs/Kconfig                                 |   15 +
>  fs/Makefile                                |    2 +
>  fs/efi.c                                   |  559 ++++++++++++
>  fs/efivarfs.c                              |  340 +++++++
>  fs/fat/fat.c                               |    4 +-
>  include/block.h                            |    1 +
>  include/console.h                          |    1 +
>  include/efi.h                              |  508 +++++++++++
>  include/filetype.h                         |    1 +
>  include/linux/efi.h                        |  547 -----------
>  include/linux/kernel.h                     |   23 +-
>  include/param.h                            |    2 +-
>  include/wchar.h                            |   16 +
>  lib/Kconfig                                |    3 +
>  lib/Makefile                               |    1 +
>  lib/misc.c                                 |    3 +
>  lib/readkey.c                              |    2 +-
>  lib/vsprintf.c                             |   62 ++
>  lib/wchar.c                                |   80 ++
>  76 files changed, 6319 insertions(+), 676 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
>  create mode 100644 include/efi.h
>  delete mode 100644 include/linux/efi.h
>  create mode 100644 include/wchar.h
>  create mode 100644 lib/wchar.c
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 1/2] EFI: enable printf UUID support
  2014-07-08  8:49 Initial EFI Support Sascha Hauer
                   ` (22 preceding siblings ...)
  2014-07-08 10:04 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2014-07-08 16:38 ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-08 16:38   ` [PATCH 2/2] EFI: introduce efi_strguid to convert GUID to human readable names Jean-Christophe PLAGNIOL-VILLARD
  23 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-07-08 16:38 UTC (permalink / raw)
  To: barebox

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 arch/efi/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/efi/Kconfig b/arch/efi/Kconfig
index f67ed9d..ed76b1e 100644
--- a/arch/efi/Kconfig
+++ b/arch/efi/Kconfig
@@ -6,6 +6,7 @@ config ARCH_EFI
 	select HAVE_DEFAULT_ENVIRONMENT_NEW
 	select EFI_GUID
 	select EFI_DEVICEPATH
+	select PRINTF_UUID
 
 config ARCH_TEXT_BASE
 	hex
-- 
1.9.rc1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 2/2] EFI: introduce efi_strguid to convert GUID to human readable names
  2014-07-08 16:38 ` [PATCH 1/2] EFI: enable printf UUID support Jean-Christophe PLAGNIOL-VILLARD
@ 2014-07-08 16:38   ` Jean-Christophe PLAGNIOL-VILLARD
  2014-07-11  7:23     ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2014-07-08 16:38 UTC (permalink / raw)
  To: barebox

use in devinfo Protocols

Tested today on qemu with all the GUID translated

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 arch/efi/efi/efi-device.c   |   3 +-
 arch/efi/efi/efi.c          |  74 ++++++++++++++++++++++++++++++
 arch/efi/include/mach/efi.h |   1 +
 include/efi.h               | 108 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/arch/efi/efi/efi-device.c b/arch/efi/efi/efi-device.c
index 71526b9..7f49924 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_strguid(&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..736b158 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>
 
@@ -227,6 +228,79 @@ int efi_errno(efi_status_t err)
 	return ret;
 }
 
+#define EFI_GUID_STRING(guid, short, long) do {	\
+	if (!efi_guidcmp(guid, *g))		\
+		return long;			\
+	} while(0)
+
+const char *efi_strguid(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";
+}
+
 static struct NS16550_plat ns16550_plat = {
 	.clock = 115200 * 16,
 };
diff --git a/arch/efi/include/mach/efi.h b/arch/efi/include/mach/efi.h
index 1e9782a..eb5171e 100644
--- a/arch/efi/include/mach/efi.h
+++ b/arch/efi/include/mach/efi.h
@@ -4,6 +4,7 @@
 #include <efi.h>
 
 const char *efi_strerror(efi_status_t err);
+const char *efi_strguid(efi_guid_t *g);
 
 extern efi_system_table_t *efi_sys_table;
 extern efi_handle_t efi_parent_image;
diff --git a/include/efi.h b/include/efi.h
index c624eb3..861dc50 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -354,6 +354,114 @@ 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;
-- 
1.9.rc1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 2/2] EFI: introduce efi_strguid to convert GUID to human readable names
  2014-07-08 16:38   ` [PATCH 2/2] EFI: introduce efi_strguid to convert GUID to human readable names Jean-Christophe PLAGNIOL-VILLARD
@ 2014-07-11  7:23     ` Sascha Hauer
  0 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-11  7:23 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

On Tue, Jul 08, 2014 at 06:38:34PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> use in devinfo Protocols
> 
> Tested today on qemu with all the GUID translated
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

I added this to my series with one change. I added the string conversion
function to common/efi-guid.c since it can be used on other
architectures aswell (for example should we ever decide to not only run
on EFI, but also provide EFI functionality).

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 09/21] Add beginning wchar support
  2014-07-08  8:50 ` [PATCH 09/21] Add beginning wchar support Sascha Hauer
@ 2014-07-11 12:35   ` Antony Pavlov
  2014-07-14  6:05     ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Antony Pavlov @ 2014-07-11 12:35 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On Tue,  8 Jul 2014 10:50:05 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

  CC      lib/wchar.o
lib/wchar.c:24:8: warning: no previous prototype for 'wcslen' [-Wmissing-prototypes]
 size_t wcslen(const wchar_t *s)
        ^

> EFI uses 16 bit character strings. Add beginning support for this.
> Since barebox uses 8 bit strings internally we need conversion functions
> to convert between 16 bit and 8 bit strings.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  include/wchar.h | 16 ++++++++++++
>  lib/Makefile    |  1 +
>  lib/misc.c      |  1 +
>  lib/wchar.c     | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+)
>  create mode 100644 include/wchar.h
>  create mode 100644 lib/wchar.c
> 
> diff --git a/include/wchar.h b/include/wchar.h
> new file mode 100644
> index 0000000..278a189
> --- /dev/null
> +++ b/include/wchar.h
> @@ -0,0 +1,16 @@
> +#ifndef __WCHAR_H
> +#define __WCHAR_H
> +
> +#include <linux/types.h>
> +
> +typedef u16 wchar_t;
> +
> +char *strcpy_wchar_to_char(char *dst, const wchar_t *src);
> +
> +wchar_t *strcpy_char_to_wchar(wchar_t *dst, const char *src);
> +
> +wchar_t *strdup_char_to_wchar(const char *src);
> +
> +char *strdup_wchar_to_char(const wchar_t *src);
> +
> +#endif /* __WCHAR_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index e8769a9..48c953d 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -44,3 +44,4 @@ obj-y			+= gui/
>  obj-$(CONFIG_XYMODEM)	+= xymodem.o
>  obj-y			+= unlink-recursive.o
>  obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
> +obj-y			+= wchar.o
> diff --git a/lib/misc.c b/lib/misc.c
> index 9f2067c..87626c1 100644
> --- a/lib/misc.c
> +++ b/lib/misc.c
> @@ -21,6 +21,7 @@
>  #include <malloc.h>
>  #include <errno.h>
>  #include <fs.h>
> +#include <string.h>
>  #include <linux/ctype.h>
>  
>  /*
> diff --git a/lib/wchar.c b/lib/wchar.c
> new file mode 100644
> index 0000000..6368a01
> --- /dev/null
> +++ b/lib/wchar.c
> @@ -0,0 +1,80 @@
> +/*
> + * wchar.c - wide character 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 <wchar.h>
> +#include <malloc.h>
> +#include <string.h>
> +
> +size_t wcslen(const wchar_t *s)
> +{
> +	size_t len = 0;
> +
> +	while (*s++)
> +		len++;
> +
> +	return len;
> +}
> +
> +char *strcpy_wchar_to_char(char *dst, const wchar_t *src)
> +{
> +	char *ret = dst;
> +
> +	while (*src)
> +		*dst++ = *src++ & 0xff;
> +
> +	*dst = 0;
> +
> +	return ret;
> +}
> +
> +wchar_t *strcpy_char_to_wchar(wchar_t *dst, const char *src)
> +{
> +	wchar_t *ret = dst;
> +
> +	while (*src)
> +		*dst++ = *src++;
> +
> +	*dst = 0;
> +
> +	return ret;
> +}
> +
> +wchar_t *strdup_char_to_wchar(const char *src)
> +{
> +	wchar_t *dst = malloc((strlen(src) + 1) * sizeof(wchar_t));
> +
> +	if (!dst)
> +		return NULL;
> +
> +	strcpy_char_to_wchar(dst, src);
> +
> +	return dst;
> +}
> +
> +char *strdup_wchar_to_char(const wchar_t *src)
> +{
> +	char *dst = malloc((wcslen(src) + 1));
> +
> +	if (!dst)
> +		return NULL;
> +
> +	strcpy_wchar_to_char(dst, src);
> +
> +	return dst;
> +}
> -- 
> 2.0.0
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 09/21] Add beginning wchar support
  2014-07-11 12:35   ` Antony Pavlov
@ 2014-07-14  6:05     ` Sascha Hauer
  0 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2014-07-14  6:05 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

On Fri, Jul 11, 2014 at 04:35:32PM +0400, Antony Pavlov wrote:
> On Tue,  8 Jul 2014 10:50:05 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
>   CC      lib/wchar.o
> lib/wchar.c:24:8: warning: no previous prototype for 'wcslen' [-Wmissing-prototypes]
>  size_t wcslen(const wchar_t *s)

Should be fixed now. Thanks for noting

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2014-07-14  6:06 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-08  8:49 Initial EFI Support Sascha Hauer
2014-07-08  8:49 ` [PATCH 01/21] Make IPaddr_t a 32bit type Sascha Hauer
2014-07-08  8:49 ` [PATCH 02/21] oftree command: Use size_t for size Sascha Hauer
2014-07-08  8:49 ` [PATCH 03/21] fat: Use correct format specifier Sascha Hauer
2014-07-08  8:50 ` [PATCH 04/21] readkey: keys are unsugned char Sascha Hauer
2014-07-08  8:50 ` [PATCH 05/21] of: platform: Use PRINTF_CONVERSION_RESOURCE for printing resources Sascha Hauer
2014-07-08  8:50 ` [PATCH 06/21] console: Add puts callback to console devices Sascha Hauer
2014-07-08  8:50 ` [PATCH 07/21] Add hex_byte_pack and hex_byte_pack_upper from kernel Sascha Hauer
2014-07-08  8:50 ` [PATCH 08/21] vsprintf: Support pU for printing UUIDs Sascha Hauer
2014-07-08  8:50 ` [PATCH 09/21] Add beginning wchar support Sascha Hauer
2014-07-11 12:35   ` Antony Pavlov
2014-07-14  6:05     ` Sascha Hauer
2014-07-08  8:50 ` [PATCH 10/21] block: Add flush callback Sascha Hauer
2014-07-08  8:50 ` [PATCH 11/21] Move efi.h to include/ Sascha Hauer
2014-07-08  8:50 ` [PATCH 12/21] filetype: Add DOS EXE file detection support Sascha Hauer
2014-07-08  8:50 ` [PATCH 13/21] efi: Add more error codes Sascha Hauer
2014-07-08  8:50 ` [PATCH 14/21] serial: ns16550: Add mmiobase to private data Sascha Hauer
2014-07-08  8:50 ` [PATCH 15/21] serial: ns16550: Add register read/write function pointers " Sascha Hauer
2014-07-08  8:50 ` [PATCH 16/21] Documentation: Add EFI documentation Sascha Hauer
2014-07-08  9:04   ` Jean-Christophe PLAGNIOL-VILLARD
2014-07-08  8:50 ` [PATCH 17/21] Add initial EFI architecture support Sascha Hauer
2014-07-08  8:50 ` [PATCH 18/21] net: Add EFI Simple Network Protocol Driver Sascha Hauer
2014-07-08  8:50 ` [PATCH 19/21] serial: Add EFI stdio driver Sascha Hauer
2014-07-08  8:50 ` [PATCH 20/21] fs: implement EFI filesystem driver Sascha Hauer
2014-07-08  8:50 ` [PATCH 21/21] fs: implement EFI variable " Sascha Hauer
2014-07-08  8:53 ` Initial EFI Support Jean-Christophe PLAGNIOL-VILLARD
2014-07-08  8:59   ` Sascha Hauer
2014-07-08  9:52     ` Sascha Hauer
2014-07-08 10:04 ` Jean-Christophe PLAGNIOL-VILLARD
2014-07-08 16:38 ` [PATCH 1/2] EFI: enable printf UUID support Jean-Christophe PLAGNIOL-VILLARD
2014-07-08 16:38   ` [PATCH 2/2] EFI: introduce efi_strguid to convert GUID to human readable names Jean-Christophe PLAGNIOL-VILLARD
2014-07-11  7:23     ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox