[Pdbg] [PATCH 1/1] Adding initial doxgyen to several files in libpdbg
Andre Marin
andre at alexamarin.com
Thu Mar 28 15:38:51 AEDT 2019
From: Andre Marin <aamarin at us.ibm.com>
---
libfdt/fdt.h | 9 +-
libpdbg/device.c | 29 +++++-
libpdbg/libpdbg.c | 97 ++++++++++++++++---
libpdbg/libpdbg.h | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++----
libpdbg/target.c | 171 ++++++++++++++++++++++++++++++---
libpdbg/target.h | 238 ++++++++++++++++++++++++++++++++++++++++++++--
6 files changed, 766 insertions(+), 55 deletions(-)
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index 526aedb..a8cc756 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -54,7 +54,10 @@
#ifndef __ASSEMBLY__
+/* The layout of the header for the devicetree */
struct fdt_header {
+ /* header fields are stored in big-endian format */
+
fdt32_t magic; /* magic word FDT_MAGIC */
fdt32_t totalsize; /* total size of DT block */
fdt32_t off_dt_struct; /* offset to structure */
@@ -73,9 +76,11 @@ struct fdt_header {
fdt32_t size_dt_struct; /* size of the structure block */
};
+/* memory reservation block :
+ not used for general memory allocation*/
struct fdt_reserve_entry {
- fdt64_t address;
- fdt64_t size;
+ fdt64_t address; /* physical address*/
+ fdt64_t size; /* size in bytes*/
};
struct fdt_node_header {
diff --git a/libpdbg/device.c b/libpdbg/device.c
index 3dc301f..c395e4c 100644
--- a/libpdbg/device.c
+++ b/libpdbg/device.c
@@ -392,6 +392,13 @@ void pdbg_target_set_property(struct pdbg_target *target, const char *name, cons
}
}
+/**
+ * @brief Get the given property and return the size
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[out] size the property size
+ * @return NULL
+ */
void *pdbg_target_property(struct pdbg_target *target, const char *name, size_t *size)
{
struct dt_property *p;
@@ -465,6 +472,12 @@ static const struct dt_property *dt_require_property(const struct pdbg_target *n
return p;
}
+/**
+ * @brief Check to see if a given compatible matches that of a pdbg_target
+ * @param[in] target the pdbg_target
+ * @param[in] compatible the compatible string we want to match against
+ * @return bool true if pdbg_target is found given compatible
+ */
bool pdbg_target_compatible(struct pdbg_target *target, const char *compatible)
{
char *c, *end;
@@ -620,7 +633,13 @@ static u32 dt_n_size_cells(const struct pdbg_target *node)
return dt_prop_get_u32_def(node->parent, "#size-cells", 1);
}
-uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *out_size)
+/**
+ * @brief Get the address for a pdbg_target
+ * @param[in] target the pdbg_target
+ * @param[out] val pointer to return value, modified only if no error.
+ * @return int 0 iff successful, otherwise -1
+ */
+uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *size)
{
const struct dt_property *p;
u32 na = dt_n_address_cells(target);
@@ -630,8 +649,8 @@ uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *out_size)
p = dt_require_property(target, "reg", -1);
n = (na + ns) * sizeof(u32);
assert(n <= p->len);
- if (out_size)
- *out_size = dt_get_number(p->prop + na * sizeof(u32), ns);
+ if (size)
+ *size = dt_get_number(p->prop + na * sizeof(u32), ns);
return dt_get_number(p->prop, na);
}
@@ -654,6 +673,10 @@ struct pdbg_target *pdbg_target_from_path(struct pdbg_target *target, const char
return dt_find_by_path(target, path);
}
+/**
+ * @brief Gets the head pdbg_target (root node)
+ * @return pdbg_target the root target
+ */
struct pdbg_target *pdbg_target_root(void)
{
return pdbg_dt_root;
diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c
index c549497..aeb8839 100644
--- a/libpdbg/libpdbg.c
+++ b/libpdbg/libpdbg.c
@@ -6,6 +6,13 @@
static pdbg_progress_tick_t progress_tick;
+/**
+ * @brief Find the next pdbg_target* given a class
+ * @param[in] class the class of interest
+ * @param[in] parent the head pdbg_target
+ * @param[in] last the last pdbg_target in the class
+ * @return the next pdbg_target* iff successful, otherwise NULL
+ */
struct pdbg_target *__pdbg_next_target(const char *class, struct pdbg_target *parent, struct pdbg_target *last)
{
struct pdbg_target *next, *tmp;
@@ -43,6 +50,12 @@ retry:
}
}
+/**
+ * @brief Find the next child pdbg_target* given a parent target
+ * @param[in] parent the head pdbg_target
+ * @param[in] last the last pdbg_target in the class
+ * @return the next pdbg_target* iff successful, otherwise NULL
+ */
struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last)
{
if (!parent || list_empty(&parent->children))
@@ -57,11 +70,22 @@ struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct
return list_entry(last->list.next, struct pdbg_target, list);
}
+/**
+ * @brief Get the pdbg_target status
+ * @param[in] target the pdbg_target
+ * @return pdbg_target_status the next pdbg_target status
+ */
enum pdbg_target_status pdbg_target_status(struct pdbg_target *target)
{
return target->status;
}
+/**
+ * @brief Set the pdbg_target status
+ * @param[in] target pdbg_target
+ * @param[in] status the status to set
+ * @return void
+ */
void pdbg_target_status_set(struct pdbg_target *target, enum pdbg_target_status status)
{
/* It's a programming error for user code to attempt anything else so
@@ -71,7 +95,11 @@ void pdbg_target_status_set(struct pdbg_target *target, enum pdbg_target_status
target->status = status;
}
-/* Searches up the tree and returns the first valid index found */
+/**
+ * @brief Searches up the tree and returns the first valid index found
+ * @param[in] target the pdbg_target
+ * @return uint32_t the target index
+ */
uint32_t pdbg_target_index(struct pdbg_target *target)
{
struct pdbg_target *dn;
@@ -84,7 +112,12 @@ uint32_t pdbg_target_index(struct pdbg_target *target)
return dn->index;
}
-/* Find a target parent from the given class */
+/**
+ * @brief Find a target parent from the given class
+ * @param[in] class the given class
+ * @param[in] target the pdbg_target
+ * @return struct pdbg_target* the first parent target of the given class, otherwise NULL
+ */
struct pdbg_target *pdbg_target_parent(const char *class, struct pdbg_target *target)
{
struct pdbg_target *parent;
@@ -100,6 +133,13 @@ struct pdbg_target *pdbg_target_parent(const char *class, struct pdbg_target *ta
return NULL;
}
+/**
+ * @brief Find a target parent from the given class
+ * @param[in] class the given class
+ * @param[in] target the pdbg_target
+ * @return struct pdbg_target* the first parent target of the given class, otherwise assert out
+ * @note Same as above but instead of returning NULL causes an assert failure
+ */
struct pdbg_target *pdbg_target_require_parent(const char *class, struct pdbg_target *target)
{
struct pdbg_target *parent = pdbg_target_parent(class, target);
@@ -108,7 +148,12 @@ struct pdbg_target *pdbg_target_require_parent(const char *class, struct pdbg_ta
return parent;
}
-/* Searched up the tree for the first target of the right class and returns its index */
+/**
+ * @brief Searched up the tree for the first target of the right class and returns its index
+ * @param[in] target the pdbg_target
+ * @param[in] class the given class
+ * @return uint32_t target parent index, otherwise -1 if there's an error
+ */
uint32_t pdbg_parent_index(struct pdbg_target *target, char *class)
{
struct pdbg_target *parent;
@@ -120,21 +165,43 @@ uint32_t pdbg_parent_index(struct pdbg_target *target, char *class)
return -1;
}
+/**
+ * @brief Get the target class name
+ * @param[in] target the pdbg_target
+ * @return char* the class name
+ */
char *pdbg_target_class_name(struct pdbg_target *target)
{
return target->class;
}
+/**
+ * @brief Get the target name
+ * @param[in] target the pdbg_target
+ * @return char* the target name
+ */
char *pdbg_target_name(struct pdbg_target *target)
{
return target->name;
}
+/**
+ * @brief Get the dn name
+ * @param[in] target the pdbg_target
+ * @return char* the dn name
+ */
const char *pdbg_target_dn_name(struct pdbg_target *target)
{
return target->dn_name;
}
+/**
+ * @brief Get the given property value
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[out] val the property value (uint32_t*)
+ * @return 0 iff successful, -1 otherwise
+ */
int pdbg_target_u32_property(struct pdbg_target *target, const char *name, uint32_t *val)
{
uint32_t *p;
@@ -150,23 +217,31 @@ int pdbg_target_u32_property(struct pdbg_target *target, const char *name, uint3
return 0;
}
+/**
+ * @brief Searched up the tree for the first target of the right class and returns its index
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[in] index of the u32 in the list of values
+ * @param[out] val pointer to return value, modified only if no error.
+ * @return int 0 iff successful, otherwise -1
+ */
int pdbg_target_u32_index(struct pdbg_target *target, const char *name, int index, uint32_t *val)
{
- size_t len;
+ size_t len;
uint32_t *p;
- p = pdbg_get_target_property(target, name, &len);
- if (!p)
- return -1;
+ p = pdbg_get_target_property(target, name, &len);
+ if (!p)
+ return -1;
- assert(len >= (index+1)*sizeof(uint32_t));
+ assert(len >= (index+1)*sizeof(uint32_t));
/* FDT pointers should be aligned, but best to check */
assert(!((uintptr_t) p & 0x3));
- /* Always aligned, so this works. */
- *val = be32toh(p[index]);
- return 0;
+ /* Always aligned, so this works. */
+ *val = be32toh(p[index]);
+ return 0;
}
void pdbg_progress_tick(uint64_t cur, uint64_t end)
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 301c2c8..db19e14 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -6,22 +6,52 @@
#include <stdbool.h>
#include <stdarg.h>
-#include <stdbool.h>
-
#include <ccan/short_types/short_types.h>
+/**
+ * @struct pdbg_target
+ * @brief PowerPC FSI Debugger target
+ */
struct pdbg_target;
+
+/**
+ * @struct pdbg_target_class
+ * @brief PowerPC FSI Debugger target class
+ */
struct pdbg_target_class;
/* loops/iterators */
+
+/**
+ * @brief Find the next compatible target given @compat compat
+ * @param[in] parent the head pdbg_target
+ * @param[in] prev the last pdbg_target in the class
+ * @return the next compatible pdbg_target*
+ */
struct pdbg_target *__pdbg_next_compatible_node(struct pdbg_target *root,
struct pdbg_target *prev,
const char *compat);
+
+/**
+ * @brief Find the next pdbg_target* given a class
+ * @param[in] klass the klass of interest
+ * @param[in] parent the head pdbg_target
+ * @param[in] last the last pdbg_target in the klass
+ * @return the next pdbg_target* iff successful, otherwise NULL
+ */
struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last);
+
+/**
+ * @brief Find the next child pdbg_target* given a parent target
+ * @param[in] parent the head pdbg_target
+ * @param[in] last the last pdbg_target in the class
+ * @return the next pdbg_target* iff successful, otherwise NULL
+ */
struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last);
-/*
- * Each target has a status associated with it. This is what each status means:
+/**
+ * @brief the pdbg_target states
+ * @note Each target has a status associated with it. This is what each status means:
*
* enabled - the target exists and has been probed, will be released by
* the release call.
@@ -46,43 +76,116 @@ struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct
* unneccessary probing by marking them disabled. If no status property exists
* it defaults to "unknown".
*/
-enum pdbg_target_status {PDBG_TARGET_UNKNOWN = 0, PDBG_TARGET_ENABLED,
- PDBG_TARGET_DISABLED, PDBG_TARGET_MUSTEXIST,
- PDBG_TARGET_NONEXISTENT, PDBG_TARGET_RELEASED};
+enum pdbg_target_status {
+ PDBG_TARGET_UNKNOWN = 0, /**< UNKNOWN STATE */
+ PDBG_TARGET_ENABLED, /**< ENABLED STATE */
+ PDBG_TARGET_DISABLED, /**< DISABLED STATE */
+ PDBG_TARGET_MUSTEXIST, /**< MUSTEXIST STATE */
+ PDBG_TARGET_NONEXISTENT, /**< NONEXISTENT STATE */
+ PDBG_TARGET_RELEASED, /**< RELEASED STATE */
+};
+
+/**
+ * @brief For each loop accross compatible targets
+ * @param[in] target the current pdbg_target
+ * @param[out] compat comptabile key to match against
+ */
#define pdbg_for_each_compatible(parent, target, compat) \
for (target = NULL; \
(target = __pdbg_next_compatible_node(parent, target, compat)) != NULL;)
+/**
+ * @brief For each loop accross targets in the class (list)
+ * @param[in] parent the root pdbg_target
+ * @param[in] target the current pdbg_target
+ */
#define pdbg_for_each_target(class, parent, target) \
for (target = __pdbg_next_target(class, parent, NULL); \
target; \
target = __pdbg_next_target(class, parent, target))
+/**
+ * @brief For each loop accross class_targets (list)
+ * @param[in] class the class_target
+ * @param[in] target the current pdbg_target
+ */
#define pdbg_for_each_class_target(class, target) \
for (target = __pdbg_next_target(class, NULL, NULL); \
target; \
target = __pdbg_next_target(class, NULL, target))
+/**
+ * @brief For each loop accross class_targets (list)
+ * @param[in] parent the head pdbg_target
+ * @param[in] target the current pdbg_target
+ */
#define pdbg_for_each_child_target(parent, target) \
for (target = __pdbg_next_child_target(parent, NULL); \
target; \
target = __pdbg_next_child_target(parent, target))
-/* Return the first parent target of the given class, or NULL if the given
- * target does not have a parent of the given class. */
+/**
+ * @brief Find a target parent from the given class
+ * @param[in] klass the given class
+ * @param[in] target the pdbg_target
+ * @return struct pdbg_target* the first parent target of the given class, otherwise NULL
+ */
struct pdbg_target *pdbg_target_parent(const char *klass, struct pdbg_target *target);
-/* Same as above but instead of returning NULL causes an assert failure. */
+/**
+ * @brief Find a target parent from the given class
+ * @param[in] klass the given class
+ * @param[in] target the pdbg_target
+ * @return struct pdbg_target* the first parent target of the given class, otherwise assert out
+ * @note Same as above but instead of returning NULL causes an assert failure
+ */
struct pdbg_target *pdbg_target_require_parent(const char *klass, struct pdbg_target *target);
-/* Set the given property. Will automatically add one if one doesn't exist */
+/**
+ * @brief Set the given property. Will automatically add one if one doesn't exist
+ * @param[in] name the given class name
+ * @param[in] target the pdbg_target
+ * @param[in] val the property to set
+ * @param[in] size the size
+ * @return void
+ */
void pdbg_target_set_property(struct pdbg_target *target, const char *name, const void *val, size_t size);
-/* Get the given property and return the size */
+/**
+ * @brief Get the given property and return the size
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[out] size the property size
+ * @return void* the pdbg_target property
+ */
void *pdbg_target_property(struct pdbg_target *target, const char *name, size_t *size);
+
+/**
+ * @brief Get the given property value
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[out] val the property value (uint32_t*)
+ * @return 0 iff successful, -1 otherwise
+ */
int pdbg_target_u32_property(struct pdbg_target *target, const char *name, uint32_t *val);
+
+/**
+ * @brief Searched up the tree for the first target of the right class and returns its index
+ * @param[in] target the pdbg_target
+ * @param[in] name the given class name
+ * @param[in] index of the u32 in the list of values
+ * @param[out] val pointer to return value, modified only if no error.
+ * @return int 0 iff successful, otherwise -1
+ */
int pdbg_target_u32_index(struct pdbg_target *target, const char *name, int index, uint32_t *val);
+
+/**
+ * @brief Get the address for a pdbg_target
+ * @param[in] target the pdbg_target
+ * @param[out] val pointer to return value, modified only if no error.
+ * @return int 0 iff successful, otherwise -1
+ */
uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *size);
/* Old deprecated for names for the above. Do not use for new projects
@@ -99,32 +202,150 @@ void pdbg_targets_init(void *fdt);
void pdbg_target_probe_all(struct pdbg_target *parent);
enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target);
void pdbg_target_release(struct pdbg_target *target);
+
+/**
+ * @brief Get the pdbg_target status
+ * @param[in] target the pdbg_target
+ * @return pdbg_target_status the next pdbg_target status
+ */
enum pdbg_target_status pdbg_target_status(struct pdbg_target *target);
+
+/**
+ * @brief Set the pdbg_target status
+ * @param[in] target pdbg_target
+ * @param[in] status the status to set
+ * @return void
+ */
void pdbg_target_status_set(struct pdbg_target *target, enum pdbg_target_status status);
+
+/**
+ * @brief Searches up the tree and returns the first valid index found
+ * @param[in] target the pdbg_target
+ * @return uint32_t the target index
+ */
uint32_t pdbg_target_index(struct pdbg_target *target);
char *pdbg_target_path(const struct pdbg_target *target);
struct pdbg_target *pdbg_target_from_path(struct pdbg_target *target, const char *path);
+
+/**
+ * @brief Searched up the tree for the first target of the right class and returns its index
+ * @param[in] target the pdbg_target
+ * @param[in] class the given class
+ * @return uint32_t target parent index, otherwise -1 if there's an error
+ */
uint32_t pdbg_parent_index(struct pdbg_target *target, char *klass);
+
+/**
+ * @brief Get the target class name
+ * @param[in] target the pdbg_target
+ * @return char* the class name
+ */
char *pdbg_target_class_name(struct pdbg_target *target);
+
+/**
+ * @brief Get the target name
+ * @param[in] target the pdbg_target
+ * @return char* the target name
+ */
char *pdbg_target_name(struct pdbg_target *target);
+
+/**
+ * @brief Get the dn name
+ * @param[in] target the pdbg_target
+ * @return char* the dn name
+ */
const char *pdbg_target_dn_name(struct pdbg_target *target);
+
+/**
+ * @brief Gets the priv member of pdbg_target
+ * @param[in] target the pdbg_target
+ * @return void* to priv
+ */
void *pdbg_target_priv(struct pdbg_target *target);
+
+/**
+ * @brief Sets the priv member of pdbg_target
+ * @param[in,out] target the pdbg_target
+ * @param[in] void* priv member to set
+ * @return void
+ */
void pdbg_target_priv_set(struct pdbg_target *target, void *priv);
+
+/**
+ * @brief Gets the head pdbg_target (root node)
+ * @return pdbg_target the root target
+ */
struct pdbg_target *pdbg_target_root(void);
+
+/**
+ * @brief Check to see if a given compatible matches that of a pdbg_target
+ * @param[in] target the pdbg_target
+ * @param[in] compatible the compatible string we want to match against
+ * @return bool true if pdbg_target is found given compatible
+ */
bool pdbg_target_compatible(struct pdbg_target *target, const char *compatible);
-/* Translate an address offset for a target to absolute address in address
- * space of a "base" target. */
+
+/**
+ * @brief Translate an address offset for a target to absolute address in address space of a "base" target
+ * @param[in] target the current pdbg_target
+ * @param[out] attr the target address offset
+ * @return struct pdbg_target* the current target
+ */
struct pdbg_target *pdbg_address_absolute(struct pdbg_target *target, uint64_t *addr);
/* Procedures */
+
+/**
+ * @brief FSI read
+ * @param[in] fsi_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
int fsi_read(struct pdbg_target *target, uint32_t addr, uint32_t *val);
+
+/**
+ * @brief FSI write
+ * @param[in] fsi_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
int fsi_write(struct pdbg_target *target, uint32_t addr, uint32_t val);
+/**
+ * @brief PIB read
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_read(struct pdbg_target *target, uint64_t addr, uint64_t *val);
+
+/**
+ * @brief PIB write
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_write(struct pdbg_target *target, uint64_t addr, uint64_t val);
+
+/**
+ * @brief Wait for a SCOM register addr to match value & mask == data
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[in] mask the mask
+ * @param[in] data the data we want to match against
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_wait(struct pdbg_target *pib_dt, uint64_t addr, uint64_t mask, uint64_t data);
+/**
+ * @struct thread_regs
+ * @brief CPU thread registers
+ */
struct thread_regs {
uint64_t nia;
uint64_t msr;
@@ -185,12 +406,32 @@ int ram_getxer(struct pdbg_target *thread, uint64_t *value);
int ram_putxer(struct pdbg_target *thread, uint64_t value);
int getring(struct pdbg_target *chiplet_target, uint64_t ring_addr, uint64_t ring_len, uint32_t result[]);
-enum pdbg_sleep_state {PDBG_THREAD_STATE_RUN, PDBG_THREAD_STATE_DOZE,
- PDBG_THREAD_STATE_NAP, PDBG_THREAD_STATE_SLEEP,
- PDBG_THREAD_STATE_STOP};
+/**
+ * @brief the pdbg thread states
+ */
+enum pdbg_sleep_state {
+ PDBG_THREAD_STATE_RUN, /**< RUN STATE */
+ PDBG_THREAD_STATE_DOZE, /**< DOZE STATE */
+ PDBG_THREAD_STATE_NAP, /**< NAP STATE */
+ PDBG_THREAD_STATE_SLEEP, /**< SLEEP STATE */
+ PDBG_THREAD_STATE_STOP, /**< STOP STATE */
+};
-enum pdbg_smt_state {PDBG_SMT_UNKNOWN, PDBG_SMT_1, PDBG_SMT_2, PDBG_SMT_4, PDBG_SMT_8};
+/**
+ * @brief the pdbg_smt states
+ */
+enum pdbg_smt_state {
+ PDBG_SMT_UNKNOWN, /**< UNKNOWN STATE */
+ PDBG_SMT_1, /**< SMT_1 STATE */
+ PDBG_SMT_2, /**< SMT_2 STATE */
+ PDBG_SMT_4, /**< SMT_4 STATE */
+ PDBG_SMT_8, /**< SMT_8 STATE */
+};
+/**
+ * @struct thread_state
+ * @brief Container of thread states
+ */
struct thread_state {
bool active;
bool quiesced;
diff --git a/libpdbg/target.c b/libpdbg/target.c
index 37d3f54..eb97dbc 100644
--- a/libpdbg/target.c
+++ b/libpdbg/target.c
@@ -10,11 +10,27 @@
#include "operations.h"
#include "debug.h"
-struct list_head empty_list = LIST_HEAD_INIT(empty_list);
-struct list_head target_classes = LIST_HEAD_INIT(target_classes);
+/**
+ * @struct empty_list
+ * @brief Defines and initializes a list_head named empty_list
+ * @note this is a special node that refers to the linked list, without being a list node
+ */
+LIST_HEAD(empty_list);
-/* Work out the address to access based on the current target and
- * final class name */
+/**
+ * @struct target_classes
+ * @brief Defines and initializes a list_head named target_classes
+ * @note this is a special node that refers to the linked list, without being a list node
+ */
+LIST_HEAD(target_classes);
+
+/**
+ * @brief Work out the address to access
+ * @param[in] target the current target
+ * @param[in] name final class name
+ * @param[out] addr the address to access
+ * @return pdbg_target* the current target
+ */
static struct pdbg_target *get_class_target_addr(struct pdbg_target *target, const char *name, uint64_t *addr)
{
/* Check class */
@@ -36,6 +52,12 @@ static struct pdbg_target *get_class_target_addr(struct pdbg_target *target, con
return target;
}
+/**
+ * @brief Translate an address offset for a target to absolute address in address space of a "base" target
+ * @param[in] target the current pdbg_target
+ * @param[out] attr the target address offset
+ * @return struct pdbg_target* the current target
+ */
struct pdbg_target *pdbg_address_absolute(struct pdbg_target *target, uint64_t *addr)
{
return get_class_target_addr(target, "pib", addr);
@@ -51,6 +73,13 @@ struct pdbg_target *pdbg_address_absolute(struct pdbg_target *target, uint64_t *
#define PIB_DATA_IND_ERR PPC_BITMASK(33, 35)
#define PIB_DATA_IND_DATA PPC_BITMASK(48, 63)
+/**
+ * @brief PIB indirect read
+ * @param[in] pib the pib target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
static int pib_indirect_read(struct pib *pib, uint64_t addr, uint64_t *data)
{
uint64_t indirect_addr;
@@ -85,6 +114,13 @@ static int pib_indirect_read(struct pib *pib, uint64_t addr, uint64_t *data)
return 0;
}
+/**
+ * @brief PIB indirect write
+ * @param[in] pib the pib target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
static int pib_indirect_write(struct pib *pib, uint64_t addr, uint64_t data)
{
uint64_t indirect_addr;
@@ -118,6 +154,13 @@ static int pib_indirect_write(struct pib *pib, uint64_t addr, uint64_t data)
return 0;
}
+/**
+ * @brief PIB read
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_read(struct pdbg_target *pib_dt, uint64_t addr, uint64_t *data)
{
struct pib *pib;
@@ -135,6 +178,13 @@ int pib_read(struct pdbg_target *pib_dt, uint64_t addr, uint64_t *data)
return rc;
}
+/**
+ * @brief PIB write
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_write(struct pdbg_target *pib_dt, uint64_t addr, uint64_t data)
{
struct pib *pib;
@@ -152,7 +202,14 @@ int pib_write(struct pdbg_target *pib_dt, uint64_t addr, uint64_t data)
return rc;
}
-/* Wait for a SCOM register addr to match value & mask == data */
+/**
+ * @brief Wait for a SCOM register addr to match value & mask == data
+ * @param[in] pib_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[in] mask the mask
+ * @param[in] data the data we want to match against
+ * @return int 0 if successful, -1 otherwise
+ */
int pib_wait(struct pdbg_target *pib_dt, uint64_t addr, uint64_t mask, uint64_t data)
{
struct pib *pib;
@@ -174,6 +231,13 @@ int pib_wait(struct pdbg_target *pib_dt, uint64_t addr, uint64_t mask, uint64_t
return 0;
}
+/**
+ * @brief OPB read
+ * @param[in] opb_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
int opb_read(struct pdbg_target *opb_dt, uint32_t addr, uint32_t *data)
{
struct opb *opb;
@@ -184,6 +248,13 @@ int opb_read(struct pdbg_target *opb_dt, uint32_t addr, uint32_t *data)
return opb->read(opb, addr64, data);
}
+/**
+ * @brief OPB write
+ * @param[in] opb_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
int opb_write(struct pdbg_target *opb_dt, uint32_t addr, uint32_t data)
{
struct opb *opb;
@@ -195,6 +266,13 @@ int opb_write(struct pdbg_target *opb_dt, uint32_t addr, uint32_t data)
return opb->write(opb, addr64, data);
}
+/**
+ * @brief FSI read
+ * @param[in] fsi_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the read data
+ * @return int 0 if successful, -1 otherwise
+ */
int fsi_read(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t *data)
{
struct fsi *fsi;
@@ -205,6 +283,13 @@ int fsi_read(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t *data)
return fsi->read(fsi, addr64, data);
}
+/**
+ * @brief FSI write
+ * @param[in] fsi_dt the pdbg_target
+ * @param[in] addr the address
+ * @param[out] data the write data
+ * @return int 0 if successful, -1 otherwise
+ */
int fsi_write(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t data)
{
struct fsi *fsi;
@@ -216,13 +301,23 @@ int fsi_write(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t data)
return fsi->write(fsi, addr64, data);
}
+/**
+ * @brief Checks that a pdbg_target has a parent target
+ * @param[in] target A PowerPC FSI Debugger target
+ * @return struct pdbg_target* the input's parent target
+ * @note we assert out if the input is the list head
+ */
struct pdbg_target *require_target_parent(struct pdbg_target *target)
{
assert(target->parent);
return target->parent;
}
-/* Finds the given class. Returns NULL if not found. */
+/**
+ * @brief Finds the target class given a name
+ * @param name the name of the class we want
+ * @return the found pdbg_target_class, otherwise NULL
+ */
struct pdbg_target_class *find_target_class(const char *name)
{
struct pdbg_target_class *target_class;
@@ -234,8 +329,12 @@ struct pdbg_target_class *find_target_class(const char *name)
return NULL;
}
-/* Same as above but dies with an assert if the target class doesn't
- * exist */
+/**
+ * @brief Finds the target class given a name
+ * @param name the name of the class we want
+ * @return the found pdbg_target_class, otherwise assert out
+ * @note same as find_target_class but asserts out if the target class doesn't exist
+ */
struct pdbg_target_class *require_target_class(const char *name)
{
struct pdbg_target_class *target_class;
@@ -248,7 +347,11 @@ struct pdbg_target_class *require_target_class(const char *name)
return target_class;
}
-/* Returns the existing class or allocates space for a new one */
+/**
+ * @brief Returns the existing class or allocates space for a new one
+ * @param name the name of the class we want
+ * @return the found or new pdbg_target_class
+ */
struct pdbg_target_class *get_target_class(const char *name)
{
struct pdbg_target_class *target_class;
@@ -266,8 +369,22 @@ struct pdbg_target_class *get_target_class(const char *name)
return target_class;
}
+/**
+ * @struct __start_hw_units
+ * @brief declaration of __start_hw_units
+ */
extern struct hw_unit_info *__start_hw_units;
+
+/**
+ * @struct __stop_hw_units
+ * @brief declaration of __stop_hw_units
+ */
extern struct hw_init_info *__stop_hw_units;
+
+/**
+ * @brief Find a target given @compat a compatibility member
+ * @param[in] compat the given compatibility
+ */
struct hw_unit_info *find_compatible_target(const char *compat)
{
struct hw_unit_info **p;
@@ -282,8 +399,11 @@ struct hw_unit_info *find_compatible_target(const char *compat)
return NULL;
}
-/* We walk the tree root down disabling targets which might/should
- * exist but don't */
+/**
+ * @brief We walk the tree root down disabling targets which might/should exist but don't
+ * @param[in] target the pdbg_target
+ * @return pdbg_target_status
+ */
enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target)
{
struct pdbg_target *parent;
@@ -344,7 +464,11 @@ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target)
return PDBG_TARGET_ENABLED;
}
-/* Releases a target by first recursively releasing all its children */
+/**
+ * @brief Releases a target by first recursively releasing all its children
+ * @param[in,out] target the pdbg_target
+ * @return void
+ */
void pdbg_target_release(struct pdbg_target *target)
{
struct pdbg_target *child;
@@ -361,8 +485,10 @@ void pdbg_target_release(struct pdbg_target *target)
target->status = PDBG_TARGET_RELEASED;
}
-/*
- * Probe all targets in the device tree.
+/**
+ * @brief Probe all targets in the device tree.
+ * @param[in,out] target the pdbg_target
+ * @return void
*/
void pdbg_target_probe_all(struct pdbg_target *parent)
{
@@ -377,6 +503,12 @@ void pdbg_target_probe_all(struct pdbg_target *parent)
}
}
+/**
+ * @brief Checks if the target is the given class
+ * @param[in] target the pdbg_target
+ * @param class the class name
+ * @return true if the pdbg_target is the class, otherwise false
+ */
bool pdbg_target_is_class(struct pdbg_target *target, const char *class)
{
if (!target || !target->class || !class)
@@ -384,11 +516,22 @@ bool pdbg_target_is_class(struct pdbg_target *target, const char *class)
return strcmp(target->class, class) == 0;
}
+/**
+ * @brief Gets the priv member of pdbg_target
+ * @param[in] target the pdbg_target
+ * @return void* to priv
+ */
void *pdbg_target_priv(struct pdbg_target *target)
{
return target->priv;
}
+/**
+ * @brief Sets the priv member of pdbg_target
+ * @param[in,out] target the pdbg_target
+ * @param[in] void* priv member to set
+ * @return void
+ */
void pdbg_target_priv_set(struct pdbg_target *target, void *priv)
{
target->priv = priv;
diff --git a/libpdbg/target.h b/libpdbg/target.h
index 729b122..0c4413b 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -23,14 +23,32 @@
#include "compiler.h"
#include "libpdbg.h"
-enum chip_type {CHIP_UNKNOWN, CHIP_P8, CHIP_P8NV, CHIP_P9};
+/** @file target.h */
+/** A chip type
+* A list of currently supported processor chip types
+*/
+enum chip_type {
+ CHIP_UNKNOWN, /**< Unknown */
+ CHIP_P8, /**< P8 */
+ CHIP_P8NV, /**< P8 Prime */
+ CHIP_P9, /**< P9 */
+};
+
+/**
+ * @struct pdbg_target_class
+ * @brief A container as a doubly linked list
+ */
struct pdbg_target_class {
char *name;
struct list_head targets;
struct list_node class_head_link;
};
+/**
+ * @struct pdbg_target
+ * @brief The PowerPC FSI Debugger target
+ */
struct pdbg_target {
char *name;
char *compatible;
@@ -51,42 +69,108 @@ struct pdbg_target {
void *priv;
};
+/**
+ * @brief Checks that a pdbg_target has a parent target
+ * @param[in] target A PowerPC FSI Debugger target
+ * @return struct pdbg_target* the input's parent target
+ * @note we assert out if the input is the list head
+ */
struct pdbg_target *require_target_parent(struct pdbg_target *target);
+
+/**
+ * @brief Finds the given class
+ * @param name the name of the class we want
+ * @return the found pdbg_target_class, otherwise NULL
+ */
struct pdbg_target_class *find_target_class(const char *name);
+
+/**
+ * @brief Finds the target class given a name
+ * @param name the name of the class we want
+ * @return the found pdbg_target_class, otherwise assert out
+ * @note same as find_target_class but asserts out if the target class doesn't exist
+ */
struct pdbg_target_class *require_target_class(const char *name);
+
+/**
+ * @brief Returns the existing class or allocates space for a new one
+ * @param name the name of the class we want
+ * @return the found or new pdbg_target_class
+ */
struct pdbg_target_class *get_target_class(const char *name);
+
+/**
+ * @brief Checks if the target is the given class
+ * @param[in] target the pdbg_target
+ * @param class the class name
+ * @return true if the pdbg_target is the class, otherwise false
+ */
bool pdbg_target_is_class(struct pdbg_target *target, const char *class);
-/* This works and should be safe because struct pdbg_target is guaranteed to be
+/**
+ * @brief A macro that casts @x x as a translate function pointer
+ * @param[in] x
+ * @note This works and should be safe because struct pdbg_target is guaranteed to be
* the first member of the specialised type (see the DECLARE_HW_UNIT definition
* below). I'm not sure how sane it is though. Probably not very but it does
- * remove a bunch of tedious container_of() typing */
+ * remove a bunch of tedious container_of() typing
+ */
#define translate_cast(x) (uint64_t (*)(struct pdbg_target *, uint64_t)) (x)
+/**
+ * @struct empty_list
+ * @brief Declares a list_head named empty_list
+ * @note this is a special node that refers to the linked list, without being a list node
+ */
extern struct list_head empty_list;
+
+/**
+ * @struct target_classes
+ * @brief Declares list_head named target_classes
+ * @note this is a special node that refers to the linked list, without being a list node
+ */
extern struct list_head target_classes;
+/**
+ * @brief A macro that iterates through a target_class (list) for a given class name
+ * @param[in] class_name the class name
+ * @param[in] target the target list
+ */
#define for_each_class_target(class_name, target) \
list_for_each((find_target_class(class_name) ? &require_target_class(class_name)->targets : &empty_list), target, class_link)
+/**
+ * @brief A macro that iterates through a list @target_class target classes
+ * @param[in] target_class the target class
+ */
#define for_each_target_class(target_class) \
list_for_each(&target_classes, target_class, class_head_link)
+/**
+ * @struct hw_unit_info
+ * @brief Declares HW unit information
+ */
struct hw_unit_info {
void *hw_unit;
size_t size;
};
+
+/**
+ * @brief Find a target given @compat a compatibility member
+ * @param[in] compat the given compatibility
+ */
struct hw_unit_info *find_compatible_target(const char *compat);
-/* We can't pack the structs themselves directly into a special
+/**
+ * @brief A macro that packs pointers name into a special section
+ * @note We can't pack the structs themselves directly into a special
* section because there doesn't seem to be any standard way of doing
* that due to alignment rules. So instead we pack pointers into a
* special section.
- *
* If this macro fails to compile for you, you've probably not
* declared the struct pdbg_target as the first member of the
* container struct. Not doing so will break other assumptions.
- * */
+ */
#define DECLARE_HW_UNIT(name) \
static inline void name ##_hw_unit_check(void) { \
((void)sizeof(char[1 - 2 * (container_off(typeof(name), target) != 0)])); \
@@ -95,6 +179,10 @@ struct hw_unit_info *find_compatible_target(const char *compat);
{ .hw_unit = &name, .size = sizeof(name) }; \
const struct hw_unit_info __used __section("hw_units") *name ##_hw_unit_p = &name ##_hw_unit
+/**
+ * @struct htm
+ * @brief Defines a HTM target
+ */
struct htm {
struct pdbg_target target;
int (*start)(struct htm *);
@@ -103,44 +191,104 @@ struct htm {
int (*dump)(struct htm *, char *);
int (*record)(struct htm *, char *);
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in htm
+ * @return struct htm*
+ */
#define target_to_htm(x) container_of(x, struct htm, target)
+/**
+ * @struct adu
+ * @brief Defines a ADU target
+ */
struct adu {
struct pdbg_target target;
int (*getmem)(struct adu *, uint64_t, uint64_t *, int);
int (*putmem)(struct adu *, uint64_t, uint64_t, int, int);
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in adu
+ * @return struct adu*
+ */
#define target_to_adu(x) container_of(x, struct adu, target)
+/**
+ * @struct pib
+ * @brief Defines a PIB target
+ */
struct pib {
struct pdbg_target target;
int (*read)(struct pib *, uint64_t, uint64_t *);
int (*write)(struct pib *, uint64_t, uint64_t);
void *priv;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in pib
+ * @return struct pib*
+ */
#define target_to_pib(x) container_of(x, struct pib, target)
+/**
+ * @struct opb
+ * @brief Defines a OPB target
+ */
struct opb {
struct pdbg_target target;
int (*read)(struct opb *, uint32_t, uint32_t *);
int (*write)(struct opb *, uint32_t, uint32_t);
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in opb
+ * @return struct opb*
+ */
#define target_to_opb(x) container_of(x, struct opb, target)
+/**
+ * @struct fsi
+ * @brief Defines a FSI target
+ */
struct fsi {
struct pdbg_target target;
int (*read)(struct fsi *, uint32_t, uint32_t *);
int (*write)(struct fsi *, uint32_t, uint32_t);
enum chip_type chip_type;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in fsi
+ * @return struct fsi*
+ */
#define target_to_fsi(x) container_of(x, struct fsi, target)
+/**
+ * @struct core
+ * @brief Defines a CORE target
+ */
struct core {
struct pdbg_target target;
bool release_spwkup;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in core
+ * @return struct core*
+ */
#define target_to_core(x) container_of(x, struct core, target)
+/**
+ * @struct thread
+ * @brief Refers to CPU threads on the host
+ */
struct thread {
struct pdbg_target target;
struct thread_state status;
@@ -163,46 +311,122 @@ struct thread {
int (*ram_putxer)(struct pdbg_target *, uint64_t value);
int (*enable_attn)(struct pdbg_target *);
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in thread
+ * @return struct thread*
+ */
#define target_to_thread(x) container_of(x, struct thread, target)
-/* Place holder for chiplets which we just want translation for */
+/**
+ * @struct chiplet
+ * @brief Defines a CHIPLET target
+ * @note Place holder for chiplets which we just want translation for
+ */
struct chiplet {
struct pdbg_target target;
int (*getring)(struct chiplet *, uint64_t, int64_t, uint32_t[]);
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in chiplet
+ * @return struct chiplet*
+ */
#define target_to_chiplet(x) container_of(x, struct chiplet, target)
+/**
+ * @struct xbus
+ * @brief Defines a XBUS target
+ */
struct xbus {
struct pdbg_target target;
uint32_t ring_id;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in xbus
+ * @return struct xbus*
+ */
#define target_to_xbus(x) container_of(x, struct xbus, target)
+/**
+ * @struct mcs
+ * @brief Defines a MCS target
+ */
struct mcs {
struct pdbg_target target;
uint32_t chip_unit;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in mcs
+ * @return struct mcs*
+ */
#define target_to_mcs(x) container_of(x, struct mcs, target)
+/**
+ * @struct pec
+ * @brief Defines a PEC target
+ */
struct pec {
struct pdbg_target target;
uint32_t chip_unit;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in pec
+ * @return struct pec*
+ */
#define target_to_pec(x) container_of(x, struct pec, target)
+/**
+ * @struct eq
+ * @brief Defines a EQ target
+ */
struct eq {
struct pdbg_target target;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in eq
+ * @return struct eq*
+ */
#define target_to_eq(x) container_of(x, struct eq, target);
+/**
+ * @struct ex
+ * @brief Defines a EX target
+ */
struct ex {
struct pdbg_target target;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in ex
+ * @return struct ex*
+ */
#define target_to_ex(x) container_of(x, struct ex, target)
+/**
+ * @struct ec
+ * @brief Defines a EC target
+ */
struct ec {
struct pdbg_target target;
};
+
+/**
+ * @brief A macro that retrieves the struct given a pointer 'target' member
+ * @param[in] x A pointer to the 'target' field in ec
+ * @return struct ec*
+ */
#define target_to_ec(x) container_of(x, struct ec, target)
#endif
--
2.14.1
More information about the Pdbg
mailing list