summaryrefslogtreecommitdiffstats
path: root/utils/regtools/include/soc_desc.hpp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:01:24 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:12:55 +0000
commit0f701a64bee43e79f95970ae9c0ec43ea7fcdf17 (patch)
treec8ac6b5516eac120797eb6a06f633919e9f48f9b /utils/regtools/include/soc_desc.hpp
parent16c915ec1826dcef2e58ecc055a3f5dfcefb235a (diff)
downloadrockbox-0f701a64bee43e79f95970ae9c0ec43ea7fcdf17.tar.gz
rockbox-0f701a64bee43e79f95970ae9c0ec43ea7fcdf17.zip
regtools: update v2 specification, library and tools
A v2 register description file can now include register variants and instances addresses can now be a list (previously it could only be a stride or a formula). Update the library to deal with that. The convert option of swiss_knife was updated and one incompatible change was introduce: if a v1 device has several addresses, those are converted to a single v2 instance with list (instead of several single instances). This should have been the behaviour from the start. Swiss_knife can now also convert regdumps, in which case it needs to be given both the dump and register description file. Also introduce two register descriptions files (vsoc1000 and vsoc2000) which give more complicated examples of v2 register description files. Change-Id: Id9415b8363269ffaf9216abfc6dd1bd1adbfcf8d
Diffstat (limited to 'utils/regtools/include/soc_desc.hpp')
-rw-r--r--utils/regtools/include/soc_desc.hpp139
1 files changed, 132 insertions, 7 deletions
diff --git a/utils/regtools/include/soc_desc.hpp b/utils/regtools/include/soc_desc.hpp
index 66f2e3b6e1..f6c5cca28f 100644
--- a/utils/regtools/include/soc_desc.hpp
+++ b/utils/regtools/include/soc_desc.hpp
@@ -125,11 +125,30 @@ struct field_t
}
};
+/** Register variant information
+ *
+ * A register variant provides an alternative access to the register, potentially
+ * we special semantics. Although there are no constraints on the type string,
+ * the following types have well-defined semantics:
+ * - alias: the same register at another address
+ * - set: writing to this register will set the 1s bits and ignore the 0s
+ * - clr: writing to this register will clear the 1s bits and ignore the 0s
+ * - tog: writing to this register will toggle the 1s bits and ignore the 0s
+ */
+struct variant_t
+{
+ soc_id_t id; /** ID (must be unique among register variants) */
+ std::string type; /** type of the variant */
+ soc_addr_t offset; /** offset of the variant */
+};
+
/** Register information */
struct register_t
{
size_t width; /** Size in bits */
+ std::string desc; /** Optional description of the register */
std::vector< field_t > field; /** List of fields */
+ std::vector< variant_t > variant; /** List of variants */
};
/** Node address range information */
@@ -138,16 +157,24 @@ struct range_t
enum type_t
{
STRIDE, /** Addresses are given by a base address and a stride */
- FORMULA /** Addresses are given by a formula */
+ FORMULA, /** Addresses are given by a formula */
+ LIST, /** Addresses are given by a list */
};
type_t type; /** Range type */
size_t first; /** First index in the range */
- size_t count; /** Number of indexes in the range */
+ size_t count; /** Number of indexes in the range (for STRIDE and RANGE) */
soc_word_t base; /** Base address (for STRIDE) */
soc_word_t stride; /** Stride value (for STRIDE) */
std::string formula; /** Formula (for FORMULA) */
std::string variable; /** Formula variable name (for FORMULA) */
+ std::vector< soc_word_t > list; /** Address list (for LIST) */
+
+ /** Return the number of indexes (based on count or list) */
+ size_t size()
+ {
+ return type == LIST ? list.size() : count;
+ }
};
/** Node instance information */
@@ -197,6 +224,12 @@ bool parse_xml(const std::string& filename, soc_t& soc, error_context_t& error_c
/** Write a SoC description to a XML file, overwriting it. A file can contain
* multiple Soc descriptions */
bool produce_xml(const std::string& filename, const soc_t& soc, error_context_t& error_ctx);
+/** Normalise a soc description by reordering elements so that:
+ * - nodes are sorted by lowest address of an instance
+ * - instances are sorted by lowest address
+ * - fields are sorted by last bit
+ * - enum are sorted by value */
+void normalize(soc_t& soc);
/** Formula parser: try to parse and evaluate a formula with some variables */
bool evaluate_formula(const std::string& formula,
const std::map< std::string, soc_word_t>& var, soc_word_t& result,
@@ -219,6 +252,8 @@ class soc_ref_t;
class node_ref_t;
class register_ref_t;
class field_ref_t;
+class enum_ref_t;
+class variant_ref_t;
class node_inst_t;
/** SoC reference */
@@ -241,6 +276,9 @@ public:
/** Compare this reference to another */
bool operator==(const soc_ref_t& r) const;
inline bool operator!=(const soc_ref_t& r) const { return !operator==(r); }
+ bool operator<(const soc_ref_t& r) const { return m_soc < r.m_soc; }
+ /** Make this reference invalid */
+ void reset();
};
/** SoC node reference
@@ -265,8 +303,10 @@ public:
node_t *get() const;
/** Returns a reference to the soc */
soc_ref_t soc() const;
- /** Returns a reference to the parent node */
- node_ref_t parent() const;
+ /** Returns a reference to the n-th parent node, 0-th is itself, 1-th is parent */
+ node_ref_t parent(unsigned level = 1) const;
+ /** Returns reference depth, root is 0, below root is 1 and so on */
+ unsigned depth() const;
/** Returns a reference to the register (which may be on a parent node) */
register_ref_t reg() const;
/** Returns a list of references to the sub-nodes */
@@ -280,6 +320,16 @@ public:
/** Compare this reference to another */
bool operator==(const node_ref_t& r) const;
inline bool operator!=(const node_ref_t& r) const { return !operator==(r); }
+ /** Delete the node (and children) pointed by the reference, invalidating it
+ * NOTE: if reference points to the root node, deletes all nodes
+ * NOTE: does nothing if the reference is not valid */
+ void remove();
+ /** Create a new child node and returns a reference to it */
+ node_ref_t create() const;
+ /** Create a register and returns a reference to it */
+ register_ref_t create_reg(size_t width = 32) const;
+ /** Make this reference invalid */
+ void reset();
};
/** SoC register reference */
@@ -300,11 +350,24 @@ public:
node_ref_t node() const;
/** Returns a list of references to the fields of the register */
std::vector< field_ref_t > fields() const;
+ /** Returns a list of references to the variants of the register */
+ std::vector< variant_ref_t > variants() const;
/** Returns a reference to a particular field */
field_ref_t field(const std::string& name) const;
+ /** Returns a reference to a particular variant */
+ variant_ref_t variant(const std::string& type) const;
/** Compare this reference to another */
bool operator==(const register_ref_t& r) const;
inline bool operator!=(const register_ref_t& r) const { return !operator==(r); }
+ /** Delete the register pointed by the reference, invalidating it
+ * NOTE: does nothing if the reference is not valid */
+ void remove();
+ /** Create a new field and returns a reference to it */
+ field_ref_t create_field() const;
+ /** Create a new variant and returns a reference to it */
+ variant_ref_t create_variant() const;
+ /** Make this reference invalid */
+ void reset();
};
/** SoC register field reference */
@@ -312,7 +375,7 @@ class field_ref_t
{
friend class register_ref_t;
register_ref_t m_reg; /* reference to the register */
- soc_id_t m_id; /* field name */
+ soc_id_t m_id; /* field id */
field_ref_t(register_ref_t reg, soc_id_t id);
public:
@@ -324,9 +387,67 @@ public:
field_t *get() const;
/** Returns a reference to the register containing the field */
register_ref_t reg() const;
+ /** Returns a list of references to the enums of the field */
+ std::vector< enum_ref_t > enums() const;
+ /** Compare this reference to another */
+ bool operator==(const field_ref_t& r) const;
+ inline bool operator!=(const field_ref_t& r) const { return !operator==(r); }
+ /** Make this reference invalid */
+ void reset();
+ /** Create a new enum and returns a reference to it */
+ enum_ref_t create_enum() const;
+};
+
+/** SoC register field enum reference */
+class enum_ref_t
+{
+ friend class field_ref_t;
+ field_ref_t m_field; /* reference to the field */
+ soc_id_t m_id; /* enum id */
+
+ enum_ref_t(field_ref_t reg, soc_id_t id);
+public:
+ /** Builds an invalid reference */
+ enum_ref_t();
+ /** Check whether this reference is valid/exists */
+ bool valid() const;
+ /** Returns a pointer to the enum, or 0 */
+ enum_t *get() const;
+ /** Returns a reference to the field containing the enum */
+ field_ref_t field() const;
/** Compare this reference to another */
bool operator==(const field_ref_t& r) const;
inline bool operator!=(const field_ref_t& r) const { return !operator==(r); }
+ /** Make this reference invalid */
+ void reset();
+};
+
+/** SoC register variant reference */
+class variant_ref_t
+{
+ friend class register_ref_t;
+ register_ref_t m_reg; /* reference to the register */
+ soc_id_t m_id; /* variant name */
+
+ variant_ref_t(register_ref_t reg, soc_id_t id);
+public:
+ /** Builds an invalid reference */
+ variant_ref_t();
+ /** Check whether this reference is valid/exists */
+ bool valid() const;
+ /** Returns a pointer to the variant, or 0 */
+ variant_t *get() const;
+ /** Returns a reference to the register containing the field */
+ register_ref_t reg() const;
+ /** Returns variant type */
+ std::string type() const;
+ /** Returns variant offset */
+ soc_word_t offset() const;
+ /** Compare this reference to another */
+ bool operator==(const variant_ref_t& r) const;
+ inline bool operator!=(const variant_ref_t& r) const { return !operator==(r); }
+ /** Make this reference invalid */
+ void reset();
};
/** SoC node instance
@@ -353,8 +474,10 @@ public:
node_ref_t node() const;
/** Check whether this reference is the root node instance */
bool is_root() const;
- /** Returns a reference to the parent instance */
- node_inst_t parent() const;
+ /** Returns a reference to the n-th parent instance, 0-th is itself, and so on */
+ node_inst_t parent(unsigned level = 1) const;
+ /** Returns reference depth, 0 is root, and so on */
+ unsigned depth() const;
/** Returns a pointer to the instance of the node, or 0 */
instance_t *get() const;
/** Returns the address of this instance */
@@ -377,6 +500,8 @@ public:
/** Compare this reference to another */
bool operator==(const node_inst_t& r) const;
inline bool operator!=(const node_inst_t& r) const { return !operator==(r); }
+ /** Make this reference invalid */
+ void reset();
};
} // soc_desc