misc: Merge branch develop into stable for v22.1

Change-Id: Iee0f0de534b5cf76667e99949d46875f7459e81a
diff --git a/_data/documentation.yml b/_data/documentation.yml
index 2acb099..2a0a53f 100755
--- a/_data/documentation.yml
+++ b/_data/documentation.yml
@@ -62,6 +62,8 @@
           url: http://doxygen.gem5.org/release/v22-0-0-0/index.html
         - page: v22.0.0.1
           url: http://doxygen.gem5.org/release/v22-0-0-1/index.html
+        - page: v22.1.0.0
+          url: http://doxygen.gem5.org/release/v22-1-0-0/index.html
 
     - title: gem5 standard library
       id: gem5-standard-library
@@ -131,6 +133,8 @@
           url: /documentation/general_docs/ruby/cache-coherence-protocols
         - page: Garnet 2.0
           url: /documentation/general_docs/ruby/garnet-2
+        - page: HeteroGarnet
+          url: /documentation/general_docs/ruby/heterogarnet
         - page: MOESI CMP directory
           url: /documentation/general_docs/ruby/MOESI_CMP_directory
         - page: Garnet Synthetic Traffic
@@ -157,6 +161,7 @@
 
     - title: CPU Models
       id: cpu_models
+      url: /documentation/general_docs/cpu_models/
       subitems:
         - page: SimpleCPU
           url: /documentation/general_docs/cpu_models/SimpleCPU
diff --git a/_pages/contributing.md b/_pages/contributing.md
index e9e3382..e066390 100644
--- a/_pages/contributing.md
+++ b/_pages/contributing.md
@@ -79,9 +79,11 @@
 
 ## Making modifications
 
+### C/CPP
+
 Different tasks will require the project to be modified in different ways.
-Though, in all cases, our style-guide must be adhered to. The full style guide
-is outlined [here](/documentation/general_docs/development/coding_style).
+Though, in all cases, our style-guide must be adhered to. The full C/C++ style
+guide is outlined [here](/documentation/general_docs/development/coding_style).
 
 As a high-level overview:
 
@@ -139,6 +141,55 @@
 }
 ```
 
+### Python
+
+We use [Python Black](https://github.com/psf/black) to format our Python code
+to the correct style. To install:
+
+```sh
+pip install black
+```
+
+Then run on modified/added python files using:
+
+```sh
+black <files/directories>
+```
+
+For varibale/method/etc. naming conventions, please follow the [PEP 8 naming
+convention recommendations](
+https://peps.python.org/pep-0008/#naming-conventions). While we try our best to
+enforce naming conventions across the gem5 project, we are aware there are
+instances where they are not. In such cases please **follow the convention
+of the code you are modifying**.
+
+### Using pre-commit
+
+To help enforce our style guide we use use [pre-commit](
+https://pre-commit.com). pre-commit is a git hook and, as such, must be
+explicitly installed by a gem5 developer.
+
+To install the gem5 pre-commit checks, execute the following in the gem5
+directory:
+
+```sh
+pip install pre-commit
+pre-commit install
+```
+
+Once installed pre-commit will run checks on modified code prior to running the
+`git commit` command (see [our section on commiting](#committing) for more
+details on commiting your changes). If these tests fail you will not be able to
+commit.
+
+These same pre-commit checks are run as part of Gerrit's CI checks (those
+which must pass to obtain a "Verified" status required for a change to be
+incorporated into the develop branch). It is therefore recommended that
+developers install pre-commit to catch style errors early.
+
+**Note:** As of the v22.0 release, the pre-commit hook is only available on the
+develop branch.
+
 ## Compiling and running tests
 
 The minimum criteria for a change to be submitted is that the code is
@@ -322,7 +373,7 @@
 Then push the new changes to Gerrit:
 
 ```Shell
-git push original HEAD:refs/for/develop
+git push origin HEAD:refs/for/develop
 ```
 
 If for some reason you no longer have your original workspace, you may pull
@@ -349,3 +400,11 @@
 Stable releases of gem5 are published three times per year. Therefore, a change
 successfully submitted to the `develop` branch will be merged into the `stable`
 branch within three to four months after submission.
+
+## gem5 Bootcamp 2022
+
+As part of [gem5's 2022 Bootcamp](/events/boot-camp-2022), contributing to gem5
+was taught as a tutorial. Slides for this tutorial can be found [here](
+https://ucdavis365-my.sharepoint.com/:p:/g/personal/jlowepower_ucdavis_edu/EQLtRAKI94JKjgk5pBmJtG8B3ssv9MaR0a2i92G0TwHK8Q?e=KN3NIppm2kg&action=embedview&wdbipreview=true).
+A video recording of this tutorial can be found [here](
+https://www.youtube.com/watch?v=T67wzFd1gVY).
diff --git a/_pages/documentation/gem5-stdlib/0-overview.md b/_pages/documentation/gem5-stdlib/0-overview.md
index 7097019..ebbc4f8 100644
--- a/_pages/documentation/gem5-stdlib/0-overview.md
+++ b/_pages/documentation/gem5-stdlib/0-overview.md
@@ -21,6 +21,10 @@
 **Note: The documentation/tutorial/etc. related to the standard library are for the v22.0 release.
 Please ensure you have the correct version of gem5 before proceeding.**
 
+As part of [gem5's 2022 Bootcamp](/events/boot-camp-2022), the stdlib was taught as a tutorial.
+Slides for this tutorial can be found [here](https://ucdavis365-my.sharepoint.com/:p:/g/personal/jlowepower_ucdavis_edu/EWxNhA79fP1Fk4byc0kfPK4BQDDTHdeNGA9p7SkAzvVO-Q?e=Y8aKMv&action=embedview&wdbipreview=true).
+A video recording of this tutorial can be found [here](https://www.youtube.com/watch?v=vbruiMyIFsA).
+
 <!-- Could use a nice picture here showing the main modules of the stdlib and how they relate -->
 
 ## The gem5 stdlib components package and its design philosophy
diff --git a/_pages/documentation/general_docs/checkpoints.md b/_pages/documentation/general_docs/checkpoints.md
index a61c5cd..87ab340 100644
--- a/_pages/documentation/general_docs/checkpoints.md
+++ b/_pages/documentation/general_docs/checkpoints.md
@@ -11,7 +11,7 @@
 ## Creation ##
 First of all, you need to create a checkpoint. Each checkpoint as saved in a new directory named 'cpt.TICKNUMBER', where TICKNUMBER refers to the tick value at which this checkpoint was created. There are several ways in which a checkpoint can be created: 
 * After booting the gem5 simulator, execute the command m5 checkpoint. One can execute the command manually using m5term, or include it in a run script to do this automatically after the Linux kernel has booted up.
-* There is a pseudo instruction that can be used for creating checkpoints. For example, one may include this pseduo instruction in an application program, so that the checkpoint is created when the application has reached a certain state.
+* There is a pseudo instruction that can be used for creating checkpoints. For example, one may include this pseudo instruction in an application program, so that the checkpoint is created when the application has reached a certain state.
 * The option **-****-take-checkpoints** can be provided to the python scripts (fs.py, ruby_fs.py) so that checkpoints are dumped periodically. The option **-****-checkpoint-at-end** can be used for creating the checkpoint at the end of the simulation. Take a look at the file **configs/common/Options.py** for these options.
 
 While creating checkpoints with Ruby memory model, it is necessary to use the MOESI hammer protocol. This is because checkpointing the correct memory state requires that the caches are flushed to the memory. This flushing operation is currently supported only with the MOESI hammer protocol.
diff --git a/_pages/documentation/general_docs/cpu_models/execution_basics.md b/_pages/documentation/general_docs/cpu_models/execution_basics.md
index b7ddb8f..cdbad1f 100644
--- a/_pages/documentation/general_docs/cpu_models/execution_basics.md
+++ b/_pages/documentation/general_docs/cpu_models/execution_basics.md
@@ -8,6 +8,12 @@
 
 # Execution basic
 
+## gem5 bootcamp 2022 module on instruction execution
+
+gem5 bootcamp (2022) had a session on learning how instructions work in gem5 and how to add new instructions in gem5.
+The slides presented in the session can be found [here](https://ucdavis365-my.sharepoint.com/:p:/g/personal/jlowepower_ucdavis_edu/EeRIKzkdUJBDlaa9AmzERusBp28hxMfkyIOp-_2H5L9AqQ?e=RoMFUD).
+
+The youtube video of the recorded bootcamp module on gem5 instructions is available [here](https://youtu.be/Z5B02jkNpck).
 
 # StaticInsts #
 The StaticInst provides all static information and methods for a binary instruction.
@@ -121,3 +127,15 @@
 * The description above is intended to illustrate the typical usage of these index types. There may be exceptions that don't precisely   follow this description, but I got tired of writing "typically" in every sentence.
 * The terms 'relative' and 'unified' were invented for use in this documentation, so you are unlikely see them in the code until the code starts catching up with this page.
 * This discussion pertains only to the architectural registers. An out-of-order CPU model such as O3 adds another layer of complexity by renaming these architectural registers (using the flattened register indices) to an underlying physical register file.
+
+
+## ISA and CPU Independence ##
+
+gem5 tries to keep CPU models ISA independent to make it easier to use any ISA with different CPU models. gem5 relies on two generic interfaces to make this independence possible: static instructions and execution context (both are discussed above).
+Static instructions allow CPU to manage instructions and the execution context allow ISA or instructions to interact with the CPU. Following picture provides a high level overview of
+what components in gem5 are ISA dependent or independent:
+
+![ISA dependent or independent components of gem5](/assets/img/ISAInd.png)
+
+**Source of the above figure:** Modular ISA-Independent Full-System Simulation (Ch 5 of Processor and System-on-Chip Simulation), G. Black, N. Binkert, and S. Reinhardt, A. Saidi.
+[Link](https://link.springer.com/content/pdf/10.1007/978-1-4419-6175-4.pdf).
\ No newline at end of file
diff --git a/_pages/documentation/general_docs/cpu_models/index.md b/_pages/documentation/general_docs/cpu_models/index.md
index 720a39f..d4c5ddf 100644
--- a/_pages/documentation/general_docs/cpu_models/index.md
+++ b/_pages/documentation/general_docs/cpu_models/index.md
@@ -1,5 +1,14 @@
 ---
 layout: documentation
 title: "gem5's CPU models"
+doc: gem5 documentation
+parent: cpu_models
 permalink: /documentation/general_docs/cpu_models/
 ---
+
+## gem5 bootcamp 2022 module on using CPU models
+
+gem5 bootcamp (2022) had a session on learning the use of different gem5 CPU models.
+The slides presented in the session can be found [here](https://ucdavis365-my.sharepoint.com/:p:/g/personal/jlowepower_ucdavis_edu/EYRn68yb9nZJk9Puf7dV40YBm25hQ91WCXnEwyjqniqeVQ?e=7Xo0).
+
+The youtube video of the recorded bootcamp module on gem5 CPU models is available [here](https://youtu.be/cDv-g-c0XCY).
\ No newline at end of file
diff --git a/_pages/documentation/general_docs/developement/coding_style.md b/_pages/documentation/general_docs/developement/coding_style.md
index 56240d8..7b8978c 100644
--- a/_pages/documentation/general_docs/developement/coding_style.md
+++ b/_pages/documentation/general_docs/developement/coding_style.md
@@ -1,13 +1,13 @@
 ---
 layout: documentation
-title: "Coding Style"
+title: "C/C++ Coding Style"
 doc: gem5 documentation
 parent: development
 permalink: /documentation/general_docs/development/coding_style/
 ---
-# Coding Style
+# C/C++ Coding Style
 
-We strive to maintain a consistent coding style in the M5 source code to make the source more readable and maintainable. This necessarily involves compromise among the multiple developers who work on this code. We feel that we have been successful in finding such a compromise, as each of the primary M5 developers is annoyed by at least one of the rules below. We ask that you abide by these guidelines as well if you develop code that you would like to contribute back to M5. An Emacs c++-mode style embodying the indentation rules is available in the source tree at util/emacs/m5-c-style.el.
+We strive to maintain a consistent coding style in the gem5 C/C++ source code to make the source more readable and maintainable. This necessarily involves compromise among the multiple developers who work on this code. We feel that we have been successful in finding such a compromise, as each of the primary M5 developers is annoyed by at least one of the rules below. We ask that you abide by these guidelines as well if you develop code that you would like to contribute back to M5. An Emacs c++-mode style embodying the indentation rules is available in the source tree at util/emacs/m5-c-style.el.
 
 ## Indentation and Line Breaks
 
diff --git a/_pages/documentation/general_docs/fullsystem/disks.md b/_pages/documentation/general_docs/fullsystem/disks.md
index 253ad0f..49572c7 100644
--- a/_pages/documentation/general_docs/fullsystem/disks.md
+++ b/_pages/documentation/general_docs/fullsystem/disks.md
@@ -483,7 +483,8 @@
 WantedBy=default.target
 ```
 
-Enable the gem5 service and disable the ttyS0 service.
+Enable the gem5 service and **disable the ttyS0 service**.
+If your disk boots up to a login prompt, it might be caused by not disabling the ttyS0 service.
 
 ```
 systemctl enable gem5.service
diff --git a/_pages/documentation/general_docs/fullsystem/guest_binaries.md b/_pages/documentation/general_docs/fullsystem/guest_binaries.md
index 98b70d9..540fbbe 100644
--- a/_pages/documentation/general_docs/fullsystem/guest_binaries.md
+++ b/_pages/documentation/general_docs/fullsystem/guest_binaries.md
@@ -25,7 +25,7 @@
 
 The tarball below contains a set of binaries: the Linux kernel and a set of bootloaders
 
-* <http://dist.gem5.org/dist/v22-0/arm/aarch-system-20210904.tar.bz2>
+* <http://dist.gem5.org/dist/v22-0/arm/aarch-system-20220707.tar.bz2>
 
 ##### Latest Linux Disk Images (**recommended**)
 
diff --git a/_pages/documentation/general_docs/m5ops.md b/_pages/documentation/general_docs/m5ops.md
index 985a2ec..6aac998 100644
--- a/_pages/documentation/general_docs/m5ops.md
+++ b/_pages/documentation/general_docs/m5ops.md
@@ -9,6 +9,7 @@
 # M5ops
 
 This page explains the special opcodes that can be used in M5 to do checkpoints etc. The m5 utility program (on our disk image and in util/m5/*) provides some of this functionality on the command line. In many cases it is best to insert the operation directly in the source code of your application of interest. You should be able to link with the appropriate libm5.a file and the m5ops.h header file has prototypes for all the functions.
+A tutorial on using the M5ops was given as a part of the gem5 2022 Bootcamp. A recording of this event can be found [here](https://youtu.be/TeHKMVOWUAY).
 
 ## Building M5 and libm5
 
@@ -111,3 +112,71 @@
 CFLAGS += -I$(GEM5_PATH)/include
 LDFLAGS += -L$(GEM5_PATH)/util/m5/build/$(TARGET_ISA)/out -lm5
 ```
+
+Here is a simple Makefile example:
+
+```make
+TARGET_ISA=x86
+
+GEM5_HOME=$(realpath ./)
+$(info   GEM5_HOME is $(GEM5_HOME))
+
+CXX=g++
+
+CFLAGS=-I$(GEM5_HOME)/include
+
+LDFLAGS=-L$(GEM5_HOME)/util/m5/build/$(TARGET_ISA)/out -lm5
+
+OBJECTS= hello_world
+
+all: hello_world
+
+hello_world:
+	$(CXX) -o $(OBJECTS) hello_world.cpp $(CFLAGS) $(LDFLAGS)
+
+clean:
+	rm -f $(OBJECTS)
+```
+
+
+## Using the "_addr" version of M5ops
+
+The "_addr" version of m5ops triggers the same simulation specific functionality as the default m5ops, but they use different trigger mechanisms. Below is a quote from the m5 utility README.md explaining the trigger mechanisms.
+
+```markdown
+The bare function name as defined in the header file will use the magic instruction based trigger mechanism, what would have historically been the default.
+
+Some macros at the end of the header file will set up other declarations which mirror all of the other definitions, but with an “_addr” and “_semi” suffix. These other versions will trigger the same gem5 operations, but using the “magic” address or semihosting trigger mechanisms. While those functions will be unconditionally declared in the header file, a definition will exist in the library only if that trigger mechanism is supported for that ABI.
+```
+
+In order to use the "_addr" version of m5ops, you need to include th m5_mmap.h header file, pass the "magic" address (ex. "0xFFFF0000" for x86) to m5op_addr, then call the map_m5_mem() to open /dev/mem. You can insert m5ops by adding "_addr" at the end of the original m5ops functions.
+
+Here is a simple example using the "_addr" version of the m5ops:
+
+```c
+#include <gem5/m5ops.h>
+#include <m5_mmap.h>
+#include <stdio.h>
+
+#define GEM5
+
+int main(void) {
+#ifdef GEM5
+    m5op_addr = 0xFFFF0000;
+    map_m5_mem();
+    m5_work_begin_addr(0,0);
+#endif
+
+    print("hello world!");
+
+#ifdef GEM5
+    m5_work_end_addr(0,0);
+#endif
+}
+```
+
+When you run the applications with m5ops inserted in FS mode with a KVM CPU, this error might appear.
+
+    ```illegal instruction (core dumped)```
+
+This is because m5ops instructions are not valid instructions to the host. Using the "_addr" version of the m5ops can fix this issue, so it might be necessary to use the "_addr" version if you want to integrate m5ops into your applications or use the m5 binary utility when running with KVM CPUs.
diff --git a/_pages/documentation/general_docs/ruby/heterogarnet.md b/_pages/documentation/general_docs/ruby/heterogarnet.md
new file mode 100644
index 0000000..f32e4d8
--- /dev/null
+++ b/_pages/documentation/general_docs/ruby/heterogarnet.md
@@ -0,0 +1,143 @@
+---
+layout: documentation
+title: "HeteroGarnet (Garnet 3.0)"
+doc: gem5 documentation
+parent: ruby
+permalink: /documentation/general_docs/ruby/heterogarnet/
+author: Srikant Bharadwaj
+---
+
+**More details of the gem5 Ruby Interconnection Network are [here](/documentation/general_docs/ruby/interconnection-network "wikilink").**
+**Details about the earlier Garnet version can be found [here](/documentation/general_docs/ruby/garnet-2 "wikilink").**
+
+### HeteroGarnet: A Detailed Simulator for Diverse Interconnect Systems
+[HeteroGarnet](https://doi.org/10.1109/DAC18072.2020.9218539) improves upon the widely-popular Garnet 2.0 network model by enabling accurate simulation of emerging interconnect systems. Specifically, HeteroGarnet adds support for clock-domain islands, network crossings supporting multiple frequency domains, and network interface controllers capable of attaching to multiple physical links. It also supports variable bandwidth links and routers by introducing a new configurable Serializer-Deserializer component. HeteroGarnet is integrated into the gem5 repository as Garnet 3.0.
+
+HeteroGarnet builds upon the original Garnet model which was published in
+[2009](https://doi.org/10.1109/ISPASS.2009.4919636).
+
+If your use of HeteroGarnet contributes to a published paper, please cite the
+following paper:
+
+```
+    @inproceedings{heterogarnet,
+        author={Bharadwaj, Srikant and Yin, Jieming and Beckmann, Bradford and Krishna, Tushar},
+        booktitle={2020 57th ACM/IEEE Design Automation Conference (DAC)},
+        title={Kite: A Family of Heterogeneous Interposer Topologies Enabled via Accurate Interconnect Modeling},
+        year={2020},
+        volume={},
+        number={},
+        pages={1-6},
+        doi={10.1109/DAC18072.2020.9218539}
+	}
+```
+
+
+
+## Topology Construction
+HeteroGarnet allows users to configure complex topologies using a python configuration file as the topology.
+The overall topology configuration could include the complete interconnect definition of the system including
+any heterogeneous components. The general flow of defining a topology involves the following steps:
+
+1. Determine the total number of routers in the system and instantiate them.
+    1. Use the **Router** class to instantiate individual routers.
+    2. Configure properties of each router, such as clock domain, supported flit width, depending on the requirements.
+```
+routers = Router(id, latency, clock_domain,
+                flit_width, supported_vnets,
+                vcs_per_vnet)
+```
+
+2. Connect the routers which connect to the end points (e.g, Cores, Caches, Directories) using external physical interconnects.
+    1. Use **ExternalLink** class to instantiate the links connecting the end points.
+    2. Configure properties of each external link, such as clock domain, link width, depending on the requirements.
+    3. Enable clock-domain crossings(CDC) and Serializer-Deserializer(SerDes) units at either depending on the interconnect topology.
+```
+external_link = ExternalLink(id, latency, clock_domain,
+                             flit_width, supported_vnets,
+                             serdes_enable, cdc_enable)
+````
+
+3. Connect the individual routers within the network depending upon the topology.
+    1. Use **InternalLink** class to instantiate the links connecting the end points.
+    2. Configure properties of each internal link, such as clock domain, link width, depending on the requirements.
+    3. Enable clock-domain crossings and Serializer-Deserializer units at either depending on the interconnect topology.
+```
+internal_link = InternalLink(id, latency, clock_domain,
+                             flit_width, supported_vnets,
+                             serdes_enable, cdc_enable)
+```
+
+Garnet 3.0 also provides several pre-configuration scripts(./configs/Network/Network.py) which automatically do some of the other steps, such as instantiating network interfaces, domain crossings, and SerDes units. The several types of units used to configure the topologies are discussed below.
+
+
+## Physical Links
+The physical link model in Garnet represents the interconnect wire itself. A link is a single entity which has its own latency, width and the types of flit it can transmit. The links also support a credit based back-pressuring mechanism. Similar to the upgraded Garnet 3.0 router, each Garnet 3.0 link can be configured to an operating frequency and width using appropriate parameters. This allows links and routers operating at different frequencies to be connected to each other.
+
+## Network Interface
+The network interface controller (NIC) is an object which sits between the network end points (e.g., Caches, DMA nodes) and the interconnection system. The NIC receives messages form the controllers and converts them into fixed-length flits, short for flow control units. These flits are sized appropriately according to the outgoing physical links. The network interface also governs the flow control and buffer management for the outgoing and incoming flits. Garnet 3.0 allows multiple ports to be attached to a single end points. Thus, the NIC decides where a certain message/flit must be scheduled.
+
+## Clock Domain Crossing Units
+To support multiple clock domains, Garnet 3.0 introduces Clock Domain Crossing (CDC) unit, as shown in the Figure below (left), which consists of first-In-First-Out (FIFO) buffers and can be instantiated anywhere within the network model. The CDC unit enables architectures with different clock domains across the system. The delay of each CDC unit configurable. The latency can also be calculated dynamically depending on the clock domains connected to it. This enables accurate modeling of DVFS techniques as CDC latencies are generally a function of the operating frequency of producer and consumer.
+
+## Serializer-Deserializer Units
+Another critical feature necessary in modeling SoCs and heterogeneous architectures is supporting various interconnect widths across the system. Consider a link between two routers within a GPU and a link between a memory controller and on-chip memory. These two links might be of different widths. To enable such configuration, Garnet 3.0 introduces the Serializer-Deserializer unit as shown in the figure below, which converts flits into appropriate widths at bit-width boundaries. These SerDes units can be instantiated anywhere in the Garnet 3.0 topology similar to the CDC unit described in the previous sub-section.
+
+![SerDes_CDC.png](/assets/img/SerDes_CDC.png)
+
+## Routing
+The routing algorithm decides how the flits travel through the topology. The objective of a routing policy is to minimize contention while maximizing the bandwidth offered by the interconnect. Garnet 3.0 provides several standard routing policies that the user can select from.
+
+### Routing Policies.
+There are several generic routing  policies that have been proposed for deadlock free routing of flits through the interconnect network.
+
+### Table based routing
+Garnet also features table based routing policy which users can select to set custom routing policies using a weight-age based system. Lower weighted links are preferred over links which are configured to have higher weights.
+
+
+
+## Flow Control and Buffer Management
+
+Flow control mechanisms determine the buffer allocation in interconnect systems. The aim of a good flow control system is minimize the impact of buffer allocation to the overall latency of a message in the system. Implementation of these mechanisms often involve micro-management of physical packets within the interconnect system.
+
+Coherence messages generated by cache controllers are often broken down into fixed-length flits (flow control units). A set of flits carrying a message is often termed as a packet. A packet could have a head-flit, body-flit, and a tail-flit to carry the contents of the message along with any additional meta data of the packet itself. Several flow control techniques have been proposed and implemented at various granularities of resource allocation.
+
+Garnet 3.0 implements a credit-based flit-level flow control mechanism with support for virtual channels.
+
+### Virtual Channels
+Virtual Channels (VCs) in a network act as separate queues which can share physical wires (physical links) between two routers or arbiters. Virtual channels are mainly used to alleviate head-of-line blocking. However, they are also used as a means for deadlock-avoidance.
+
+### Buffer Backpressure
+Most implementations of interconnection networks do not tolerate dropping of packets or flits during traversal. Thus, there is a need to strictly manage the flits using backpressuring mechanisms. 
+
+### Credit-based backpressuring
+Credit-based backpressuring mechanism is often used for low-latency implementation of flit-stalling. Credits track the number of buffers available at the next intermediate destination by decrementing the overall buffers every time a flit is sent. A credit is then sent back by the destination when it is vacated.
+
+Routers in interconnect systems perform arbitration, allocation of buffers, and flow control within the network. The objective of the router microarchitecture is to minimize the contention within the router while offering minimal per-hop latency for the flits. The complexity of the router microarchitecture also affects the overall energy and area consumption of the interconnect system.
+
+
+## Life of a Message in Garnet 3.0
+In this section we describe the life of a message in the NoC after it is generated by a cache controller unit. We take the case of Garnet 3.0 for describing the process, but the general modeling principles can be extended to other software simulation/modeling tools as well.
+
+![HeteroGarnet_Life.png](/assets/img/HeteroGarnet_Life.png)
+
+The overall flow of the system is shown in detail in figure above. It shows a simple example scenario where a message is generated by a cache controller destined for another cache controller which is connected through routers via physical links, serializer-deserializer units, and clock-domain crossings.
+
+### Injection of Message
+The source cache controller creates a message and assigns one or more  cache controllers as the destination. This message is then injected into message queues. A cache controller often has several outgoing and incoming message buffers for different kinds of messages.
+
+### Conversion to Flits.
+A network interface controller unit (NIC) is attached to each cache controller. This NIC wakes up and consumes the messages from the message queues. Each message is then converted to unicast messages before being broken down into fixed-length flits according to the size supported by the outgoing physical links. These flits are then scheduled for transmission depending on the availability of buffers at the next hop through one of the output links. The outgoing link is chosen depending on the destination, routing policy, and the type of message.
+
+### Transmission to Local Router.
+Each network interface is connected to one or more "local" routers which is could be connected through an "External" link. Once a flit is scheduled, it is transmitted over these external links which deliver the flit to the router after a period of defined latency.
+
+### Router Arbitration.
+The flit wakes up the router which is a multi-stage unit. The router houses the input buffers, VC allocation, switch arbitration, and crossbar units. On arrival the flit is first placed in a input buffer queue. There are several input buffer queues in a router which contend for an output link and a VC for the next hop. This is done using the VC allocation and switch arbitration stages. Once a flit is selected for transmission, the crossbar stage directs the flit to the output link. A credit is then sent back to the NIC as the input buffer space is vacated for the next flit to arrive.
+
+### Serialization-Deserialization.
+The serialization-deserialization (SerDes) is an optional unit that can be enabled depending on the design requirements. The SerDes units consumes the flits and appropriately converts it into outgoing flit size. In addition to manipulating the data packets, the SerDes also handles the credit system, by serializing or deserializing the credit units.
+
+
+## Area, Power and Energy Model
+Frameworks like Orion2.0 and DSENT provide models for the area and power for the various building blocks of a NoC router and links. HeteroGarnet integrates DSENT as an external tool to report area, power and energy (which depends on activity) at the end of the simulation.
diff --git a/_pages/documentation/learning_gem5/gem5_101/3_gem5_101_homework3.md b/_pages/documentation/learning_gem5/gem5_101/3_gem5_101_homework3.md
index 50b9bef..594b987 100644
--- a/_pages/documentation/learning_gem5/gem5_101/3_gem5_101_homework3.md
+++ b/_pages/documentation/learning_gem5/gem5_101/3_gem5_101_homework3.md
@@ -59,9 +59,9 @@
 
 Usually while carrying out experiments for evaluating a design, one would like to look only at statistics for the portion of the code that is most important.  To do so, typically programs are annotated so that the simulator, on reaching an annotated portion of the code, carries out functions like create a checkpoint, output and reset statistical variables.
 
-You will edit the C++ code from the first part to output and reset stats just before the start of the DAXPY loop and just after it.  For this, include the file `util/m5/m5op.h` in the program.  You will find this file in `util/m5` directory of the gem5 repository.  Use the function `m5_dumpreset_stats()` from this file in your program. This function outputs the statistical variables and then resets them. You can provide 0 as the value for the delay and the period arguments.
+You will edit the C++ code from the first part to output and reset stats just before the start of the DAXPY loop and just after it.  For this, include the file `util/m5/m5op.h` in the program.  You will find this file in `util/m5` directory of the gem5 repository.  Use the function `m5_dump_reset_stats()` from this file in your program. This function outputs the statistical variables and then resets them. You can provide 0 as the value for the delay and the period arguments.
 
-To provide the definition of the `m5_dumpreset_stats()`, go to the directory `util/m5` and edit the Makefile.x86 in the following way:
+To provide the definition of the `m5_dump_reset_stats()`, go to the directory `util/m5` and edit the Makefile.x86 in the following way:
 
 ```
   diff --git a/util/m5/Makefile.x86 b/util/m5/Makefile.x86
@@ -78,7 +78,7 @@
    all: m5
 ```
 
-Execute the command `make -f Makefile.x86` in the directory `util/m5`.  This will create an object file named `m5op_x86.o`.  Link this file with the program for DAXPY.  Now again simulate the program with the timing simple CPU.  This time you should see three sets of statistics in the file stats.txt.  Report the breakup of instructions among different op classes for the three parts of the program.  Provide the fragment of the generated assembly code that starts with call to `m5_dumpreset_stats()` and ends `m5_dumpreset_stats()`, and has the main daxpy loop in between.
+Execute the command `make -f Makefile.x86` in the directory `util/m5`.  This will create an object file named `m5op_x86.o`.  Link this file with the program for DAXPY.  Now again simulate the program with the timing simple CPU.  This time you should see three sets of statistics in the file stats.txt.  Report the breakup of instructions among different op classes for the three parts of the program.  Provide the fragment of the generated assembly code that starts with call to `m5_dump_reset_stats()` and ends `m5_dump_reset_stats()`, and has the main daxpy loop in between.
 
 
 3. There are several different types of CPUs that gem5 supports: atomic, timing, out-of-order, inorder and kvm.  Let's talk about the timing and the inorder cpus.  The timing CPU (also known as SimpleTimingCPU) executes each arithmetic instruction in a single cycle, but requires multiple cycles for memory accesses.  Also, it is not pipelined.  So only a single instruction is being worked upon at any time.  The inorder cpu (also known as Minor) executes instructions in a pipelined fashion.  As I understand it has the following pipe stages: fetch1, fetch2, decode and execute.
@@ -99,7 +99,7 @@
 1. The email should contain the name and ID numbers of the student submitting
 the assignment. The files below should be attached as a zip file to the email.
 
-2. A file named daxpy.cpp which is used for testing.  This file should also include the pseudo-instructions (`m5_dumpreset_stats()`) as asked in part 2.  Also provide a file daxpy.s with the fragment of the generated assembly code as asked for in part 2.
+2. A file named daxpy.cpp which is used for testing.  This file should also include the pseudo-instructions (`m5_dump_reset_stats()`) as asked in part 2.  Also provide a file daxpy.s with the fragment of the generated assembly code as asked for in part 2.
 
 3. stats.txt and config.ini files for all the simulations.
 
diff --git a/_pages/documentation/learning_gem5/part1/part1_2_simple_config.md b/_pages/documentation/learning_gem5/part1/part1_2_simple_config.md
index e1b2f39..4cee564 100644
--- a/_pages/documentation/learning_gem5/part1/part1_2_simple_config.md
+++ b/_pages/documentation/learning_gem5/part1/part1_2_simple_config.md
@@ -66,8 +66,8 @@
 Let's start by creating a new config file and opening it:
 
 ```
-mkdir configs/tutorial
-touch configs/tutorial/simple.py
+mkdir configs/tutorial/part1/
+touch configs/tutorial/part1/simple.py
 ```
 
 This is just a normal python file that will be executed by the embedded
diff --git a/_pages/documentation/learning_gem5/part1/part1_6_extending_configs.md b/_pages/documentation/learning_gem5/part1/part1_6_extending_configs.md
index 59f8ce4..a37a533 100644
--- a/_pages/documentation/learning_gem5/part1/part1_6_extending_configs.md
+++ b/_pages/documentation/learning_gem5/part1/part1_6_extending_configs.md
@@ -36,7 +36,7 @@
 default ARM configurations. To do so, we just replace x86 with ARM:  
 
 ```
-scons build/ARM/gem5.opt -j20
+scons build/ARM/gem5.opt -j 20
 ```
 
 When compilation is finished you should have a working gem5 executable
diff --git a/_pages/documentation/learning_gem5/part2/part2_2_debugging.md b/_pages/documentation/learning_gem5/part2/part2_2_debugging.md
index ccc5d48..340e758 100644
--- a/_pages/documentation/learning_gem5/part2/part2_2_debugging.md
+++ b/_pages/documentation/learning_gem5/part2/part2_2_debugging.md
@@ -230,16 +230,16 @@
 ```
 
 `DPRINTF` is a C++ macro. The first parameter is a *debug flag* that has
-been declared in a SConscript file. We can use the flag `Hello` since we
+been declared in a SConscript file. We can use the flag `HelloExample` since we
 declared it in the `src/learning_gem5/SConscript` file. The rest of the
 arguments are variable and can be anything you would pass to a `printf`
 statement.
 
-Now, if you recompile gem5 and run it with the "Hello" debug flag, you
+Now, if you recompile gem5 and run it with the "HelloExample" debug flag, you
 get the following result.
 
 ```
-    build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py
+    build/X86/gem5.opt --debug-flags=HelloExample configs/learning_gem5/part2/run_hello.py
 ```
 
     gem5 Simulator System.  http://gem5.org
@@ -248,7 +248,7 @@
     gem5 compiled Jan  4 2017 09:40:10
     gem5 started Jan  4 2017 09:41:01
     gem5 executing on chinook, pid 29078
-    command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py
+    command line: build/X86/gem5.opt --debug-flags=HelloExample configs/learning_gem5/part2/run_hello.py
 
     Global frequency set at 1000000000000 ticks per second
           0: hello: Created the hello object
diff --git a/_pages/documentation/learning_gem5/part2/part2_5_memoryobject.md b/_pages/documentation/learning_gem5/part2/part2_5_memoryobject.md
index 0eb4174..22962e6 100644
--- a/_pages/documentation/learning_gem5/part2/part2_5_memoryobject.md
+++ b/_pages/documentation/learning_gem5/part2/part2_5_memoryobject.md
@@ -112,7 +112,7 @@
 
 In the figure above, first, the master sends a timing request by
 calling `sendTimingReq`, which in turn calls `recvTimingResp`. The
-slave, returns true from `recvTimingResp`, which is returned from the
+slave, returns true from `recvTimingReq`, which is returned from the
 call to `sendTimingReq`. The master continue executing, and the slave
 does whatever is necessary to complete the request (e.g., if it is a
 cache, it looks up the tags to see if there is a match to the address in
diff --git a/_pages/documentation/learning_gem5/part3/part3_00_MSIntro.md b/_pages/documentation/learning_gem5/part3/part3_00_MSIntro.md
index cd1f04b..a446073 100644
--- a/_pages/documentation/learning_gem5/part3/part3_00_MSIntro.md
+++ b/_pages/documentation/learning_gem5/part3/part3_00_MSIntro.md
@@ -8,13 +8,10 @@
 ---
 
 
-Introduction to Ruby
-====================
+## Introduction to Ruby
 
-Ruby comes from the [multifacet GEMS
-project](http://research.cs.wisc.edu/gems/). Ruby provides a detailed
-cache memory and cache coherence models as well as a detailed network
-model (Garnet).
+Ruby comes from the [multifacet GEMS project](http://research.cs.wisc.edu/gems/).
+Ruby provides a detailed cache memory and cache coherence models as well as a detailed network model (Garnet).
 
 Ruby is flexible. It can model many different kinds of coherence
 implementations, including broadcast, directory, token, region-based
diff --git a/_pages/documentation/learning_gem5/part3/part3_01_cache-intro.md b/_pages/documentation/learning_gem5/part3/part3_01_cache-intro.md
index f94f6c1..4fc4510 100644
--- a/_pages/documentation/learning_gem5/part3/part3_01_cache-intro.md
+++ b/_pages/documentation/learning_gem5/part3/part3_01_cache-intro.md
@@ -8,8 +8,7 @@
 ---
 
 
-MSI example cache protocol
-==========================
+## MSI example cache protocol
 
 Before we implement a cache coherence protocol, it is important to have
 a solid understanding of cache coherence. This section leans heavily on
@@ -25,7 +24,7 @@
 Details for the protocol can be found in Section 8.2 of *A Primer on Memory Consistency and Cache Coherence* (pages 141-149).
 It will be helpful to print out Section 8.2 to reference as you are implementing the protocol.
 
-You can download an exceprt of Sorin et al. that contains Section 8.2 [here](/_pages/static/external/Sorin_et-al_Excerpt_8.2.pdf).
+You can download the Second Edition [via this link](https://link.springer.com/content/pdf/10.1007/978-3-031-01764-3.pdf).
 
 ## First steps to writing a protocol
 
@@ -41,11 +40,9 @@
 ```python
 Import('*')
 
-all_protocols.extend([
-'MSI',
-])
+main.Append(ALL_PROTOCOLS=['MSI'])
 
-protocol_dirs.append(str(Dir('.').abspath))
+main.Append(PROTOCOL_DIRS=[Dir('.')])
 ```
 
 We do two things in this file. First, we register the name of our
@@ -57,10 +54,9 @@
 the SLICC compiler.
 
 You can download the `SConsopts` file
-[here](/_pages/static/scripts/part3/MSI\_protocol/SConsopts\).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/SConsopts).
 
-Writing a state machine file
-----------------------------
+### Writing a state machine file
 
 The next step, and most of the effort in writing a protocol, is to
 create the state machine files. State machine files generally follow the
@@ -85,3 +81,5 @@
 Transitions
 :   Specify actions to execute given a starting state and an event and
     the final state. This is the meat of the state machine definition.
+
+Over the next few sections we will go over how to write each of these components of the protocol.
diff --git a/_pages/documentation/learning_gem5/part3/part3_02_cache-declarations.md b/_pages/documentation/learning_gem5/part3/part3_02_cache-declarations.md
index 986a790..8509fe2 100644
--- a/_pages/documentation/learning_gem5/part3/part3_02_cache-declarations.md
+++ b/_pages/documentation/learning_gem5/part3/part3_02_cache-declarations.md
@@ -8,9 +8,6 @@
 ---
 
 
-Declaring a state machine
-=========================
-
 Let's start on our first state machine file! First, we will create the
 L1 cache controller for our MSI protocol.
 
@@ -50,8 +47,7 @@
 from the author of the protocol. It is important to be clear with these
 descriptions since coherence protocols can get quite complicated.
 
-State machine parameters
-------------------------
+## State machine parameters
 
 Proceeding the `machine()` declaration is a colon, after which all of
 the parameters to the state machine are declared. These parameters are
@@ -181,8 +177,7 @@
     mandatoryQueue = Param.MessageBuffer("")
 ```
 
-State declarations
-------------------
+## State declarations
 
 The next part of the state machine is the state declaration. Here, we
 are going to declare all of the stable and transient states for the
@@ -240,8 +235,7 @@
 functional writes, all blocks are updated with new data if they have
 busy, read-only, or read-write permission.
 
-Event declarations
-------------------
+## Event declarations
 
 Next, we need to declare all of the events that are triggered by
 incoming messages for this cache controller. These events come directly
@@ -275,8 +269,7 @@
 }
 ```
 
-User-defined structures
------------------------
+## User-defined structures
 
 Next, we need to define some structures that we will use in other places
 in this controller. The first one we will define is `Entry`. This is the
@@ -334,8 +327,7 @@
 The `external="yes"` tells SLICC to not look for the definition of this
 structure. This is similar to declaring a variable `extern` in C/C++.
 
-Other declarations and definitions required
--------------------------------------------
+## Other declarations and definitions required
 
 Finally, we are going to go through some boilerplate of declaring
 variables, declaring functions in `AbstractController` that we will use
diff --git a/_pages/documentation/learning_gem5/part3/part3_03_cache-in-ports.md b/_pages/documentation/learning_gem5/part3/part3_03_cache-in-ports.md
index 5f5d1e3..5c54e87 100644
--- a/_pages/documentation/learning_gem5/part3/part3_03_cache-in-ports.md
+++ b/_pages/documentation/learning_gem5/part3/part3_03_cache-in-ports.md
@@ -8,9 +8,6 @@
 ---
 
 
-In port code blocks
-===================
-
 After declaring all of the structures we need in the state machine file,
 the first "functional" part of the file are the "in ports". This section
 specifies what *events* to *trigger* on different incoming messages.
@@ -228,7 +225,7 @@
 is specified as a `NetDest`, which is a bitmap of all the `MachineID` in
 the system. This allows messages to be broadcast to a flexible set of
 receivers. The message also has a size. You can find the possible
-message sizes in `src/mem/protocol/RubySlicc_Exports.sm`.
+message sizes in `src/mem/ruby/protocol/RubySlicc_Exports.sm`.
 
 This message may also contain a data block and the number acks that are
 expected. Thus, we can include these in the message definition as well.
@@ -240,7 +237,7 @@
 written the functional access may fail.
 
 You can download the complete `MSI-msg.sm` file 
-[here](/_pages/static/scripts/part3/MSI_protocol/MSI-msg.sm).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-msg.sm).
 
 Now that we have defined the data in the response message, we can look
 at how we choose which action to trigger in the `in_port` for response
diff --git a/_pages/documentation/learning_gem5/part3/part3_04_cache_actions.md b/_pages/documentation/learning_gem5/part3/part3_04_cache_actions.md
index e782a77..4e7c04d 100644
--- a/_pages/documentation/learning_gem5/part3/part3_04_cache_actions.md
+++ b/_pages/documentation/learning_gem5/part3/part3_04_cache_actions.md
@@ -7,9 +7,7 @@
 author: Jason Lowe-Power
 ---
 
-
-Action code blocks
-==================
+## Action code blocks
 
 The next section of the state machine file is the action blocks. The
 action blocks are executed during a transition from one state to
diff --git a/_pages/documentation/learning_gem5/part3/part3_05_cache_transitions.md b/_pages/documentation/learning_gem5/part3/part3_05_cache_transitions.md
index 9cc1e9c..a0d7ac0 100644
--- a/_pages/documentation/learning_gem5/part3/part3_05_cache_transitions.md
+++ b/_pages/documentation/learning_gem5/part3/part3_05_cache_transitions.md
@@ -8,8 +8,7 @@
 ---
 
 
-Transition code blocks
-======================
+## Transition code blocks
 
 Finally, we've reached the final section of the state machine file! This
 section contains the details for all of the transitions between states
@@ -201,4 +200,4 @@
 ```
 
 You can download the complete `MSI-cache.sm` file
-[here](/_pages/static/scripts/part3/MSI_protocol/MSI-cache.sm).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-cache.sm).
diff --git a/_pages/documentation/learning_gem5/part3/part3_06_directory.md b/_pages/documentation/learning_gem5/part3/part3_06_directory.md
index 4a3d70b..ff427d1 100644
--- a/_pages/documentation/learning_gem5/part3/part3_06_directory.md
+++ b/_pages/documentation/learning_gem5/part3/part3_06_directory.md
@@ -8,9 +8,6 @@
 ---
 
 
-MSI Directory implementation
-============================
-
 Implementing a directory controller is very similar to the L1 cache
 controller, except using a different state machine table. The state
 machine fore the directory can be found in Table 8.2 in Sorin et al.
@@ -36,6 +33,8 @@
 MessageBuffer *responseFromCache, network="From", virtual_network="2",
       vnet_type="response";
 
+MessageBuffer *requestToMemory;
+
 MessageBuffer *responseFromMemory;
 
 {
@@ -65,11 +64,10 @@
 the L1 cache. These virtual network numbers are how the Ruby network
 directs messages between controllers.
 
-There is also one more special message buffer: `responseFromMemory`.
+There is also two more special message buffers: `requestToMemory` and `responseFromMemory`.
 This is similar to the `mandatoryQueue`, except instead of being like a
-slave port for CPUs it is like a master port. The `responseFromMemory`
-buffer will deliver response sent across the the memory port, as we will
-see below in the action section.
+responder port for CPUs it is like a requestor port. The `responseFromMemory` and `requestToMemory`
+buffers will deliver responses sent across the the memory port and send requests across the memory port, as we will see below in the action section.
 
 After the parameters and message buffers, we need to declare all of the
 states, events, and other local structures.
@@ -115,7 +113,7 @@
     MemAck,       desc="Ack from memory that write is complete";
 }
 
-structure(Entry, desc="...", interface="AbstractEntry") {
+structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
     State DirState,         desc="Directory state";
     NetDest Sharers,        desc="Sharers for this block";
     NetDest Owner,          desc="Owner of this block";
@@ -136,7 +134,10 @@
 the sharers and the owner. This makes sense for the sharers, since we
 want a full bitvector for all L1 caches that may be sharing the block.
 The reason we also use a `NetDest` for the owner is to simply copy the
-structure into the message we send as a response as shown below.
+structure into the message we send as a response as shown below.D
+Note that we add one extra parameter to the `Entry` declaration: `main="false"`.
+This extra parameter tells the replacement policy that this `Entry` is special and should be ignored.
+In the `DirectoryMemory` we are tracking *all* of the backing memory locations, so there is no need for a replacement policy.
 
 In this implementation, we use a few more transient states than in Table
 8.2 in Sorin et al. to deal with the fact that the memory latency in
@@ -283,12 +284,11 @@
 }
 ```
 
-The next part of the state machine file is the actions. First, we define
-actions for queuing memory reads and writes. For this, we will use a
-special function define in the `AbstractController`: `queueMemoryRead`.
-This function takes an address and converts it to a gem5 request and
-packet and sends it to across the port that is connected to this
-controller. We will see how to connect this port in the
+The next part of the state machine file is the actions.
+First, we define actions for sending memory reads and writes.
+For this, we will use the special `memQueue_out` port that we defined above.
+If we `enqueue` messages on this port, they will be translated into "normal" gem5 `PacketPtr`s and sent across the memory port defined in the configuration.
+We will see how to connect this port in the
 configuration section \<MSI-config-section\>. Note that we need two
 different actions to send data to memory for both requests and responses
 since there are two different message buffers (virtual networks) that
@@ -297,7 +297,13 @@
 ```cpp
 action(sendMemRead, "r", desc="Send a memory read request") {
     peek(request_in, RequestMsg) {
-        queueMemoryRead(in_msg.Requestor, address, toMemLatency);
+        enqueue(memQueue_out, MemoryMsg, toMemLatency) {
+            out_msg.addr := address;
+            out_msg.Type := MemoryRequestType:MEMORY_READ;
+            out_msg.Sender := in_msg.Requestor;
+            out_msg.MessageSize := MessageSizeType:Request_Control;
+            out_msg.Len := 0;
+        }
     }
 }
 
@@ -305,8 +311,14 @@
     peek(request_in, RequestMsg) {
         DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
         DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
-        queueMemoryWrite(in_msg.Requestor, address, toMemLatency,
-                         in_msg.DataBlk);
+        enqueue(memQueue_out, MemoryMsg, toMemLatency) {
+            out_msg.addr := address;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := in_msg.Requestor;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := in_msg.DataBlk;
+            out_msg.Len := 0;
+        }
     }
 }
 
@@ -314,9 +326,14 @@
     peek(response_in, ResponseMsg) {
         DPRINTF(RubySlicc, "Writing memory for %#x\n", address);
         DPRINTF(RubySlicc, "Writing %s\n", in_msg.DataBlk);
-        queueMemoryWrite(in_msg.Sender, address, toMemLatency,
-                         in_msg.DataBlk);
-    }
+        enqueue(memQueue_out, MemoryMsg, toMemLatency) {
+            out_msg.addr := address;
+            out_msg.Type := MemoryRequestType:MEMORY_WB;
+            out_msg.Sender := in_msg.Sender;
+            out_msg.MessageSize := MessageSizeType:Writeback_Data;
+            out_msg.DataBlk := in_msg.DataBlk;
+            out_msg.Len := 0;
+        }
 }
 ```
 
@@ -574,4 +591,4 @@
 ```
 
 You can download the complete `MSI-dir.sm` file
-[here](/_pages/static/scripts/part3/MSI_protocol/MSI-dir.sm).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-dir.sm).
diff --git a/_pages/documentation/learning_gem5/part3/part3_07_MSIbuilding.md b/_pages/documentation/learning_gem5/part3/part3_07_MSIbuilding.md
index b4bf80e..7ba83eb 100644
--- a/_pages/documentation/learning_gem5/part3/part3_07_MSIbuilding.md
+++ b/_pages/documentation/learning_gem5/part3/part3_07_MSIbuilding.md
@@ -8,18 +8,16 @@
 ---
 
 
-Compiling a SLICC protocol
-==========================
+## Building the MSI protocol
 
-The SLICC file
---------------
+### The SLICC file
 
 Now that we have finished implementing the protocol, we need to compile
 it. You can download the complete SLICC files below:
 
--   [MSI-cache.sm](/_pages/static/scripts/part3/MSI\_protocol/MSI-cache.sm)
--   [MSI-dir.sm](/_pages/static/scripts/part3/MSI\_protocol/MSI-dir.sm)
--   [MSI-msg.sm](/_pages/static/scripts/part3/MSI\_protocol/MSI-msg.sm)
+- [MSI-cache.sm](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-cache.sm)
+- [MSI-dir.sm](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-dir.sm)
+- [MSI-msg.sm](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/MSI-msg.sm)
 
 Before building the protocol, we need to create one more file:
 `MSI.slicc`. This file tells the SLICC compiler which state machine
@@ -44,10 +42,9 @@
 ```
 
 You can download the fill file
-[here](/_pages/static/scripts/part3/MSI_protocol/MSI.slicc).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/src/learning_gem5/part3/s/MSI.slicc).
 
-Compiling a protocol with SCons
--------------------------------
+### Compiling a protocol with SCons
 
 Most SCons defaults (found in `build_opts/`) specify the protocol as
 `MI_example`, an example, but poor performing protocol. Therefore, we
@@ -55,7 +52,7 @@
 to specify the SCons options on the command line. The command line below
 will build our new protocol with the X86 ISA.
 
-```
+```sh
 scons build/X86_MSI/gem5.opt --default=X86 PROTOCOL=MSI SLICC_HTML=True
 ```
 
diff --git a/_pages/documentation/learning_gem5/part3/part3_08_configuration.md b/_pages/documentation/learning_gem5/part3/part3_08_configuration.md
index 059d318..c6bed44 100644
--- a/_pages/documentation/learning_gem5/part3/part3_08_configuration.md
+++ b/_pages/documentation/learning_gem5/part3/part3_08_configuration.md
@@ -8,8 +8,7 @@
 ---
 
 
-Configuring a simple Ruby system
-================================
+## A configuration script for the MSI protocol
 
 First, create a new configuration directory in `configs/`. Just like all
 gem5 configuration files, we will have a configuration run script. For
@@ -43,10 +42,9 @@
 system and the memory controllers.
 
 You can download the complete run script
-[here](_pages/static/scripts/part3/configs/simple_ruby.py).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/configs/learning_gem5/part3/simple_ruby.py).
 
-Cache system configuration
---------------------------
+### Cache system configuration
 
 Now, let's create a file `msi_caches.py`. In this file, we will create
 four classes: `MyCacheSystem` which will inherit from `RubySystem`,
@@ -54,7 +52,7 @@
 by SLICC from our two state machines, and `MyNetwork` which will inherit
 from `SimpleNetwork`.
 
-### L1 Cache
+#### L1 Cache
 
 Let's start with the `L1Cache`. First, we will inherit from
 `L1Cache_Controller` since we named our L1 cache "L1Cache" in the state
@@ -147,7 +145,7 @@
     self.responseFromDirOrSibling.slave = ruby_system.network.master
 ```
 
-### Directory
+#### Directory
 
 Now, we can similarly implement the directory. There are three
 differences from the L1 cache. First, we need to set the address ranges
@@ -199,7 +197,7 @@
         self.responseFromMemory = MessageBuffer()
 ```
 
-### Ruby System
+#### Ruby System
 
 Now, we can implement the Ruby system object. For this object, the
 constructor is simple. It just checks the SCons variable `PROTOCOL` to
@@ -294,7 +292,7 @@
             cpu.dtb.walker.port = self.sequencers[i].slave
 ```
 
-### Network
+#### Network
 
 Finally, the last object we have to implement is the network. The
 constructor is simple, but we need to declare an empty list for the list
@@ -339,4 +337,4 @@
 ```
 
 You can download the complete `msi_caches.py` file
-[here](/_pages/static/scripts/part3/configs/msi_caches.py).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/configs/learning_gem5/part3/msi_caches.py).
diff --git a/_pages/documentation/learning_gem5/part3/part3_09_running.md b/_pages/documentation/learning_gem5/part3/part3_09_running.md
index 50f89f1..6e9ae53 100644
--- a/_pages/documentation/learning_gem5/part3/part3_09_running.md
+++ b/_pages/documentation/learning_gem5/part3/part3_09_running.md
@@ -8,8 +8,7 @@
 ---
 
 
-Running the simple Ruby system
-==============================
+## Running the simple Ruby system
 
 Now, we can run our system with the MSI protocol!
 
@@ -112,7 +111,7 @@
 
 With the above code compiled as `threads`, we can run gem5!
 
-```
+```sh
 build/MSI/gem5.opt configs/learning_gem5/part6/simple_ruby.py
 ```
 
@@ -120,6 +119,7 @@
 are unimplemented syscalls in SE mode due to using pthreads and can be
 safely ignored for this simple example.
 
+```termout
     gem5 Simulator System.  http://gem5.org
     gem5 is copyrighted software; use the --copyright option for details.
 
@@ -168,3 +168,4 @@
     warn: ignoring syscall madvise(...)
     Validating...Success!
     Exiting @ tick 9386342000 because exiting with last active thread context
+```
diff --git a/_pages/documentation/learning_gem5/part3/part3_10_MSIdebugging.md b/_pages/documentation/learning_gem5/part3/part3_10_MSIdebugging.md
index 7ff437d..d06c110 100644
--- a/_pages/documentation/learning_gem5/part3/part3_10_MSIdebugging.md
+++ b/_pages/documentation/learning_gem5/part3/part3_10_MSIdebugging.md
@@ -8,8 +8,6 @@
 ---
 
 
-Debugging SLICC Protocols
-=========================
 
 In this section, I present the steps that I took while debugging the MSI
 protocol implemented earlier in this chapter. Learning to debug
@@ -26,8 +24,7 @@
 then the solution to the error, sometimes with some commentary of the
 different tactics I tried to solve the error.
 
-General debugging tips
-----------------------
+## General debugging tips
 
 Ruby has many useful debug flags. However, the most useful, by far, is
 `ProtocolTrace`. Below, you will see several examples of using the
@@ -83,8 +80,7 @@
 easier to debug your protocol with the random tester than with real
 applications!
 
-Understanding Protocol Traces
------------------------------
+## Understanding Protocol Traces
 
 Unfortunately, despite extensive effort to catch bugs in them, coherence
 protocols (even heavily tested ones) will have bugs. Sometimes these
@@ -105,6 +101,7 @@
 is happening. To start with, lets look at a small snippet of a protocol
 trace (we will discuss the details of this trace further below):
 
+```protocoltrace
     ...
     4541   0    L1Cache         Replacement   MI_A>MI_A   [0x4ac0, line 0x4ac0]
     4542   0    L1Cache              PutAck   MI_A>I      [0x4ac0, line 0x4ac0]
@@ -118,37 +115,38 @@
     5321   0        Seq               Begin       >       [0x4aec, line 0x4ac0] ST
     5322   0    L1Cache               Store      S>SM_AD  [0x4ac0, line 0x4ac0]
     5327   0  Directory                GetM      S>M_M    [0x4ac0, line 0x4ac0]
+```
 
 Every line in this trace has a set pattern in terms of what information
 appears on that line. Specifically, the fields are:
 
-1.  Current Tick: the tick the print is occurs in
-2.  Machine Version: The number of the machine where this request is
-    coming from. For example, if there are 4 L1 caches, then the numbers
-    would be 0-3. Assuming you have 1 L1 Cache per core, you can think
-    of this as representing the core the request is coming from.
-3.  Component: which part of the system is doing the print. Generally,
-    `Seq` is shorthand for Sequencer, `L1Cache` represents the L1 Cache,
-    "Directory" represents the directory, and so on. For L1 caches and
-    the directory, this represents the name of the machine type (i.e.,
-    what is after "MachineType:" in the `machine()` definition).
-4.  Action: what the component is doing. For example, "Begin" means the
-    Sequencer has received a new request, "Done" means that the
-    Sequencer is completing a previous request, and "DataDirNoAcks"
-    means that our DataDirNoAcks event is being triggered.
-5.  Transition (e.g., MI\_A\>MI\_A): what state transition this action
-    is doing (format: "currentState\>nextState"). If no transition is
-    happening, this is denoted with "\>".
-6.  Address (e.g., [0x4ac0, line 0x4ac0]): the physical address of the
-    request (format: [wordAddress, lineAddress]). This address will
-    always be cache-block aligned except for requests from the
-    `Sequencer` and `mandatoryQueue`.
-7.  (Optional) Comments: optionally, there is one additional field to
-    pass comments. For example, the "LD" , "ST", and "33 cycles" lines
-    use this extra field to pass additional information to the trace --
-    such as identifying the request as a load or store. For SLICC
-    transitions, `APPEND_TRANSITION_COMMENT` often use this, as we
-    [discussed previously](../cache-actions/).
+1. Current Tick: the tick the print is occurs in
+2. Machine Version: The number of the machine where this request is
+   coming from. For example, if there are 4 L1 caches, then the numbers
+   would be 0-3. Assuming you have 1 L1 Cache per core, you can think
+   of this as representing the core the request is coming from.
+3. Component: which part of the system is doing the print. Generally,
+   `Seq` is shorthand for Sequencer, `L1Cache` represents the L1 Cache,
+   "Directory" represents the directory, and so on. For L1 caches and
+   the directory, this represents the name of the machine type (i.e.,
+   what is after "MachineType:" in the `machine()` definition).
+4. Action: what the component is doing. For example, "Begin" means the
+   Sequencer has received a new request, "Done" means that the
+   Sequencer is completing a previous request, and "DataDirNoAcks"
+   means that our DataDirNoAcks event is being triggered.
+5. Transition (e.g., MI\_A\>MI\_A): what state transition this action
+   is doing (format: "currentState\>nextState"). If no transition is
+   happening, this is denoted with "\>".
+6. Address (e.g., [0x4ac0, line 0x4ac0]): the physical address of the
+   request (format: [wordAddress, lineAddress]). This address will
+   always be cache-block aligned except for requests from the
+   `Sequencer` and `mandatoryQueue`.
+7. (Optional) Comments: optionally, there is one additional field to
+   pass comments. For example, the "LD" , "ST", and "33 cycles" lines
+   use this extra field to pass additional information to the trace --
+   such as identifying the request as a load or store. For SLICC
+   transitions, `APPEND_TRANSITION_COMMENT` often use this, as we
+   [discussed previously](../cache-actions/).
 
 Generally, spaces are used to separate each of these fields (the space
 between the fields are added implicitly, you do not need to add them).
@@ -176,15 +174,18 @@
 `Seq               Begin` and `Seq                Done` trace prints
 come from (search for ProtocolTrace).
 
-Errors I ran into debugging MSI
--------------------------------
+## Errors I ran into debugging MSI
 
+```termout
     gem5.opt: build/MSI/mem/ruby/system/Sequencer.cc:423: void Sequencer::readCallback(Addr, DataBlock&, bool, MachineType, Cycles, Cycles, Cycles): Assertion `m_readRequestTable.count(makeLineAddress(address))' failed.
+```
 
-I'm an idiot, it was that I called readCallback in externalStoreHit
+I'm made a silly mistake. It was that I called readCallback in externalStoreHit
 instead of writeCallback. It's good to start simple!
 
+```termout
     gem5.opt: build/MSI/mem/ruby/network/MessageBuffer.cc:220: Tick MessageBuffer::dequeue(Tick, bool): Assertion `isReady(current_time)' failed.
+```
 
 I ran gem5 in GDB to get more information. Look at
 L1Cache\_Controller::doTransitionWorker. The current transition is:
@@ -195,8 +196,10 @@
 The problem is that the PutAck is on the forward network, not the
 response network.
 
+```termout
     panic: Invalid transition
     system.caches.controllers0 time: 3594 addr: 3264 event: DataDirAcks state: IS_D
+```
 
 Hmm. I think this shouldn't have happened. The needed acks should always
 be 0 or you get data from the owner. Ah. So I implemented sendDataToReq
@@ -215,19 +218,21 @@
 requestor is the owner do we include the number of sharers. Otherwise,
 it doesn't matter at all and we just set the sharers to 0.
 
-
+```termout
     panic: Invalid transition system.caches.controllers0 time: 5332
     addr: 0x4ac0 event: Inv state: SM\_AD
+```
 
 First, let's look at where Inv is triggered. If you get an invalidate...
 only then. Maybe it's that we are on the sharer list and shouldn't be?
 
 We can use protocol trace and grep to find what's going on.
 
-```
+```sh
 build/MSI/gem5.opt --debug-flags=ProtocolTrace configs/learning_gem5/part6/ruby_test.py | grep 0x4ac0
 ```
 
+```termout
     ...
     4541   0    L1Cache         Replacement   MI_A>MI_A   [0x4ac0, line 0x4ac0]
     4542   0    L1Cache              PutAck   MI_A>I      [0x4ac0, line 0x4ac0]
@@ -241,6 +246,7 @@
     5321   0        Seq               Begin       >       [0x4aec, line 0x4ac0] ST
     5322   0    L1Cache               Store      S>SM_AD  [0x4ac0, line 0x4ac0]
     5327   0  Directory                GetM      S>M_M    [0x4ac0, line 0x4ac0]
+```
 
 Maybe there is a sharer in the sharers list when there shouldn't be? We
 can add a defensive assert in clearOwner and setOwner.
@@ -261,7 +267,9 @@
 
 Now, I get the following error:
 
+```termout
     panic: Runtime Error at MSI-dir.sm:301: assert failure.
+```
 
 This is in setOwner. Well, actually this is OK since we need to have the
 sharers still set until we count them to send the ack count to the
@@ -280,7 +288,9 @@
 
 So, onto the next problem!
 
+```termout
     panic: Deadlock detected: current_time: 56091 last_progress_time: 6090 difference:  50001 processor: 0
+```
 
 Deadlocks are the worst kind of error. Whatever caused the deadlock is
 ancient history (i.e., likely happened many cycles earlier), and often
@@ -290,6 +300,7 @@
 the protocol trace into a file because it grows *very* big) I see that
 there is an address that is trying to be replaced. Let's start there.
 
+```protocoltrace
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
@@ -300,10 +311,12 @@
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
     56091   0    L1Cache         Replacement   SM_A>SM_A   [0x5ac0, line 0x5ac0]
+```
 
 Before this replacement got stuck I see the following in the protocol
 trace. Note: this is 50000 cycles in the past!
 
+```protocoltrace
     ...
     5592   0    L1Cache               Store      S>SM_AD  [0x5ac0, line 0x5ac0]
     5597   0  Directory                GetM      S>M_M    [0x5ac0, line 0x5ac0]
@@ -311,6 +324,7 @@
     5641   0  Directory             MemData    M_M>M      [0x5ac0, line 0x5ac0]
     ...
     5646   0    L1Cache         DataDirAcks  SM_AD>SM_A   [0x5ac0, line 0x5ac0]
+```
 
 Ah! This clearly should not be DataDirAcks since we only have a single
 CPU! So, we seem to not be subtracting properly. Going back to the
@@ -328,6 +342,7 @@
 
 What I'm seeing at the end of the protocol trace is the following.
 
+```protocoltrace
     144684   0    L1Cache         Replacement   MI_A>MI_A   [0x5bc0, line 0x5bc0]
     ...
     144685   0  Directory                GetM   MI_M>MI_M   [0x54c0, line 0x54c0]
@@ -340,6 +355,7 @@
     ...
     144687   0  Directory                GetM   MI_M>MI_M   [0x54c0, line 0x54c0]
     ...
+```
 
 This is repeated for a long time.
 
@@ -385,10 +401,12 @@
 Then, I see the following output when running with ProtocolTrace and
 RubySlicc.
 
+```gem5trace
     118   0  Directory             MemData    M_M>M      [0x400, line 0x400]
     118: system.caches.controllers2: MSI-dir.sm:160: Owner [NetDest (16) 1 0  -  -  - 0  -  -  -  -  -  -  -  -  -  -  -  -  - ]
     118   0  Directory                GetM      M>M      [0x400, line 0x400]
     118: system.caches.controllers2: MSI-dir.sm:160: Owner [NetDest (16) 1 1  -  -  - 0  -  -  -  -  -  -  -  -  -  -  -  -  - ]
+```
 
 It looks like when we process the GetM when in state M we need to first
 clear the owner before adding the new owner. The other options is in
@@ -397,7 +415,9 @@
 
 Oooo! This is a new error!
 
+```termout
     panic: Runtime Error at MSI-dir.sm:229: Unexpected message type..
+```
 
 What is this message that fails? Let's use the RubyNetwork debug flag to
 try to track down what message is causing this error. A few lines above
@@ -409,7 +429,9 @@
 the first two 0's are for the CPUs, and the other 1 must be fore the
 directory.
 
+```gem5trace
     2285: PerfectSwitch-2: Message: [ResponseMsg: addr = [0x8c0, line 0x8c0] Type = InvAck Sender = L1Cache-1 Destination = [NetDest (16) 0 0  -  -  - 1  -  -  -  -  -  -  -  -  -  -  -  -  - ] DataBlk = [ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xb1 0xb2 0xb3 0xb4 0xca 0xcb 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ] MessageSize = Control Acks = 0 ]
+```
 
 This message has the type InvAck, which is clearly wrong! It seems that
 we are setting the requestor wrong when we send the invalidate (Inv)
@@ -419,8 +441,10 @@
 requestor. This was already correct for the FwdGetS/M, but I missed the
 invalidate somehow. On to the next error!
 
+```termout
     panic: Invalid transition
     system.caches.controllers0 time: 2287 addr: 0x8c0 event: LastInvAck state: SM_AD
+```
 
 This seems to be that I am not counting the acks correctly. It could
 also be that the directory is much slower than the other caches at
@@ -449,10 +473,12 @@
 corrupted in the ancient past. I believe the address is the last one in
 the protocol trace.
 
+```termout
     panic: Action/check failure: proc: 0 address: 19688 data: 0x779e6d0
     byte\_number: 0 m\_value+byte\_number: 53 byte: 0 [19688, value: 53,
     status: Check\_Pending, initiating node: 0, store\_count: 4]Time:
     5843
+```
 
 So, it could be something to do with ack counts, though I don't think
 this is the issue. Either way, it's a good idea to annotate the protocol
@@ -468,7 +494,9 @@
 }
 ```
 
+```protocoltrace
     5737   1    L1Cache              InvAck  SM_AD>SM_AD  [0x400, line 0x400] Acks: -1
+```
 
 For these data issues, the debug flag RubyNetwork is useful because it
 prints the value of the data blocks at every point it is in the network.
@@ -477,24 +505,28 @@
 have valid data. In fact, if we go back in time some we see that there
 was some non-zero elements.
 
+```protocoltrace
     5382   1    L1Cache                 Inv      S>I      [0x4cc0, line 0x4cc0]
+```
 
-    > 5383: PerfectSwitch-1: Message: [ResponseMsg: addr = [0x4cc0, line
-    > 0x4cc0] Type = InvAck Sender = L1Cache-1 Destination = [NetDest (16) 1
-    > 0 - - - 0 - - - - - - - - - - - - - ] DataBlk = [ 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x35 0x36 0x37 0x61 0x6d 0x6e 0x6f 0x70 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ] MessageSize = Control Acks =
-    > 0 ] ... ... ... 5389 0 Directory MemData M\_M\    >M [0x4cc0, line 0x4cc0]
-    > 5390: PerfectSwitch-2: incoming: 0 5390: PerfectSwitch-2: Message:
-    > [ResponseMsg: addr = [0x4cc0, line 0x4cc0] Type = Data Sender =
-    > Directory-0 Destination = [NetDest (16) 1 0 - - - 0 - - - - - - - - -
-    > - - - - ] DataBlk = [ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
-    > 0x0 ] MessageSize = Data Acks = 1 ]
+```gem5trace
+    5383: PerfectSwitch-1: Message: [ResponseMsg: addr = [0x4cc0, line
+    0x4cc0] Type = InvAck Sender = L1Cache-1 Destination = [NetDest (16) 1
+    0 - - - 0 - - - - - - - - - - - - - ] DataBlk = [ 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x35 0x36 0x37 0x61 0x6d 0x6e 0x6f 0x70 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ] MessageSize = Control Acks =
+    0 ] ... ... ... 5389 0 Directory MemData M\_M\    >M [0x4cc0, line 0x4cc0]
+    5390: PerfectSwitch-2: incoming: 0 5390: PerfectSwitch-2: Message:
+    [ResponseMsg: addr = [0x4cc0, line 0x4cc0] Type = Data Sender =
+    Directory-0 Destination = [NetDest (16) 1 0 - - - 0 - - - - - - - - -
+    - - - - ] DataBlk = [ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
+    0x0 ] MessageSize = Data Acks = 1 ]
+```
 
 It seems that memory is not being updated correctly on the M-\>S
 transition. After lots of digging and using the MemoryAccess debug flag
@@ -503,8 +535,10 @@
 PutM, but not right for Data. We need to have another action to send
 data from response queue!
 
+```termout
     panic: Invalid transition
     system.caches.controllers0 time: 44381 addr: 0x7c0 event: Inv state: SM_AD
+```
 
 Invalid transition is my personal favorite kind of SLICC error. For this
 error, you know exactly what address caused it, and it's very easy to
diff --git a/_pages/documentation/learning_gem5/part3/part3_11_simple-MI_example.md b/_pages/documentation/learning_gem5/part3/part3_11_simple-MI_example.md
index c38e8bb..c11be46 100644
--- a/_pages/documentation/learning_gem5/part3/part3_11_simple-MI_example.md
+++ b/_pages/documentation/learning_gem5/part3/part3_11_simple-MI_example.md
@@ -7,10 +7,6 @@
 author: Jason Lowe-Power
 ---
 
-
-Configuring for a standard protocol
-===================================
-
 You can easily adapt the simple example configurations from this part to
 the other SLICC protocols in gem5. In this chapter, we will briefly look
 at an example with `MI_example`, though this can be easily extended to
@@ -26,7 +22,7 @@
 the classes needed for `MI_example`. There are only a couple of changes
 from `MSI`, mostly due to different naming schemes. You can download the
 file
-[here](/_pages/static/scripts/part3/configs/ruby_caches_MI_example.py).
+[here](https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/configs/learning_gem5/part3/ruby_caches_MI_example.py).
 
 ```python
 class MyCacheSystem(RubySystem):
diff --git a/_pages/events/boot-camp-2022.md b/_pages/events/boot-camp-2022.md
index 0ac0ede..fcd2c8f 100644
--- a/_pages/events/boot-camp-2022.md
+++ b/_pages/events/boot-camp-2022.md
@@ -12,6 +12,19 @@
 
 **Important Note:** Registration for this event is now closed.
 
+
+## Livestream and discussion
+
+You can find links to all of the livestreamed videos on [YouTube](https://www.youtube.com/playlist?list=PL_hVbFs_loVSaSDPr1RJXP5RRFWjBMqq3).
+
+Instead of using YouTube comments, we will be using [Slack](https://app.slack.com/client/T03JNC47S2E/C03PJRJ4RQ8) for our discussions.
+You can use the following [invite](https://join.slack.com/t/gem5-workspace/shared_invite/zt-1aal963w6-_cqn0u8QgBh3GeeSi2Ja7g) link to enter the slack.
+Once you have joined, type `/join-channel bootcamp-2022` in any text box (e.g., in a DM to yourself) to join the bootcamp channel.
+
+## gem5 Bootcamp Content
+
+The Bootcamp event content, including archived videos of events, can be found here: https://gem5bootcamp.github.io/gem5-bootcamp-env/
+
 ## Key Dates
 
 * Boot camp: **July 11th to July 15th 2022**
@@ -86,3 +99,48 @@
 | Friday Morning | Writing tests and contributing to gem5 | - Write a GTest to test a piece of CPP code <br> - Write a PyUnit test to test a python function <br> - Use testlib to test a gem5 simulation condition <br> - Run Testlib/PyUnit/GUnit tests for gem5 <br> - Understand gem5's quick/Kokoro, long/Nightly, very-long/Weekly test structure <br> - Understand gem5's code-formatting guidelines <br> - Use git to add code to the repo <br> - Review patches on Gerrit <br> - Respond to feedback on Gerrit |
 | Friday Afternoon | gem5 extensions and other simulators | - Incorporate SST into a simulation <br> - Incorporate DRAMSim into a simulation <br> - Use SystemC in gem5 and gem5 in SystemC |
 | | Wrapping things up | |
+
+## Information for attendees
+
+### Hosting
+
+Those attendees being hosted on campus will be staying in [Wall Hall](https://housing.ucdavis.edu/residence-halls/wall-hall).
+Please check your email for information on checking into your room on the day of arrival.
+
+### General Event Information
+
+The Bootcamp will run Monday to Friday, 9AM to 4PM each day at UC Davis's [Putah Creek Lodge](https://ces.ucdavis.edu/putah-creek-lodge).
+Please see our map below highlighting the suggested walking route from Wall Hall to the Putah Creek lodge.
+
+![](/assets/files/bootcamp-2022/bootcamp-travel-map.png)
+
+### Meals
+
+A continental breakfast (with coffee) will be served daily, at around 8:30AM, at Putah Creek Lodge.
+
+Each day lunch will be served 12-noon and will conclude at 1PM.
+Lunch will consist of a selection of sandwiches and wraps.
+There will be no pork served and vegan options will be provided.
+
+The session will continue for 3 more hours until 4PM.
+Coffee and snacks will be provided during this time.
+
+Evening meals will be provided by Housing Services with food served from 5PM to 7PM each day at the campus dining halls.
+Please check your email for information about using Conference Housing Services Dining Commons.
+
+Breakfast will be provided by Conference Housing Service Dining Commons on Saturday Morning, assuming you choose to stay Friday night.
+
+### Welcome Dinner
+
+On Monday attendees will have a Welcome Dinner at [Dunloe Brewing](https://dunloebrewing.com/) (1606 Olive Dr, Davis).
+The event will start at 5:30PM and attendees will head there straight after Monday's Workshop session from Putah Creek Lodge.
+The event will conclude at 7:30PM.
+
+[Zim Cuisine](https://www.zimcuisine.com) will be catering this event.
+
+### Thursday Night Social Event
+
+From 7PM to 10PM Thursday night a social event will be held for all Workshop attendees at the [Memorial Union Games Area](https://memorialunion.ucdavis.edu/games-area).
+
+**Food will not be provided at this event.**
+Attendees should utilize Dining Commons services prior to attending.
diff --git a/_pages/events/hpca-2023.md b/_pages/events/hpca-2023.md
new file mode 100644
index 0000000..c0b86c7
--- /dev/null
+++ b/_pages/events/hpca-2023.md
@@ -0,0 +1,46 @@
+---
+title: "HPCA 2023: gem5 Tutorial"
+permalink: events/hpca-2023
+---
+
+We are happy to announce the gem5 Tutorial, to be co-located with [HPCA 2023](https://hpca-conf.org/2023/), in Montreal, on  **Saturday February 25th 2023**. **We intend for this event to be held in person**.
+
+The gem5 Tutorial will be held in the morning session and will focus on teaching those new to gem5 how to use the latest version.
+It will be "crash course" in gem5 and assume no prior knowledge of using computer architecture simulators.
+The tutorial will focus heavily on new features in gem5, such as the [gem5 standard library](/documentation/gem5-stdlib/overview), so may be suitable for those who have used gem5 before but wish to refresh their skills.
+
+Please keep an eye on the [HPCA 2023 event page](https://hpca-conf.org/2023/) for details on registering for this event.
+
+## Key Dates
+
+* HPCA Conference: **February 25th to March 1st 2023**
+* gem5 Tutorial: **February 25th 2023 (Morning Session)**
+
+# Location and Room
+
+The tutorial will be held at the HPCA '23's main venue, the Hotel Bonaventure, in Westmount 6.
+
+### Preliminary Schedule (Subject to change)
+
+Below is a preliminary schedule for the tutorial.
+It highlights the topics we intend to cover over the course of the 3-hour event.
+
+* Getting started with gem5 [1.5 hours]
+    * A short history of gem5.
+    * Overall (software) architecture of gem5.
+    * Compiling gem5.
+    * Introduction to running a gem5 simulation using prebuilt systems
+    * First time running gem5 and interpreting the output.
+    * Building a gem5 simulation using stdlib components.
+    * Simple example to show select statistical outputs.
+    * Work through examples building SE-mode and FS-mode simulations.
+* Extending gem5 [~1 hour]
+    * Structure of gem5 C++ code.
+    * Writing a simple SimObject.
+    * Creating your own component, extending from the stdlib.
+    * Running simulations using your SimObject/component.
+* Deeper gem5 topics [~1 hour]
+    * The gem5 memory system.
+    * Overview of Ruby.
+    * A brief overview of other gem5 features.
+    * Limitations of gem5.
diff --git a/_pages/events/index.md b/_pages/events/index.md
index 594311c..3080d92 100644
--- a/_pages/events/index.md
+++ b/_pages/events/index.md
@@ -16,6 +16,15 @@
 The slides and handouts are the same material except that the handouts
 are formatted with two slides per page.
 
+## HPCA 2023: The gem5 Tutorial
+
+[More information can be found on the event's page](/events/hpca-2023).
+
+We will be hosting the 5th gem5 Tutorial HPCA 2023.
+
+The tutorial will give those new to gem5 a "crash course" in using the tool to carry out architecture research.
+
+
 ## gem5 Boot Camp 2022
 
 [More information can be found on the official Boot Camp event page](/events/boot-camp-2022)
diff --git a/_pages/events/isca-2022.md b/_pages/events/isca-2022.md
index e26908d..114141e 100644
--- a/_pages/events/isca-2022.md
+++ b/_pages/events/isca-2022.md
@@ -15,6 +15,15 @@
 The workshop will continue with short presentations (15 minutes each) on gem5-related topics.
 We hope this will invoke discussions on gem5-related topics.
 
+## Links
+
+* [Livestream recording of tutorial](https://www.youtube.com/watch?v=qA0zYKgDw0c&ab_channel=gem5)
+  * [Intro and Simulation slides](/assets/files/isca2022-tutorial/learning-gem5-part-1.pdf)
+  * [Standard library slides](/assets/files/isca2022-tutorial/gem5-stdlib-tutorial.pdf)
+  * [Getting started developing slides](/assets/files/isca2022-tutorial/learning-gem5-developing.pdf)
+  * [A bit of everything else slides](/assets/files/isca2022-tutorial/a-little-bit-of-everything.pdf)
+* [Livestream recording of workshop](https://www.youtube.com/watch?v=4q69hhO64Cc&ab_channel=gem5)
+
 ## Key Dates
 
 * ~~Workshop presentation proposal deadline: **April 26th 2022** (Presentation abstracts can be submitted [here](https://forms.gle/VZxXsWBniUPGBQdw5))~~
diff --git a/_posts/2020-06-15-town-hall-notes.md b/_posts/2020-06-15-town-hall-notes.md
new file mode 100644
index 0000000..6b54b98
--- /dev/null
+++ b/_posts/2020-06-15-town-hall-notes.md
@@ -0,0 +1,70 @@
+---
+layout: post
+title:  "Town Hall Meeting notes"
+author: Bobby R. Bruce
+date:   15-06-2020
+---
+
+On Wednesday June 3rd the gem5 Workshop Town hall was held.
+
+This session was recorded and is publicly available for viewing:
+
+<iframe width="560" height="315"
+src="https://www.youtube.com/embed/fvCXmMBblZY" frameborder="0"
+allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
+allowfullscreen></iframe>
+
+Noted below are the highlights from the meeting:
+
+* A question was raised about minor releases. While we are open to the idea of
+releasing minor versions of gem5, we have no immediate plans to do so in the
+near future. We will continue to focus efforts on the next major version of
+gem5; to be released in the next few months.
+* The project intends to provide "good known configurations" which are
+tested against, and known to be realistic simulations of, real-world hardware.
+* To produce a faster product, it was suggested that gem5 could be
+paralleized. This is considered a task requiring significant engineering
+effort. As such, we have no intention of doing so as part of any foreseeable
+release.
+* The stats package was discussed at length, particularly the fact that its
+output is confusing.
+    * Stats documentation is accepted to be lacking and should be improved.
+    * A suggestion was raised to include a stats parser in the code-base. There
+was general agreement this would be beneficial.
+    * A JSON stats output format is now available, though not all SimObjects
+have been converted for it to function correctly in all cases.
+* Testing SimObjects was raised as a pain-point.
+    * A test harness for SimObjects would be of benefit; one that would
+permit the creation of unit tests for SimObjects.
+    * Better SimObject testing plays into gem5's broader desire to improve
+testing overall.
+* Some complained about gem5's code format checking.
+    * We could provide a clang format checker config as part of the gem5
+code-base.
+    * Some policies could be relaxed, particularly those regarding the C/C++
+header files which are, in some cases, non-standard.
+    * A general move towards more standardized C/C++ code-style standards would
+be beneficial overall.
+* It was noted that the clang address sanitizer should be run more frequently.
+Though these were run prior to the release of gem5-20, regular checks could
+catch bugs earlier in development.
+* Many in the community are are interested in the simulated performance. Going
+forward, this should be noted on the gem5 benchmark page. This data will enable
+us to understand whether our performance is degrading or improving over time.
+    * There were suggestions that simulated performance should be regularly,
+and automatically, tested in order to flag changes that result in degraded
+performance. However, it is unknown how this can be achieved.
+* FlexCPU should be merged into the gem5 code-base.
+* In a discussion regarding O3CPU; it was generally accepted that it is very
+out-of-date and needs considerable improvements.
+* PCI/PCIe support is desired by some but most agreed it should not be a top
+priority.
+* Multicore simulation is agreed to have problems and, generally, needs to be
+better supported.
+* A question was raised asking if SE mode will eventually be dropped. While we
+will continue to improve FS mode, we wish to maintain SE mode as it can be
+used to run faster simulations in cases where full-system simulation is not
+required.
+    * There is on-going engineering efforts to consolidate the SE and FS code
+in order to lessen the maintenance burden associated with supporting both modes
+of usage.
diff --git a/assets/files/bootcamp-2022/bootcamp-travel-map.png b/assets/files/bootcamp-2022/bootcamp-travel-map.png
new file mode 100644
index 0000000..a3538bf
--- /dev/null
+++ b/assets/files/bootcamp-2022/bootcamp-travel-map.png
Binary files differ
diff --git a/assets/files/isca2022-tutorial/a-little-bit-of-everything.pdf b/assets/files/isca2022-tutorial/a-little-bit-of-everything.pdf
new file mode 100644
index 0000000..fd5cfd8
--- /dev/null
+++ b/assets/files/isca2022-tutorial/a-little-bit-of-everything.pdf
Binary files differ
diff --git a/assets/files/isca2022-tutorial/gem5-stdlib-tutorial.pdf b/assets/files/isca2022-tutorial/gem5-stdlib-tutorial.pdf
new file mode 100644
index 0000000..7b22293
--- /dev/null
+++ b/assets/files/isca2022-tutorial/gem5-stdlib-tutorial.pdf
Binary files differ
diff --git a/assets/files/isca2022-tutorial/learning-gem5-developing.pdf b/assets/files/isca2022-tutorial/learning-gem5-developing.pdf
new file mode 100644
index 0000000..c1f1df6
--- /dev/null
+++ b/assets/files/isca2022-tutorial/learning-gem5-developing.pdf
Binary files differ
diff --git a/assets/files/isca2022-tutorial/learning-gem5-part-1.pdf b/assets/files/isca2022-tutorial/learning-gem5-part-1.pdf
new file mode 100644
index 0000000..fd23553
--- /dev/null
+++ b/assets/files/isca2022-tutorial/learning-gem5-part-1.pdf
Binary files differ
diff --git a/assets/img/HeteroGarnet_Life.png b/assets/img/HeteroGarnet_Life.png
new file mode 100644
index 0000000..d15525b
--- /dev/null
+++ b/assets/img/HeteroGarnet_Life.png
Binary files differ
diff --git a/assets/img/ISAInd.png b/assets/img/ISAInd.png
new file mode 100644
index 0000000..36e4455
--- /dev/null
+++ b/assets/img/ISAInd.png
Binary files differ
diff --git a/assets/img/SerDes_CDC.png b/assets/img/SerDes_CDC.png
new file mode 100644
index 0000000..0af3719
--- /dev/null
+++ b/assets/img/SerDes_CDC.png
Binary files differ
diff --git a/index.html b/index.html
index 448cebc..f0c1a76 100755
--- a/index.html
+++ b/index.html
@@ -21,6 +21,8 @@
   <a href="https://gem5.googlesource.com/public/gem5"><button type="button" class="btn btn-outline-primary">Source</button></a>
   <a href="https://gem5-review.googlesource.com/"><button type="button" class="btn btn-outline-primary">Code Review</button></a>
   <a href="https://arxiv.org/abs/2007.03152"><button type="button" class="btn btn-outline-primary">gem5-20+ paper</button></a>
+  <a href="https://join.slack.com/t/gem5-workspace/shared_invite/zt-1c8go4yjo-LNb7l~BZ0FagwmVxX08y9g"><button type="button" class="btn btn-outline-primary">Join our Slack</button></a>
+  <a href="https://www.youtube.com/channel/UCCpCGEj_835WYmbB0g96lZw"><button type="button" class="btn btn-outline-primary">gem5 Youtube</button></a>
 
   <div class="testing-status">
     <div class="testing-title">
@@ -76,6 +78,17 @@
 
     <div class="col">
       <div class="card">
+        <div class="fav"><i class="fa fa-youtube"></i></div>
+        <div class="card-body">
+          <h5 class="card-title">YouTube</h5>
+          <p class="card-text">Learn more about gem5 on our YouTube channel</p>
+          <a href="https://www.youtube.com/channel/UCCpCGEj_835WYmbB0g96lZw" class="btn btn-primary">Go to YouTube</a>
+        </div>
+      </div>
+    </div>
+
+    <div class="col">
+      <div class="card">
         <div class="fav"><i class="fa fa-download"></i></div>
         <div class="card-body">
           <h5 class="card-title">Guest binaries</h5>