mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 01/10] efi: add proper reset hook
@ 2014-11-04  9:42 Lucas Stach
  2014-11-04  9:42 ` [PATCH 02/10] efi: add Barebox GUID Lucas Stach
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

This allows to actually reset the system from barebox
instead of dropping back into the EFI firmware.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 arch/efi/efi/efi.c |  2 +-
 include/efi.h      | 11 +++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index 7de8ec82e8fa..af3fc4366ba1 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -248,7 +248,7 @@ console_initcall(efi_console_init);
 
 void reset_cpu(unsigned long addr)
 {
-	BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
+	RT->reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
 
 	while(1);
 }
diff --git a/include/efi.h b/include/efi.h
index 4ad9f69237e7..70fe254dbafa 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -255,9 +255,11 @@ extern efi_boot_services_t *BS;
 /*
  * Types and defines for EFI ResetSystem
  */
-#define EFI_RESET_COLD 0
-#define EFI_RESET_WARM 1
-#define EFI_RESET_SHUTDOWN 2
+typedef enum {
+	EFI_RESET_COLD = 0,
+	EFI_RESET_WARM = 1,
+	EFI_RESET_SHUTDOWN = 2
+} efi_reset_type_t;
 
 /*
  * EFI Runtime Services table
@@ -279,7 +281,8 @@ typedef struct {
 			s16 *variable_name, efi_guid_t *vendor);
 	void *set_variable;
 	void *get_next_high_mono_count;
-	void *reset_system;
+	void (EFIAPI *reset_system)(efi_reset_type_t reset_type, efi_status_t reset_status,
+			unsigned long data_size, void *reset_data);
 	void *update_capsule;
 	void *query_capsule_caps;
 	void *query_variable_info;
-- 
2.1.1


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

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

* [PATCH 02/10] efi: add Barebox GUID
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-05  7:21   ` Sascha Hauer
  2014-11-04  9:42 ` [PATCH 03/10] fs: efivar: cosmetic changes Lucas Stach
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

A proper GUID is needed to namespace all sorts of
things, most prominently persistent variables.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 include/efi.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/efi.h b/include/efi.h
index 70fe254dbafa..507115881b55 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -468,6 +468,10 @@ extern efi_runtime_services_t *RT;
 #define EFI_VLANCONFIGDXE_INF_GUID \
 	EFI_GUID(0xe4f61863, 0xfe2c, 0x4b56, 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf)
 
+/* barebox specific GUIDs */
+#define EFI_BAREBOX_VENDOR_GUID \
+	EFI_GUID(0x5b91f69c, 0x8b88, 0x4a2b, 0x92, 0x69, 0x5f, 0x1d, 0x80, 0x2b, 0x51, 0x75)
+
 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;
-- 
2.1.1


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

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

* [PATCH 03/10] fs: efivar: cosmetic changes
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
  2014-11-04  9:42 ` [PATCH 02/10] efi: add Barebox GUID Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 04/10] fs: efivar: switch to standard list implementation Lucas Stach
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index 58c637ef19b4..4e13c8365e0e 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -1,7 +1,7 @@
 /*
- * ramfs.c - a malloc based filesystem
+ * efivars.c - EFI variable filesystem
  *
- * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -75,8 +75,8 @@ int efi_guid_parse(const char *str, efi_guid_t *guid)
 			if (*str != '-')
 				return -EINVAL;
 			str++;
-                        break;
-                }
+			break;
+		}
 	}
 
 	return 0;
-- 
2.1.1


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

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

* [PATCH 04/10] fs: efivar: switch to standard list implementation
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
  2014-11-04  9:42 ` [PATCH 02/10] efi: add Barebox GUID Lucas Stach
  2014-11-04  9:42 ` [PATCH 03/10] fs: efivar: cosmetic changes Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 05/10] fs: efivar: move variable discovery into probe Lucas Stach
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Cleans the code a bit and will allow us to implement
removing of vars quite a bit easier.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index 4e13c8365e0e..fda5d7449e4f 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -196,12 +196,12 @@ static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
 
 struct efivarfs_dir_entry {
 	char *name;
-	struct efivarfs_dir_entry *next;
+	struct list_head node;
 };
 
 struct efivarfs_dir {
-	struct efivarfs_dir_entry *first;
-	struct efivarfs_dir_entry *current;
+	struct list_head entries;
+	struct list_head *current;
 	DIR dir;
 };
 
@@ -217,6 +217,7 @@ static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
 	name[0] = 0;
 
 	edir = xzalloc(sizeof(*edir));
+	INIT_LIST_HEAD(&edir->entries);
 
 	while (1) {
 		struct efivarfs_dir_entry *entry;
@@ -230,19 +231,12 @@ static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
 		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;
+		list_add_tail(&entry->node, &edir->entries);
 	}
 
-	edir->current = edir->first;
+	edir->current = edir->entries.next;
 
 	return &edir->dir;
 }
@@ -250,11 +244,14 @@ static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
 static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 {
 	struct efivarfs_dir *edir = container_of(dir, struct efivarfs_dir, dir);
+	struct efivarfs_dir_entry *entry;
 
-	if (!edir->current)
+	if (edir->current == &edir->entries)
 		return NULL;
 
-	strcpy(dir->d.d_name, edir->current->name);
+	entry = list_entry(edir->current, struct efivarfs_dir_entry, node);
+
+	strcpy(dir->d.d_name, entry->name);
 
 	edir->current = edir->current->next;
 
@@ -264,16 +261,11 @@ static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 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;
+	struct efivarfs_dir_entry *entry, *tmp;
 
-	while (entry) {
-		struct efivarfs_dir_entry *tmp;
+	list_for_each_entry_safe(entry, tmp, &edir->entries, node) {
 		free(entry->name);
-		tmp = entry->next;
 		free(entry);
-		entry = tmp;
 	}
 
 	free(edir);
-- 
2.1.1


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

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

* [PATCH 05/10] fs: efivar: move variable discovery into probe
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (2 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 04/10] fs: efivar: switch to standard list implementation Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 06/10] lib: add wchar strdup Lucas Stach
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

So we can manipulate things easier.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 109 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 58 insertions(+), 51 deletions(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index fda5d7449e4f..aa66aa8dd99d 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -34,9 +34,18 @@
 #include <mach/efi.h>
 #include <mach/efi-device.h>
 
+struct efivarfs_inode {
+	char *name;
+	struct list_head node;
+};
+
+struct efivarfs_dir {
+	struct list_head *current;
+	DIR dir;
+};
+
 struct efivarfs_priv {
-	struct efi_file_handle *root_dir;
-	struct efi_file_io_interface *protocol;
+	struct list_head inodes;
 };
 
 static int char_to_nibble(char c)
@@ -194,64 +203,29 @@ static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
 	return f->pos;
 }
 
-struct efivarfs_dir_entry {
-	char *name;
-	struct list_head node;
-};
-
-struct efivarfs_dir {
-	struct list_head entries;
-	struct list_head *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_priv *priv = dev->priv;
 	struct efivarfs_dir *edir;
-	unsigned long size;
-	unsigned char *name8;
-
-	name[0] = 0;
 
 	edir = xzalloc(sizeof(*edir));
-	INIT_LIST_HEAD(&edir->entries);
-
-	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);
-
-		list_add_tail(&entry->node, &edir->entries);
-	}
-
-	edir->current = edir->entries.next;
+	edir->current = priv->inodes.next;
 
 	return &edir->dir;
 }
 
 static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 {
+	struct efivarfs_priv *priv = dev->priv;
 	struct efivarfs_dir *edir = container_of(dir, struct efivarfs_dir, dir);
-	struct efivarfs_dir_entry *entry;
+	struct efivarfs_inode *inode;
 
-	if (edir->current == &edir->entries)
+	if (edir->current == &priv->inodes)
 		return NULL;
 
-	entry = list_entry(edir->current, struct efivarfs_dir_entry, node);
+	inode = list_entry(edir->current, struct efivarfs_inode, node);
 
-	strcpy(dir->d.d_name, entry->name);
+	strcpy(dir->d.d_name, inode->name);
 
 	edir->current = edir->current->next;
 
@@ -261,12 +235,6 @@ static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 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, *tmp;
-
-	list_for_each_entry_safe(entry, tmp, &edir->entries, node) {
-		free(entry->name);
-		free(entry);
-	}
 
 	free(edir);
 
@@ -300,12 +268,51 @@ static int efivarfs_stat(struct device_d *dev, const char *filename, struct stat
 
 static int efivarfs_probe(struct device_d *dev)
 {
+	efi_status_t efiret;
+	efi_guid_t vendor;
+	s16 name[1024];
+	unsigned long size;
+	unsigned char *name8;
+	struct efivarfs_priv *priv;
+
+	name[0] = 0;
+
+	priv = xzalloc(sizeof(*priv));
+	INIT_LIST_HEAD(&priv->inodes);
+
+	while (1) {
+		struct efivarfs_inode *inode;
+
+		size = sizeof(name);
+		efiret = RT->get_next_variable(&size, name, &vendor);
+		if (EFI_ERROR(efiret))
+			break;
+
+		inode = xzalloc(sizeof(*inode));
+		name8 = strdup_wchar_to_char(name);
+
+		inode->name = asprintf("%s-%pUl", name8, &vendor);
+		free(name8);
+
+		list_add_tail(&inode->node, &priv->inodes);
+	}
+
+	dev->priv = priv;
+
 	return 0;
 }
 
 static void efivarfs_remove(struct device_d *dev)
 {
-	free(dev->priv);
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *inode, *tmp;
+
+	list_for_each_entry_safe(inode, tmp, &priv->inodes, node) {
+		free(inode->name);
+		free(inode);
+	}
+
+	free(priv);
 }
 
 static struct fs_driver_d efivarfs_driver = {
-- 
2.1.1


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

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

* [PATCH 06/10] lib: add wchar strdup
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (3 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 05/10] fs: efivar: move variable discovery into probe Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 07/10] fs: efivar: preserve more info in inode Lucas Stach
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 include/wchar.h |  2 ++
 lib/wchar.c     | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/wchar.h b/include/wchar.h
index 80dcd81bf442..702d8e239a7c 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -5,6 +5,8 @@
 
 typedef u16 wchar_t;
 
+wchar_t *strdup_wchar(const wchar_t *src);
+
 char *strcpy_wchar_to_char(char *dst, const wchar_t *src);
 
 wchar_t *strcpy_char_to_wchar(wchar_t *dst, const char *src);
diff --git a/lib/wchar.c b/lib/wchar.c
index 6368a019941e..b2e9e7545b1f 100644
--- a/lib/wchar.c
+++ b/lib/wchar.c
@@ -31,6 +31,22 @@ size_t wcslen(const wchar_t *s)
 	return len;
 }
 
+wchar_t *strdup_wchar(const wchar_t *src)
+{
+	int len = wcslen(src);
+	wchar_t *tmp, *dst;
+
+	if (!(dst = malloc((len + 1) * sizeof(wchar_t))))
+		return NULL;
+
+	tmp = dst;
+
+	while ((*dst++ = *src++))
+		/* nothing */;
+
+	return tmp;
+}
+
 char *strcpy_wchar_to_char(char *dst, const wchar_t *src)
 {
 	char *ret = dst;
-- 
2.1.1


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

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

* [PATCH 07/10] fs: efivar: preserve more info in inode
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (4 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 06/10] lib: add wchar strdup Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 08/10] fs: efivar: don't store attributes in file Lucas Stach
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Preserve info needed for easy manipulation of variables.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index aa66aa8dd99d..a36020d2d08e 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -35,7 +35,9 @@
 #include <mach/efi-device.h>
 
 struct efivarfs_inode {
-	char *name;
+	s16 *name;
+	efi_guid_t vendor;
+	char *full_name; /* name including vendor namespacing */
 	struct list_head node;
 };
 
@@ -225,7 +227,7 @@ static struct dirent *efivarfs_readdir(struct device_d *dev, DIR *dir)
 
 	inode = list_entry(edir->current, struct efivarfs_inode, node);
 
-	strcpy(dir->d.d_name, inode->name);
+	strcpy(dir->d.d_name, inode->full_name);
 
 	edir->current = edir->current->next;
 
@@ -271,8 +273,8 @@ static int efivarfs_probe(struct device_d *dev)
 	efi_status_t efiret;
 	efi_guid_t vendor;
 	s16 name[1024];
+	char *name8;
 	unsigned long size;
-	unsigned char *name8;
 	struct efivarfs_priv *priv;
 
 	name[0] = 0;
@@ -289,9 +291,12 @@ static int efivarfs_probe(struct device_d *dev)
 			break;
 
 		inode = xzalloc(sizeof(*inode));
-		name8 = strdup_wchar_to_char(name);
+		inode->name = strdup_wchar(name);
+
+		inode->vendor = vendor;
 
-		inode->name = asprintf("%s-%pUl", name8, &vendor);
+		name8 = strdup_wchar_to_char(inode->name);
+		inode->full_name = asprintf("%s-%pUl", name8, &vendor);
 		free(name8);
 
 		list_add_tail(&inode->node, &priv->inodes);
-- 
2.1.1


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

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

* [PATCH 08/10] fs: efivar: don't store attributes in file
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (5 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 07/10] fs: efivar: preserve more info in inode Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 09/10] fs: efivar: implement write support Lucas Stach
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

We don't have a use-case yet where we need to manipulate
the attributes of a variable and it confuses "normal"
users of the variables.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index a36020d2d08e..f54925133848 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -131,6 +131,7 @@ struct efivars_file {
 	unsigned long size;
 	efi_guid_t vendor;
 	s16 *name;
+	u32 attributes;
 };
 
 static int efivarfs_open(struct device_d *dev, FILE *f, const char *filename)
@@ -138,7 +139,6 @@ 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));
 
@@ -146,28 +146,27 @@ static int efivarfs_open(struct device_d *dev, FILE *f, const char *filename)
 	if (ret)
 		return -ENOENT;
 
-	efiret = RT->get_variable(efile->name, &efile->vendor, &attributes, &efile->size, NULL);
+	efiret = RT->get_variable(efile->name, &efile->vendor,
+				  &efile->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));
+	efile->buf = malloc(efile->size);
 	if (!efile->buf) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
 	efiret = RT->get_variable(efile->name, &efile->vendor, NULL, &efile->size,
-			efile->buf + sizeof(uint32_t));
+			efile->buf);
 	if (EFI_ERROR(efiret)) {
 		ret = -efi_errno(efiret);
 		goto out;
 	}
 
-	*(uint32_t *)efile->buf = attributes;
-
-	f->size = efile->size + sizeof(uint32_t);
+	f->size = efile->size;
 	f->inode = efile;
 
 	return 0;
-- 
2.1.1


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

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

* [PATCH 09/10] fs: efivar: implement write support
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (6 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 08/10] fs: efivar: don't store attributes in file Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-04  9:42 ` [PATCH 10/10] efi: mount efivarfs by default if enabled Lucas Stach
  2014-11-05  7:21 ` [PATCH 01/10] efi: add proper reset hook Sascha Hauer
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Implement the standard FS ops for writing/manipulating
efivars.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 fs/efivarfs.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/efi.h |   3 +-
 2 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index f54925133848..9a1503bd1387 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -126,6 +126,75 @@ static int efivarfs_parse_filename(const char *filename, efi_guid_t *vendor, s16
 	return 0;
 }
 
+static int efivars_create(struct device_d *dev, const char *pathname, mode_t mode)
+{
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *inode;
+	efi_guid_t vendor;
+	efi_status_t efiret;
+	u8 dummydata;
+	char *name8;
+	s16 *name;
+	int ret;
+
+	if (pathname[0] == '/')
+		pathname++;
+
+	/* deny creating files with other vendor GUID than our own */
+	ret = efivarfs_parse_filename(pathname, &vendor, &name);
+	if (ret)
+		return -ENOENT;
+
+	if (memcmp(&vendor, &EFI_BAREBOX_VENDOR_GUID, sizeof(efi_guid_t)))
+		return -EPERM;
+
+	inode = xzalloc(sizeof(*inode));
+	inode->name = name;
+	inode->vendor = vendor;
+
+
+	name8 = strdup_wchar_to_char(inode->name);
+	inode->full_name = asprintf("%s-%pUl", name8, &inode->vendor);
+	free(name8);
+
+	efiret = RT->set_variable(inode->name, &inode->vendor,
+				  EFI_VARIABLE_NON_VOLATILE |
+				  EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				  EFI_VARIABLE_RUNTIME_ACCESS,
+				  1, &dummydata);
+	if (EFI_ERROR(efiret)) {
+		free(inode);
+		return -efi_errno(efiret);
+	}
+
+	list_add_tail(&inode->node, &priv->inodes);
+
+	return 0;
+}
+
+static int efivars_unlink(struct device_d *dev, const char *pathname)
+{
+	struct efivarfs_priv *priv = dev->priv;
+	struct efivarfs_inode *inode, *tmp;
+	efi_status_t efiret;
+
+	if (pathname[0] == '/')
+		pathname++;
+
+	list_for_each_entry_safe(inode, tmp, &priv->inodes, node) {
+		if (!strcmp(inode->full_name, pathname)) {
+			efiret = RT->set_variable(inode->name, &inode->vendor,
+						  0, 0, NULL);
+			if (EFI_ERROR(efiret))
+				return -efi_errno(efiret);
+			list_del(&inode->node);
+			free(inode);
+		}
+	}
+
+	return 0;
+}
+
 struct efivars_file {
 	void *buf;
 	unsigned long size;
@@ -197,6 +266,38 @@ static int efivarfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insiz
 	return insize;
 }
 
+static int efivarfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t insize)
+{
+	struct efivars_file *efile = f->inode;
+
+	if (efile->size < f->pos + insize) {
+		efile->buf = realloc(efile->buf, f->pos + insize);
+		efile->size = f->pos + insize;
+	}
+
+	memcpy(efile->buf + f->pos, buf, insize);
+
+	RT->set_variable(efile->name, &efile->vendor, efile->attributes,
+			 efile->size ? efile->size : 1, efile->buf);
+
+	return insize;
+}
+
+static int efivarfs_truncate(struct device_d *dev, FILE *f, ulong size)
+{
+	struct efivars_file *efile = f->inode;
+
+	efile->size = size;
+	efile->buf = realloc(efile->buf, efile->size + sizeof(uint32_t));
+
+	RT->set_variable(efile->name, &efile->vendor, efile->attributes,
+			 efile->size ? efile->size : 1, efile->buf);
+
+	f->size = efile->size;
+
+	return 0;
+}
+
 static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
 {
 	f->pos = pos;
@@ -320,9 +421,13 @@ static void efivarfs_remove(struct device_d *dev)
 }
 
 static struct fs_driver_d efivarfs_driver = {
+	.create    = efivars_create,
+	.unlink    = efivars_unlink,
 	.open      = efivarfs_open,
 	.close     = efivarfs_close,
 	.read      = efivarfs_read,
+	.write     = efivarfs_write,
+	.truncate  = efivarfs_truncate,
 	.lseek     = efivarfs_lseek,
 	.opendir   = efivarfs_opendir,
 	.readdir   = efivarfs_readdir,
diff --git a/include/efi.h b/include/efi.h
index 507115881b55..cc6a0d81a543 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -279,7 +279,8 @@ typedef struct {
 			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;
+	efi_status_t (EFIAPI *set_variable)(s16 *variable_name, efi_guid_t *vendor,
+			u32 Attributes, unsigned long data_size, void *data);
 	void *get_next_high_mono_count;
 	void (EFIAPI *reset_system)(efi_reset_type_t reset_type, efi_status_t reset_status,
 			unsigned long data_size, void *reset_data);
-- 
2.1.1


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

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

* [PATCH 10/10] efi: mount efivarfs by default if enabled
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (7 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 09/10] fs: efivar: implement write support Lucas Stach
@ 2014-11-04  9:42 ` Lucas Stach
  2014-11-05  7:21 ` [PATCH 01/10] efi: add proper reset hook Sascha Hauer
  9 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-04  9:42 UTC (permalink / raw)
  To: barebox

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 common/startup.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/common/startup.c b/common/startup.c
index ceb597b0ebba..14d669a4ff42 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -50,6 +50,12 @@ static int mount_root(void)
 	mount("none", "ramfs", "/", NULL);
 	mkdir("/dev", 0);
 	mount("none", "devfs", "/dev", NULL);
+
+	if (IS_ENABLED(CONFIG_FS_EFIVARFS)) {
+		mkdir("/efivars", 0);
+		mount("none", "efivarfs", "/efivars", NULL);
+	}
+
 	return 0;
 }
 fs_initcall(mount_root);
-- 
2.1.1


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

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

* Re: [PATCH 01/10] efi: add proper reset hook
  2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
                   ` (8 preceding siblings ...)
  2014-11-04  9:42 ` [PATCH 10/10] efi: mount efivarfs by default if enabled Lucas Stach
@ 2014-11-05  7:21 ` Sascha Hauer
  2014-11-05  9:00   ` Lucas Stach
  9 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2014-11-05  7:21 UTC (permalink / raw)
  To: Lucas Stach; +Cc: barebox

On Tue, Nov 04, 2014 at 10:42:47AM +0100, Lucas Stach wrote:
> This allows to actually reset the system from barebox
> instead of dropping back into the EFI firmware.

Now we can reset the system, but not go back into the EFI firmware
anymore. Should we introduce a command to make that possible?

Sascha

> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  arch/efi/efi/efi.c |  2 +-
>  include/efi.h      | 11 +++++++----
>  2 files changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
> index 7de8ec82e8fa..af3fc4366ba1 100644
> --- a/arch/efi/efi/efi.c
> +++ b/arch/efi/efi/efi.c
> @@ -248,7 +248,7 @@ console_initcall(efi_console_init);
>  
>  void reset_cpu(unsigned long addr)
>  {
> -	BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
> +	RT->reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
>  
>  	while(1);
>  }
> diff --git a/include/efi.h b/include/efi.h
> index 4ad9f69237e7..70fe254dbafa 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -255,9 +255,11 @@ extern efi_boot_services_t *BS;
>  /*
>   * Types and defines for EFI ResetSystem
>   */
> -#define EFI_RESET_COLD 0
> -#define EFI_RESET_WARM 1
> -#define EFI_RESET_SHUTDOWN 2
> +typedef enum {
> +	EFI_RESET_COLD = 0,
> +	EFI_RESET_WARM = 1,
> +	EFI_RESET_SHUTDOWN = 2
> +} efi_reset_type_t;
>  
>  /*
>   * EFI Runtime Services table
> @@ -279,7 +281,8 @@ typedef struct {
>  			s16 *variable_name, efi_guid_t *vendor);
>  	void *set_variable;
>  	void *get_next_high_mono_count;
> -	void *reset_system;
> +	void (EFIAPI *reset_system)(efi_reset_type_t reset_type, efi_status_t reset_status,
> +			unsigned long data_size, void *reset_data);
>  	void *update_capsule;
>  	void *query_capsule_caps;
>  	void *query_variable_info;
> -- 
> 2.1.1
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
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] 14+ messages in thread

* Re: [PATCH 02/10] efi: add Barebox GUID
  2014-11-04  9:42 ` [PATCH 02/10] efi: add Barebox GUID Lucas Stach
@ 2014-11-05  7:21   ` Sascha Hauer
  2014-11-05  9:03     ` Lucas Stach
  0 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2014-11-05  7:21 UTC (permalink / raw)
  To: Lucas Stach; +Cc: barebox

On Tue, Nov 04, 2014 at 10:42:48AM +0100, Lucas Stach wrote:
> A proper GUID is needed to namespace all sorts of
> things, most prominently persistent variables.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  include/efi.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/efi.h b/include/efi.h
> index 70fe254dbafa..507115881b55 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -468,6 +468,10 @@ extern efi_runtime_services_t *RT;
>  #define EFI_VLANCONFIGDXE_INF_GUID \
>  	EFI_GUID(0xe4f61863, 0xfe2c, 0x4b56, 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf)
>  
> +/* barebox specific GUIDs */
> +#define EFI_BAREBOX_VENDOR_GUID \
> +	EFI_GUID(0x5b91f69c, 0x8b88, 0x4a2b, 0x92, 0x69, 0x5f, 0x1d, 0x80, 0x2b, 0x51, 0x75)

Can we just make up our own?

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] 14+ messages in thread

* Re: [PATCH 01/10] efi: add proper reset hook
  2014-11-05  7:21 ` [PATCH 01/10] efi: add proper reset hook Sascha Hauer
@ 2014-11-05  9:00   ` Lucas Stach
  0 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-05  9:00 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Am Mittwoch, den 05.11.2014, 08:21 +0100 schrieb Sascha Hauer:
> On Tue, Nov 04, 2014 at 10:42:47AM +0100, Lucas Stach wrote:
> > This allows to actually reset the system from barebox
> > instead of dropping back into the EFI firmware.
> 
> Now we can reset the system, but not go back into the EFI firmware
> anymore. Should we introduce a command to make that possible?
> 
Yes, that makes sense. I'll add a command for that.

> Sascha
> 
> > 
> > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > ---
> >  arch/efi/efi/efi.c |  2 +-
> >  include/efi.h      | 11 +++++++----
> >  2 files changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
> > index 7de8ec82e8fa..af3fc4366ba1 100644
> > --- a/arch/efi/efi/efi.c
> > +++ b/arch/efi/efi/efi.c
> > @@ -248,7 +248,7 @@ console_initcall(efi_console_init);
> >  
> >  void reset_cpu(unsigned long addr)
> >  {
> > -	BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
> > +	RT->reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);
> >  
> >  	while(1);
> >  }
> > diff --git a/include/efi.h b/include/efi.h
> > index 4ad9f69237e7..70fe254dbafa 100644
> > --- a/include/efi.h
> > +++ b/include/efi.h
> > @@ -255,9 +255,11 @@ extern efi_boot_services_t *BS;
> >  /*
> >   * Types and defines for EFI ResetSystem
> >   */
> > -#define EFI_RESET_COLD 0
> > -#define EFI_RESET_WARM 1
> > -#define EFI_RESET_SHUTDOWN 2
> > +typedef enum {
> > +	EFI_RESET_COLD = 0,
> > +	EFI_RESET_WARM = 1,
> > +	EFI_RESET_SHUTDOWN = 2
> > +} efi_reset_type_t;
> >  
> >  /*
> >   * EFI Runtime Services table
> > @@ -279,7 +281,8 @@ typedef struct {
> >  			s16 *variable_name, efi_guid_t *vendor);
> >  	void *set_variable;
> >  	void *get_next_high_mono_count;
> > -	void *reset_system;
> > +	void (EFIAPI *reset_system)(efi_reset_type_t reset_type, efi_status_t reset_status,
> > +			unsigned long data_size, void *reset_data);
> >  	void *update_capsule;
> >  	void *query_capsule_caps;
> >  	void *query_variable_info;
> > -- 
> > 2.1.1
> > 
> > 
> > _______________________________________________
> > barebox mailing list
> > barebox@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox
> > 
> 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

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

* Re: [PATCH 02/10] efi: add Barebox GUID
  2014-11-05  7:21   ` Sascha Hauer
@ 2014-11-05  9:03     ` Lucas Stach
  0 siblings, 0 replies; 14+ messages in thread
From: Lucas Stach @ 2014-11-05  9:03 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Am Mittwoch, den 05.11.2014, 08:21 +0100 schrieb Sascha Hauer:
> On Tue, Nov 04, 2014 at 10:42:48AM +0100, Lucas Stach wrote:
> > A proper GUID is needed to namespace all sorts of
> > things, most prominently persistent variables.
> > 
> > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > ---
> >  include/efi.h | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/include/efi.h b/include/efi.h
> > index 70fe254dbafa..507115881b55 100644
> > --- a/include/efi.h
> > +++ b/include/efi.h
> > @@ -468,6 +468,10 @@ extern efi_runtime_services_t *RT;
> >  #define EFI_VLANCONFIGDXE_INF_GUID \
> >  	EFI_GUID(0xe4f61863, 0xfe2c, 0x4b56, 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf)
> >  
> > +/* barebox specific GUIDs */
> > +#define EFI_BAREBOX_VENDOR_GUID \
> > +	EFI_GUID(0x5b91f69c, 0x8b88, 0x4a2b, 0x92, 0x69, 0x5f, 0x1d, 0x80, 0x2b, 0x51, 0x75)
> 
> Can we just make up our own?
> 
Yes we do. I've looked into this a while and it seems that every EFI
vendor/user is expected to just make up his own GUIDs. There is no
central registry or something except for the GUIDs that are standardized
in the EFI spec. The expectation here seems to be that GUIDs carry
enough entropy to not run into any collision problems.

Regards,
Lucas

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

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

end of thread, other threads:[~2014-11-05  9:03 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-04  9:42 [PATCH 01/10] efi: add proper reset hook Lucas Stach
2014-11-04  9:42 ` [PATCH 02/10] efi: add Barebox GUID Lucas Stach
2014-11-05  7:21   ` Sascha Hauer
2014-11-05  9:03     ` Lucas Stach
2014-11-04  9:42 ` [PATCH 03/10] fs: efivar: cosmetic changes Lucas Stach
2014-11-04  9:42 ` [PATCH 04/10] fs: efivar: switch to standard list implementation Lucas Stach
2014-11-04  9:42 ` [PATCH 05/10] fs: efivar: move variable discovery into probe Lucas Stach
2014-11-04  9:42 ` [PATCH 06/10] lib: add wchar strdup Lucas Stach
2014-11-04  9:42 ` [PATCH 07/10] fs: efivar: preserve more info in inode Lucas Stach
2014-11-04  9:42 ` [PATCH 08/10] fs: efivar: don't store attributes in file Lucas Stach
2014-11-04  9:42 ` [PATCH 09/10] fs: efivar: implement write support Lucas Stach
2014-11-04  9:42 ` [PATCH 10/10] efi: mount efivarfs by default if enabled Lucas Stach
2014-11-05  7:21 ` [PATCH 01/10] efi: add proper reset hook Sascha Hauer
2014-11-05  9:00   ` Lucas Stach

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