doc: Move documents into subdirectories

This change creates the following directories under docs/
in order to provide a grouping for the content:

- components
- design
- getting_started
- perf
- process

In each of these directories an index.rst file is created
and this serves as an index / landing page for each of the
groups when the pages are compiled. Proper layout of the
top-level table of contents relies on this directory/index
structure.

Without this patch it is possible to build the documents
correctly with Sphinx but the output looks messy because
there is no overall hierarchy.

Change-Id: I3c9f4443ec98571a56a6edf775f2c8d74d7f429f
Signed-off-by: Paul Beesley <paul.beesley@arm.com>
diff --git a/docs/design/psci-pd-tree.rst b/docs/design/psci-pd-tree.rst
new file mode 100644
index 0000000..2e2163a
--- /dev/null
+++ b/docs/design/psci-pd-tree.rst
@@ -0,0 +1,311 @@
+PSCI Power Domain Tree design
+=============================
+
+
+
+
+.. contents::
+
+--------------
+
+Requirements
+------------
+
+#. A platform must export the ``plat_get_aff_count()`` and
+   ``plat_get_aff_state()`` APIs to enable the generic PSCI code to
+   populate a tree that describes the hierarchy of power domains in the
+   system. This approach is inflexible because a change to the topology
+   requires a change in the code.
+
+   It would be much simpler for the platform to describe its power domain tree
+   in a data structure.
+
+#. The generic PSCI code generates MPIDRs in order to populate the power domain
+   tree. It also uses an MPIDR to find a node in the tree. The assumption that
+   a platform will use exactly the same MPIDRs as generated by the generic PSCI
+   code is not scalable. The use of an MPIDR also restricts the number of
+   levels in the power domain tree to four.
+
+   Therefore, there is a need to decouple allocation of MPIDRs from the
+   mechanism used to populate the power domain topology tree.
+
+#. The current arrangement of the power domain tree requires a binary search
+   over the sibling nodes at a particular level to find a specified power
+   domain node. During a power management operation, the tree is traversed from
+   a 'start' to an 'end' power level. The binary search is required to find the
+   node at each level. The natural way to perform this traversal is to
+   start from a leaf node and follow the parent node pointer to reach the end
+   level.
+
+   Therefore, there is a need to define data structures that implement the tree in
+   a way which facilitates such a traversal.
+
+#. The attributes of a core power domain differ from the attributes of power
+   domains at higher levels. For example, only a core power domain can be identified
+   using an MPIDR. There is no requirement to perform state coordination while
+   performing a power management operation on the core power domain.
+
+   Therefore, there is a need to implement the tree in a way which facilitates this
+   distinction between a leaf and non-leaf node and any associated
+   optimizations.
+
+--------------
+
+Design
+------
+
+Describing a power domain tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 1., the existing platform APIs
+``plat_get_aff_count()`` and ``plat_get_aff_state()`` have been
+removed. A platform must define an array of unsigned chars such that:
+
+#. The first entry in the array specifies the number of power domains at the
+   highest power level implemented in the platform. This caters for platforms
+   where the power domain tree does not have a single root node, for example,
+   the FVP has two cluster power domains at the highest level (1).
+
+#. Each subsequent entry corresponds to a power domain and contains the number
+   of power domains that are its direct children.
+
+#. The size of the array minus the first entry will be equal to the number of
+   non-leaf power domains.
+
+#. The value in each entry in the array is used to find the number of entries
+   to consider at the next level. The sum of the values (number of children) of
+   all the entries at a level specifies the number of entries in the array for
+   the next level.
+
+The following example power domain topology tree will be used to describe the
+above text further. The leaf and non-leaf nodes in this tree have been numbered
+separately.
+
+::
+
+                                         +-+
+                                         |0|
+                                         +-+
+                                        /   \
+                                       /     \
+                                      /       \
+                                     /         \
+                                    /           \
+                                   /             \
+                                  /               \
+                                 /                 \
+                                /                   \
+                               /                     \
+                            +-+                       +-+
+                            |1|                       |2|
+                            +-+                       +-+
+                           /   \                     /   \
+                          /     \                   /     \
+                         /       \                 /       \
+                        /         \               /         \
+                     +-+           +-+         +-+           +-+
+                     |3|           |4|         |5|           |6|
+                     +-+           +-+         +-+           +-+
+            +---+-----+    +----+----|     +----+----+     +----+-----+-----+
+            |   |     |    |    |    |     |    |    |     |    |     |     |
+            |   |     |    |    |    |     |    |    |     |    |     |     |
+            v   v     v    v    v    v     v    v    v     v    v     v     v
+          +-+  +-+   +-+  +-+  +-+  +-+   +-+  +-+  +-+   +-+  +--+  +--+  +--+
+          |0|  |1|   |2|  |3|  |4|  |5|   |6|  |7|  |8|   |9|  |10|  |11|  |12|
+          +-+  +-+   +-+  +-+  +-+  +-+   +-+  +-+  +-+   +-+  +--+  +--+  +--+
+
+This tree is defined by the platform as the array described above as follows:
+
+::
+
+        #define PLAT_NUM_POWER_DOMAINS       20
+        #define PLATFORM_CORE_COUNT          13
+        #define PSCI_NUM_NON_CPU_PWR_DOMAINS \
+                           (PLAT_NUM_POWER_DOMAINS - PLATFORM_CORE_COUNT)
+
+        unsigned char plat_power_domain_tree_desc[] = { 1, 2, 2, 2, 3, 3, 3, 4};
+
+Removing assumptions about MPIDRs used in a platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 2., it is assumed that the platform assigns a
+unique number (core index) between ``0`` and ``PLAT_CORE_COUNT - 1`` to each core
+power domain. MPIDRs could be allocated in any manner and will not be used to
+populate the tree.
+
+``plat_core_pos_by_mpidr(mpidr)`` will return the core index for the core
+corresponding to the MPIDR. It will return an error (-1) if an MPIDR is passed
+which is not allocated or corresponds to an absent core. The semantics of this
+platform API have changed since it is required to validate the passed MPIDR. It
+has been made a mandatory API as a result.
+
+Another mandatory API, ``plat_my_core_pos()`` has been added to return the core
+index for the calling core. This API provides a more lightweight mechanism to get
+the index since there is no need to validate the MPIDR of the calling core.
+
+The platform should assign the core indices (as illustrated in the diagram above)
+such that, if the core nodes are numbered from left to right, then the index
+for a core domain will be the same as the index returned by
+``plat_core_pos_by_mpidr()`` or ``plat_my_core_pos()`` for that core. This
+relationship allows the core nodes to be allocated in a separate array
+(requirement 4.) during ``psci_setup()`` in such an order that the index of the
+core in the array is the same as the return value from these APIs.
+
+Dealing with holes in MPIDR allocation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For platforms where the number of allocated MPIDRs is equal to the number of
+core power domains, for example, Juno and FVPs, the logic to convert an MPIDR to
+a core index should remain unchanged. Both Juno and FVP use a simple collision
+proof hash function to do this.
+
+It is possible that on some platforms, the allocation of MPIDRs is not
+contiguous or certain cores have been disabled. This essentially means that the
+MPIDRs have been sparsely allocated, that is, the size of the range of MPIDRs
+used by the platform is not equal to the number of core power domains.
+
+The platform could adopt one of the following approaches to deal with this
+scenario:
+
+#. Implement more complex logic to convert a valid MPIDR to a core index while
+   maintaining the relationship described earlier. This means that the power
+   domain tree descriptor will not describe any core power domains which are
+   disabled or absent. Entries will not be allocated in the tree for these
+   domains.
+
+#. Treat unallocated MPIDRs and disabled cores as absent but still describe them
+   in the power domain descriptor, that is, the number of core nodes described
+   is equal to the size of the range of MPIDRs allocated. This approach will
+   lead to memory wastage since entries will be allocated in the tree but will
+   allow use of a simpler logic to convert an MPIDR to a core index.
+
+Traversing through and distinguishing between core and non-core power domains
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 3 and 4, separate data structures have been defined
+to represent leaf and non-leaf power domain nodes in the tree.
+
+.. code:: c
+
+    /*******************************************************************************
+     * The following two data structures implement the power domain tree. The tree
+     * is used to track the state of all the nodes i.e. power domain instances
+     * described by the platform. The tree consists of nodes that describe CPU power
+     * domains i.e. leaf nodes and all other power domains which are parents of a
+     * CPU power domain i.e. non-leaf nodes.
+     ******************************************************************************/
+    typedef struct non_cpu_pwr_domain_node {
+        /*
+         * Index of the first CPU power domain node level 0 which has this node
+         * as its parent.
+         */
+        unsigned int cpu_start_idx;
+
+        /*
+         * Number of CPU power domains which are siblings of the domain indexed
+         * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx
+         * -> cpu_start_idx + ncpus' have this node as their parent.
+         */
+        unsigned int ncpus;
+
+        /* Index of the parent power domain node */
+        unsigned int parent_node;
+
+        -----
+    } non_cpu_pd_node_t;
+
+    typedef struct cpu_pwr_domain_node {
+        u_register_t mpidr;
+
+        /* Index of the parent power domain node */
+        unsigned int parent_node;
+
+        -----
+    } cpu_pd_node_t;
+
+The power domain tree is implemented as a combination of the following data
+structures.
+
+::
+
+    non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
+    cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
+
+Populating the power domain tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``populate_power_domain_tree()`` function in ``psci_setup.c`` implements the
+algorithm to parse the power domain descriptor exported by the platform to
+populate the two arrays. It is essentially a breadth-first-search. The nodes for
+each level starting from the root are laid out one after another in the
+``psci_non_cpu_pd_nodes`` and ``psci_cpu_pd_nodes`` arrays as follows:
+
+::
+
+    psci_non_cpu_pd_nodes -> [[Level 3 nodes][Level 2 nodes][Level 1 nodes]]
+    psci_cpu_pd_nodes -> [Level 0 nodes]
+
+For the example power domain tree illustrated above, the ``psci_cpu_pd_nodes``
+will be populated as follows. The value in each entry is the index of the parent
+node. Other fields have been ignored for simplicity.
+
+::
+
+                          +-------------+     ^
+                    CPU0  |      3      |     |
+                          +-------------+     |
+                    CPU1  |      3      |     |
+                          +-------------+     |
+                    CPU2  |      3      |     |
+                          +-------------+     |
+                    CPU3  |      4      |     |
+                          +-------------+     |
+                    CPU4  |      4      |     |
+                          +-------------+     |
+                    CPU5  |      4      |     | PLATFORM_CORE_COUNT
+                          +-------------+     |
+                    CPU6  |      5      |     |
+                          +-------------+     |
+                    CPU7  |      5      |     |
+                          +-------------+     |
+                    CPU8  |      5      |     |
+                          +-------------+     |
+                    CPU9  |      6      |     |
+                          +-------------+     |
+                    CPU10 |      6      |     |
+                          +-------------+     |
+                    CPU11 |      6      |     |
+                          +-------------+     |
+                    CPU12 |      6      |     v
+                          +-------------+
+
+The ``psci_non_cpu_pd_nodes`` array will be populated as follows. The value in
+each entry is the index of the parent node.
+
+::
+
+                          +-------------+     ^
+                    PD0   |      -1     |     |
+                          +-------------+     |
+                    PD1   |      0      |     |
+                          +-------------+     |
+                    PD2   |      0      |     |
+                          +-------------+     |
+                    PD3   |      1      |     | PLAT_NUM_POWER_DOMAINS -
+                          +-------------+     | PLATFORM_CORE_COUNT
+                    PD4   |      1      |     |
+                          +-------------+     |
+                    PD5   |      2      |     |
+                          +-------------+     |
+                    PD6   |      2      |     |
+                          +-------------+     v
+
+Each core can find its node in the ``psci_cpu_pd_nodes`` array using the
+``plat_my_core_pos()`` function. When a core is turned on, the normal world
+provides an MPIDR. The ``plat_core_pos_by_mpidr()`` function is used to validate
+the MPIDR before using it to find the corresponding core node. The non-core power
+domain nodes do not need to be identified.
+
+--------------
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*