9
0
Fork 0

Merge branch 'for-next/state'

This commit is contained in:
Sascha Hauer 2015-04-13 12:57:14 +02:00
commit ee0035e5cc
11 changed files with 1503 additions and 0 deletions

View File

@ -0,0 +1,107 @@
barebox,state
=============
Overview
--------
Boards often have the need to store variables in persistent memory.
The constraints are often different from what the regular environment
can do:
* compact binary format to make it suitable for small EEPROMs/MRAMs
* atomic save/restore of the whole variable set
* redundancy
``barebox,state`` is a framework to describe, access, store and
restore a set of variables. A state variable set can be fully
described in a devicetree node. This node could be part of the regular
devicetree blob or it could be an extra devicetree solely for the
state. The state variable set contains variables of different types
and a place to store the variable set.
A state node contains a description of a set of variables along with a
place where the variables are stored.
Required properties:
* ``compatible``: should be ``barebox,state``;
* ``magic``: A 32bit number used as a magic to identify the state
Optional properties:
* ``backend``: describes where the data for this state is stored
* ``backend-type``: should be ``raw`` or ``dtb``.
Variable nodes
--------------
These are subnodes of a state node each describing a single
variable. The node name may end with ``@<ADDRESS>``, but the suffix is
sripped from the variable name.
State variables have a type. Currenty supported types are: ``uint32``,
``enum32`` and ``mac`` address. Fixed length strings are planned but
not implemented. Variable length strings are not planned.
Required properties:
* ``reg``: Standard ``reg`` property with ``#address-cells = <1>`` and
``#size-cells = <1>``. Defines the ``offset`` and ``size`` of the
variable in the ``raw`` backend. ``size`` must fit the node
``type``. Variables are not allowed to overlap.
* ``type``: Should be ``uint32``, ``enum32`` or ``mac`` for the type
of the variable
* ``names``: For ``enum32`` values only, this specifies the values
possible for ``enum32``.
Optional properties:
* ``default``: The default value if the variable cannot be read from
storage. For ``enum32`` values it is an integer representing an
offset into the names array.
Example::
state: state@0 {
magic = <0x27031977>;
compatible = "barebox,state";
backend-type = "raw";
backend = &eeprom, "partname:state";
foo {
reg = <0x00 0x4>;
type = "u32";
default = <0x0>;
};
bar {
reg = <0x10 0x4>;
type = "enum32";
names = "baz", "qux";
default ="qux";
};
};
Backends
--------
Currently two backends exist. The raw backend is a very compact format
consisting of a magic value for identification, the raw values and a
CRC. Two copies are maintained for making sure that during update the
storage device still contains a valid state. The dtb backend stores
the state as a devicetree binary blob. This is exactly the original
devicetree description of the state itself, but additionally contains
the actual values of the variables. Unlike the raw state backend the
dtb state backend can describe itself.
Frontend
--------
As frontend a state instance is a regular barebox device which has
device parameters for the state variables. With this the variables can
be accessed like normal shell variables. The ``state`` command is used
to save/restore a state to the backend device.
After initializing the variable can be accessed with ``$state.foo``.
``state -s`` stores the state to eeprom.

View File

@ -2096,6 +2096,11 @@ config CMD_TIME
Note: This command depends on COMMAND being interruptible,
otherwise the timer may overrun resulting in incorrect results
config CMD_STATE
tristate
depends on STATE
prompt "state"
# end Miscellaneous commands
endmenu

View File

@ -110,3 +110,4 @@ obj-$(CONFIG_CMD_FIRMWARELOAD) += firmwareload.o
obj-$(CONFIG_CMD_CMP) += cmp.o
obj-$(CONFIG_CMD_NV) += nv.o
obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o
obj-$(CONFIG_CMD_STATE) += state.o

77
commands/state.c Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <getopt.h>
#include <command.h>
#include <state.h>
static int do_state(int argc, char *argv[])
{
int opt, ret = 0;
struct state *state = NULL;
int do_save = 0, do_load = 0;
const char *statename = "state";
while ((opt = getopt(argc, argv, "sl")) > 0) {
switch (opt) {
case 's':
do_save = 1;
break;
case 'l':
do_load = 1;
break;
default:
return COMMAND_ERROR_USAGE;
}
}
if (do_save && do_load)
return COMMAND_ERROR_USAGE;
if (!do_save && !do_load) {
state_info();
return 0;
}
if (optind < argc)
statename = argv[optind];
state = state_by_name(statename);
if (!state) {
printf("cannot find state %s\n", statename);
return -ENOENT;
}
if (do_save)
ret = state_save(state);
else if (do_load)
ret = state_load(state);
return ret;
}
static const __maybe_unused char cmd_state_help[] =
"Usage: state [OPTIONS] [STATENAME]\n"
"\n"
"options:\n"
"-s save state\n"
"-l load state\n";
BAREBOX_CMD_START(state)
.cmd = do_state,
BAREBOX_CMD_DESC("handle state information")
BAREBOX_CMD_GROUP(CMD_GRP_MISC)
BAREBOX_CMD_HELP(cmd_state_help)
BAREBOX_CMD_END

View File

@ -706,6 +706,13 @@ config BAREBOXCRC32_TARGET
config POLLER
bool "generic polling infrastructure"
config STATE
bool "generic state infrastructure"
depends on OF_BAREBOX_DRIVERS
select ENVIRONMENT_VARIABLES
select OFTREE
select PARAMETER
config RESET_SOURCE
bool "detect Reset cause"
depends on GLOBALVAR

View File

@ -42,6 +42,7 @@ obj-$(CONFIG_POLLER) += poller.o
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
obj-$(CONFIG_SHELL_HUSH) += hush.o
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
obj-$(CONFIG_STATE) += state.o
obj-$(CONFIG_UIMAGE) += image.o uimage.o
obj-$(CONFIG_MENUTREE) += menutree.o
obj-$(CONFIG_EFI_GUID) += efi-guid.o

1198
common/state.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,4 +15,8 @@ config SRAM
help
This driver adds support for memory mapped SRAM.
config STATE_DRV
tristate "state driver"
depends on STATE
endmenu

View File

@ -4,3 +4,4 @@
obj-$(CONFIG_JTAG) += jtag.o
obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_STATE_DRV) += state.o

81
drivers/misc/state.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2013 Sascha Hauer <s.hauer@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <of.h>
#include <state.h>
#include <linux/err.h>
static int state_probe(struct device_d *dev)
{
struct device_node *np = dev->device_node;
struct state *state;
const char *alias;
const char *backend_type = NULL;
int ret;
char *path;
if (!np)
return -EINVAL;
alias = of_alias_get(np);
if (!alias)
alias = "state";
state = state_new_from_node(alias, np);
if (IS_ERR(state))
return PTR_ERR(state);
ret = of_find_path(np, "backend", &path);
if (ret)
return ret;
dev_info(dev, "outpath: %s\n", path);
ret = of_property_read_string(np, "backend-type", &backend_type);
if (ret)
return ret;
else if (!strcmp(backend_type, "raw"))
ret = state_backend_raw_file(state, path, 0, 0);
else if (!strcmp(backend_type, "dtb"))
ret = state_backend_dtb_file(state, path);
else
dev_warn(dev, "invalid backend type: %s\n", backend_type);
if (ret)
return ret;
state_load(state);
return 0;
}
static __maybe_unused struct of_device_id state_ids[] = {
{
.compatible = "barebox,state",
}, {
/* sentinel */
}
};
static struct driver_d state_driver = {
.name = "state",
.probe = state_probe,
.of_compatible = DRV_OF_COMPAT(state_ids),
};
device_platform_driver(state_driver);

21
include/state.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __STATE_H
#define __STATE_H
struct state;
int state_backend_dtb_file(struct state *state, const char *path);
int state_backend_raw_file(struct state *state, const char *path,
off_t offset, size_t size);
struct state *state_new_from_fdt(const char *name, void *fdt);
struct state *state_new_from_node(const char *name, struct device_node *node);
struct state *state_by_name(const char *name);
struct state *state_by_node(const struct device_node *node);
int state_get_name(const struct state *state, char const **name);
int state_load(struct state *state);
int state_save(struct state *state);
void state_info(void);
#endif /* __STATE_H */