Merge branch 'for-next/state'
This commit is contained in:
commit
ee0035e5cc
|
@ -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.
|
|
@ -2096,6 +2096,11 @@ config CMD_TIME
|
||||||
Note: This command depends on COMMAND being interruptible,
|
Note: This command depends on COMMAND being interruptible,
|
||||||
otherwise the timer may overrun resulting in incorrect results
|
otherwise the timer may overrun resulting in incorrect results
|
||||||
|
|
||||||
|
config CMD_STATE
|
||||||
|
tristate
|
||||||
|
depends on STATE
|
||||||
|
prompt "state"
|
||||||
|
|
||||||
# end Miscellaneous commands
|
# end Miscellaneous commands
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
|
|
@ -110,3 +110,4 @@ obj-$(CONFIG_CMD_FIRMWARELOAD) += firmwareload.o
|
||||||
obj-$(CONFIG_CMD_CMP) += cmp.o
|
obj-$(CONFIG_CMD_CMP) += cmp.o
|
||||||
obj-$(CONFIG_CMD_NV) += nv.o
|
obj-$(CONFIG_CMD_NV) += nv.o
|
||||||
obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o
|
obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o
|
||||||
|
obj-$(CONFIG_CMD_STATE) += state.o
|
||||||
|
|
|
@ -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
|
|
@ -706,6 +706,13 @@ config BAREBOXCRC32_TARGET
|
||||||
config POLLER
|
config POLLER
|
||||||
bool "generic polling infrastructure"
|
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
|
config RESET_SOURCE
|
||||||
bool "detect Reset cause"
|
bool "detect Reset cause"
|
||||||
depends on GLOBALVAR
|
depends on GLOBALVAR
|
||||||
|
|
|
@ -42,6 +42,7 @@ obj-$(CONFIG_POLLER) += poller.o
|
||||||
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
||||||
obj-$(CONFIG_SHELL_HUSH) += hush.o
|
obj-$(CONFIG_SHELL_HUSH) += hush.o
|
||||||
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
|
obj-$(CONFIG_SHELL_SIMPLE) += parser.o
|
||||||
|
obj-$(CONFIG_STATE) += state.o
|
||||||
obj-$(CONFIG_UIMAGE) += image.o uimage.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_GUID) += efi-guid.o
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,4 +15,8 @@ config SRAM
|
||||||
help
|
help
|
||||||
This driver adds support for memory mapped SRAM.
|
This driver adds support for memory mapped SRAM.
|
||||||
|
|
||||||
|
config STATE_DRV
|
||||||
|
tristate "state driver"
|
||||||
|
depends on STATE
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
|
|
||||||
obj-$(CONFIG_JTAG) += jtag.o
|
obj-$(CONFIG_JTAG) += jtag.o
|
||||||
obj-$(CONFIG_SRAM) += sram.o
|
obj-$(CONFIG_SRAM) += sram.o
|
||||||
|
obj-$(CONFIG_STATE_DRV) += state.o
|
||||||
|
|
|
@ -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);
|
|
@ -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 */
|
Loading…
Reference in New Issue