website: Add API documentation

Change-Id: Iea4fa8d281c58c4c27cf342a5bc87d7ec39d4116
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5-website/+/34897
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: Jason Lowe-Power <power.jg@gmail.com>
diff --git a/_data/documentation.yml b/_data/documentation.yml
index bbcea56..40648d6 100755
--- a/_data/documentation.yml
+++ b/_data/documentation.yml
@@ -37,6 +37,10 @@
       id: gem5_resources
       url: /documentation/general_docs/gem5_resources
 
+    - title: gem5 APIs
+      id: gem5-apis
+      url: /documentation/general_docs/gem5-apis
+
     - title: Full System
       id: fullsystem
       subitems:
diff --git a/_pages/documentation/general_docs/apis.md b/_pages/documentation/general_docs/apis.md
new file mode 100644
index 0000000..d46df6e
--- /dev/null
+++ b/_pages/documentation/general_docs/apis.md
@@ -0,0 +1,210 @@
+---

+layout: documentation

+title: gem5-resources

+doc: gem5 documentation

+parent: gem5-apis

+permalink: /documentation/general_docs/gem5-apis/

+authors: Bobby R. Bruce

+---

+

+For complete documentation of all methods and variables tagged as APIs, please

+see our [Doxygen Module page](

+http://doxygen.gem5.org/release/v20-1-0-0/modules.html).

+

+# The gem5 API

+

+In efforts to improve product stability, the gem5 development team is gradually

+tagging methods and variables within gem5 as APIs which developers will need to

+undergo specific procedures to change. Our goal with the gem5 API is to provide

+a stable interface for users to build gem5 models, and extend the gem5

+code-base, with guarantees these APIs will not change in a dramatic sudden

+manner between gem5 releases.

+

+## How is the gem5 API documented?

+

+We document the gem5 APIs using the [Doxygen documentation generation tool](

+https://www.doxygen.nl/index.html). This means you may see the API tagged

+at the level of source-code and via our [web-based documentation](

+http://doxygen.gem5.org). We use Doxygen's `@ingroup` tag, to specify a

+method/variables as part of the gem5 API. We break the API down into

+sub-domains such as `api_simobject` or `api_ports`, though all the gem5 APIs

+are tagged with the prefix `api_`. For example, we tag SimObject's `params()`

+function as follows:

+

+```cpp

+/**

+* @return This function returns the cached copy of the object parameters.

+*

+* @ingroup api_simobject

+*/

+const Params *params() const { return _params; }

+```

+

+Via Doxygen automatic generation, the list of gem5 APIs can be found on the

+[Doxygen module page](http://doxygen.gem5.org/release/current/modules.html).

+In this example, the entire list of SimObject APIs are noted in the

+[SimObject API page](

+http://doxygen.gem5.org/release/current/group__api__simobject.html). The

+definitions of different API groups can be found in

+[`src/doxygen/group_definitions.hh`](

+https://gem5.googlesource.com/public/gem5/+/refs/heads/master/src/doxygen/group_definitions.hh).

+

+### Notes for developers

+

+If a developer wishes to tag a new method/variable as part of the gem5 API,

+the gem5 community should be consulted. APIs are intended to stay unaltered for

+some time. To avoid the gem5 project becoming encumbered with "too many APIs",

+we strongly advise those wishing to extend the API to communicate to the

+gem5 development team as to why the API will be of value. The

+[gem5-dev mailing list](/mailing_lists/) is a good communication channel for

+this.

+

+## How can the API change?

+

+We do not guarantee the gem5 API will never change over time. gem5 is a

+product under continual development which must adapt to the needs of the

+computer architecture research community. However, we guarantee that API

+changes will follow strict guidelines outlined below.

+

+1. When an API method or variable is altered, it will be done so in a way in

+which the new API will exist alongside the old, with the old API tagged as

+deprecated and still functional.

+

+2. The old, deprecated API will exist for two gem5 major cycles before being

+removed entirely from code-base, though gem5 developers may choose to keep a

+deprecated API in the code-base for longer. For example, if an API is tagged as

+deprecated in gem5 21.0, it will also still exist (still tagged as deprecated)

+in gem5 21.1. It may be removed entirely in gem5 21.2, though this will be left

+to the discretion of the gem5 developers.

+

+3. The gem5 deprecated C++ APIs will be tagged with the C++ deprecated

+attribute (`[[deprecated(<msg>)]]`). When utilizing a deprecated C++ API, a

+warning will be given at compilation time specifying which API to transition

+to. The gem5 deprecated Python parameter APIs are wrapped with our [bespoke

+`DeprecatedParam` class](

+https://gem5.googlesource.com/public/gem5/+/bd13e8e206e6c86581cf9afa904ef1060351a4b0/src/python/m5/params.py#2166).

+Python parameters wrapped in this class will throw an warning when used and

+specify which API to transition to.

+

+### Notes for Developers

+

+Prior to making any changes to the gem5 API the [gem5-dev mailing list](

+/mailing_lists/) should be consulted. Changing the API, for whatever reason,

+**will** be subject to higher scrutiny than other changes. Developers should

+be prepared to provide compelling arguments as to why the API needs changed. We

+strongly recommend API changes are discussed or they may be rejected during the

+Gerrit Code review.

+

+When creating a new API the old API must be tagged as deprecated and the new

+API created to exist alongside the old. **It is of upmost importance that the

+old, deprecated API is maintained and not deleted**.

+

+As an example, take the following code:

+

+```cpp

+/**

+ * @ingroup api_bitfield

+ */

+inline uint64_t

+mask(int first, int last)

+{

+    return mbits((uint64_t)-1LL, first, last);

+}

+```

+

+This function is part of the gem5 bitfield API. It is a basic mask function

+that takes the MSB (first) and the LSB (last) for the generation of a 64-bit.

+Let us assume there is a good argument that this function should be replaced

+with one that takes the MSB (first), and the length of the mask instead.

+

+To start, the old API needs maintained (i.e., not changed) and tagged with the

+`[[deprecated(<msg>)]]` tag. The message (`<msg>`) Should state the new API

+to use, and the API tagging should be removed. The new API should then be

+created and tagged. So, using our example:

+

+```cpp

+[[deprecated("Use mask_length instead.")]]

+inline uint64_t

+mask(int first, int last)

+{

+    return mbits((uint64_t)-1LL, first, last);

+}

+

+/**

+ * @ingroup api_bitfield

+ */

+inline uint64_t

+mask_length(int first, int length)

+{

+    return mbits((uint64_t)-1LL, first, first + length);

+}

+```

+

+Here a new function, `mask_length`, has been created. It has been tagged

+correctly via Doxygen. The old API, `mask` exists but has the

+`[[deprecated]]` annotation added. The message provided states which API

+replaces it.

+

+The developer then needs to replace all usage of `mask` in the code-base with

+`mask_length`. A warning will be given at compile time if `mask` is used,

+stating that it is deprecated and to "Use mask\_length instead.".

+

+Occasionally there may be need to change the python API interface, which

+relates to tagged APIs. For example, let's take the below code:

+

+```python

+class TLBCoalescer(ClockedObject):

+    type = 'TLBCoalescer'

+    cxx_class = 'TLBCoalescer'

+    cxx_header = 'gpu-compute/tlb_coalescer.hh'

+

+    ...

+

+    slave    = VectorResponsePort("Port on side closer to CPU/CU")

+    master   = VectorRequestPort("Port on side closer to memory")

+

+   ...

+```

+

+[In recent revisions](

+https://gem5.googlesource.com/public/gem5/+/392c1ced53827198652f5eda58e1874246b024f4)

+the terms `master` and `slave` have been replaced. Though, the `slave` and

+`master` terminology are widely used, so much so we consider them part of the

+old API. We therefore wish to deprecate this API is a safe manner while

+changing `master` and `slave` with `cpu_side_ports` and `mem_side_ports`. To

+do so we would maintain the `master` and `slave` variables but utilize our

+[`DeprecatedParam` Class](

+https://gem5.googlesource.com/public/gem5/+/bd13e8e206e6c86581cf9afa904ef1060351a4b0/src/python/m5/params.py#2166)

+to produce warnings when and if these deprecated variables are used. Working on

+our example, we would produce the following:

+

+```python

+class TLBCoalescer(ClockedObject):

+    type = 'TLBCoalescer'

+    cxx_class = 'TLBCoalescer'

+    cxx_header = 'gpu-compute/tlb_coalescer.hh'

+

+    ...

+

+    cpu_side_ports = VectorResponsePort("Port on side closer to CPU/CU")

+    slave    = DeprecatedParam(cpu_side_ports,

+                        '`slave` is now called `cpu_side_ports`')

+    mem_side_ports = VectorRequestPort("Port on side closer to memory")

+    master   = DeprecatedParam(mem_side_ports,

+                        '`master` is now called `mem_side_ports`')

+

+   ...

+```

+

+Note the use of `DeprecatedParam` that both ensures `master` and `slave` still

+function by redirecting to `mem_side_ports` and `cpu_side_ports` respectively,

+as well as providing a comment explaining why this API was deprecated. This

+will be displayed to the user as a warning if `master` or `slave` are ever

+used.

+

+As with all changes to the gem5 source, these changes will have to go through

+our Gerrit code review system before being merged into the `develop` branch,

+and eventually making its way to our `stable` branch as part of a gem5 release.

+In line with our API policy, these deprecated APIs must exist in a

+marked-as-deprecated state for two gem5 major release cycles. After this they

+may be removed though developers are under no requirement to do so.