From 5e802f81741d5c99a1c0b38f7d2277aa78855409 Mon Sep 17 00:00:00 2001 From: Paul Scheffler Date: Wed, 30 Aug 2023 22:20:25 +0200 Subject: [PATCH] doc: More work on documentation --- README.md | 2 +- docs/gs.md | 6 +- docs/img/arch.svg | 582 +++++++++++++++++++----------------- docs/tg/integr.md | 66 +++- docs/tg/sim.md | 20 +- docs/tg/xilinx.md | 16 +- docs/um/arch.md | 316 +++++++++++++++----- docs/um/index.md | 5 + docs/um/sw.md | 108 ++++++- hw/regs/cheshire_regs.hjson | 2 +- mkdocs.yml | 2 +- 11 files changed, 752 insertions(+), 373 deletions(-) diff --git a/README.md b/README.md index 9a918831e..a58de20c2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cheshire -Cheshire is a minimal Linux-capable host platform built around the RISC-V [CVA6]() core. Its goal is to provide a *lightweight*, *configurable*, *autonomously booting* host to systems that need one, from minimal Linux-capable SoCs to manycore compute accelerators. +Cheshire is a minimal Linux-capable host platform built around the RISC-V [CVA6](https://github.com/openhwgroup/cva6) core. Its goal is to provide a *lightweight*, *configurable*, *autonomously booting* host to systems that need one, from minimal Linux-capable SoCs to manycore compute accelerators. Cheshire is developed as part of the PULP project, a joint effort between ETH Zurich and the University of Bologna. diff --git a/docs/gs.md b/docs/gs.md index 40fcb5667..5b95d9c80 100644 --- a/docs/gs.md +++ b/docs/gs.md @@ -9,7 +9,7 @@ The project is structured as follows: | Directory | Description | Documentation | | --------- | ---------------------------------------- | ---------------------------| | `hw` | Hardware sources as SystemVerilog RTL | [Architecture](um/arch.md) | -| `sw` | Software stack, build setup, and tests | [Software](um/sw.md) | +| `sw` | Software stack, build setup, and tests | [Software Stack](um/sw.md) | | `target` | Simulation, FPGA, and ASIC target setups | [Targets](tg/index.md) | | `util` | Utility scripts | | | `doc` | Documentation | [Home](index.md) | @@ -22,8 +22,8 @@ To *build* Cheshire, you will need: - GNU Make `>= 3.82` - Bender `>= 0.27.1` - Python `>= 3.9` -- Python packages in `requirements.txt` - RISCV GCC `>= 11.2.0` +- Python packages in `requirements.txt` Depending on your desired target, additional dependencies may be needed. @@ -50,7 +50,7 @@ The following additional targets are not invoked by the above, but also availabl - `bootrom-all`: Rebuilds the boot ROM. This is not done by default as reproducible builds (as checked by CI) can only be guaranteed for fixed compiler versions. - `nonfree-init`: Clones our internal repository with nonfree resources we cannot release, including our internal CI. *This is not necessary to use Cheshire*. -- `clean-deps`: Removes checked-out bender dependencies and submodules. This is useful if references to dependencies are updated. +- `clean-deps`: Removes checked-out bender dependencies and submodules. This is useful when references to dependencies are updated. ## Targets diff --git a/docs/img/arch.svg b/docs/img/arch.svg index 7edbfd142..29f81e47c 100644 --- a/docs/img/arch.svg +++ b/docs/img/arch.svg @@ -9,9 +9,9 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="206.99742mm" - height="119.27628mm" - viewBox="0 0 103.49871 59.638144" + width="206.99744mm" + height="127.2832mm" + viewBox="0 0 103.49872 63.6416" version="1.1" id="svg8" inkscape:version="0.92.2 (5c3e80d, 2017-08-06)" @@ -753,6 +753,21 @@ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" transform="scale(0.2)" /> + + + + originx="2.8532166" + originy="-34.999999" /> @@ -812,14 +827,14 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(5.8532164,-104.36186)"> + transform="translate(5.7798251,-102.03933)"> + height="57.999996" + x="7.0733914" + y="107.68093" /> CVA6 0 ... cfg.NumCores AXI4+ATOP Crossbar iDMA JTAG Debug Serial Link VGA @@ -1059,22 +1074,22 @@ id="rect841-2-7-5-1" width="14.000002" height="3.9999998" - x="63.989441" - y="141.99998" /> + x="64.062836" + y="138.68091" /> Regbus Demux ... ... cfg.AxiExtNumMst cfg.AxiExtNumSlv @@ -1153,11 +1168,11 @@ id="rect841-2-7-5-1-77" width="14.000002" height="3.9999998" - x="63.989441" - y="146.99998" /> + x="64.062836" + y="143.68091" /> @@ -1166,94 +1181,94 @@ id="rect841-2-7-5-1-77-8" width="14.000002" height="3.9999998" - x="63.989441" - y="151.99998" /> + x="64.062836" + y="148.68091" /> IRQ Router CLINT PLIC CVA6 1 + x="28.073389" + y="159.68091" /> CLIC Device configs @@ -1262,41 +1277,41 @@ id="rect897-6" width="5.9999995" height="26.000002" - x="10" - y="124" /> + x="10.073391" + y="123.68093" /> Last Level Cache + x="64.073402" + y="133.68092" /> GPIO @@ -1305,23 +1320,23 @@ id="rect841-2-7-5-5-3-5-1" width="13.999999" height="4.0000014" - x="64.000008" - y="132" /> + x="64.073402" + y="128.68092" /> SPI Host @@ -1330,22 +1345,22 @@ id="rect841-2-7-5-5-3-5-1-2" width="13.999999" height="4.0000014" - x="64.000008" - y="126.99998" /> + x="64.073402" + y="123.68091" /> I2C @@ -1354,22 +1369,22 @@ id="rect841-2-7-5-5-3-5-1-2-2" width="13.999999" height="4.0000014" - x="64" - y="122.00002" /> + x="64.073395" + y="118.68095" /> UART @@ -1378,149 +1393,149 @@ id="rect841-2-7-5-1-0" width="14.000003" height="3.9999998" - x="64.000008" - y="157" /> + x="64.073402" + y="153.68092" /> Boot ROM gpio* spih* i2c* uart* xeip_ext* m*ip_ext* intr_ext* + transform="translate(1.0733974,-3.3190792)"> + transform="translate(1.0733974,-3.3190792)"> ... cfg.RegExtNumSlv reg_ext_slv* vga* slink* jtag* axi_ext* dbg* axi_llc* ... (to DRAM) + + SoC Regs + diff --git a/docs/tg/integr.md b/docs/tg/integr.md index 7d6fc10b7..26e4c91f1 100644 --- a/docs/tg/integr.md +++ b/docs/tg/integr.md @@ -1,6 +1,6 @@ # SoC Integration -Cheshire is designed to be *highly configurable* and provide host and interconnect infrastructure for systems on various scales. Examples of SoCs integrating Cheshire are: +Cheshire is designed to be *highly configurable* and provide host and interconnect infrastructure for systems on various scales. Examples of SoCs integrating Cheshire as a host are: - [Iguana](https://github.com/pulp-platform/iguana), an minimal end-to-end open-source Linux-capable SoC built with open tools. - [Carfield](https://github.com/pulp-platform/carfield), a mixed-criticality SoC targeting the automotive domain. @@ -9,7 +9,7 @@ Cheshire is designed to be *highly configurable* and provide host and interconne As for internal targets, Cheshire *must be built* before use in external projects. We aim to simplify this as much as possible with a portable *make fragment*. -If you use GNU Make to build your project and Bender to handle dependencies, you can include the Cheshire build system into your own Makefile with: +If you use GNU Make to build your project and Bender to handle dependencies, you can include the Cheshire build system into your own makefile with: ```make include $(shell bender path cheshire)/cheshire.mk @@ -21,4 +21,64 @@ You can leverage this to ensure your Cheshire build is up to date and rebuild ha ## Instantiating Cheshire -Almost all features of Cheshire can be included/excluded or scaled through parameterization. We empose an internal memory map and reasonable constraints on all parameters, but within these constraints, Cheshire can scale to fit numerous scenarios. +Almost all features of Cheshire can be included, excluded, or scaled through parameterization. We impose an internal memory map and reasonable constraints on all parameters, but within these constraints, Cheshire can scale to fit numerous scenarios. + +We provide a SystemVerilog macros header in `hw/include/cheshire/typedef.svh` that simplifies defining necessary interface types for Cheshire. To define a configuration struct for Cheshire, we recommend defining a *function* in a system package that starts from the default configuration `DefaultCfg` in `cheshire_pkg` and changes only necessary parameters. + +Unused inputs and inputs of zero effective width should be tied so as to initiate data transfers or handshakes (usually `'0`). + +A minimal clean instantiation would look as follows: + +```systemverilog +`include "cheshire/typedef.svh" + +// Define function to derive configuration from defaults. +// This could also (preferrably) be done in a system package. +function automatic cheshire_pkg::cheshire_cfg_t gen_cheshire_cfg(); + cheshire_pkg::cheshire_cfg_t ret = cheshire_pkg::DefaultCfg; + // Make overriding changes. Here, we add two AXI manager ports + ret.AxiExtNumMst = 2; + return ret; +endfunction + +localparam cheshire_cfg_t CheshireCfg = gen_cheshire_cfg(); + +// Generate interface types prefixed by `csh_` from our configuration. +`CHESHIRE_TYPEDEF_ALL(csh_, CheshireCfg) + +// Instantiate Cheshire with our configuration and interface types. +cheshire_soc #( + .Cfg ( CheshireCfg ), + .ExtHartinfo ( '0 ), // Tie iff there are no external harts. + .axi_ext_llc_req_t ( csh_axi_llc_req_t ), + .axi_ext_llc_rsp_t ( csh_axi_llc_rsp_t ), + .axi_ext_mst_req_t ( csh_axi_mst_req_t ), + .axi_ext_mst_rsp_t ( csh_axi_mst_rsp_t ), + .axi_ext_slv_req_t ( csh_axi_slv_req_t ), + .axi_ext_slv_rsp_t ( csh_axi_slv_rsp_t ), + .reg_ext_req_t ( csh_reg_req_t ), + .reg_ext_rsp_t ( csh_reg_rsp_t ) +) dut ( + // ... IOs here ... +); +``` + +## Verifying Cheshire In-System + +To simplify the simulation and verification of Cheshire in other systems, we provide a monolithic block of verification IPs called `cheshire_vip`. This includes: + +* ELF binary preloading tasks over JTAG, serial link, and UART. +* External AXI manager ports accessing the chip through the serial link. +* A UART receiver printing to standard output. +* Serial link and LLC subordinate memories. +* Preloadable I2C EEPROM and SPI NOR Flash models (used to simulate boot). + +Additionally, we provide a module `cheshire_vip_tristate` which adapts the unidirectional IO of this module to bidirectional IOs which may be interfaced with pads where necessary. + +## Platform ROM + +To set up boot-critical resources in the surrounding system (clock sources, IO pads, memories, PHYs, ...) or fork off execution from the built-in boot ROM, Cheshire can invoke an external *platform ROM* before external interaction if configured accordingly; see [Boot ROM](../um/sw.md#boot-rom). + +Note that a reference clock, a sufficiently fast and stable system clock, correctly set-up IOs, and an accessible scratchpad memory are *required* for Cheshire's built-in boot modes. Platforms which do not inherently fulfill these criteria on boot ROM entry and want to use the built-in boot methods *must* provide a platform ROM. + +The platform ROM can be also used to extend and customize the boot chain. This may include adding further boot modes, suspending Cheshire boot until a given time, or implementing security features. diff --git a/docs/tg/sim.md b/docs/tg/sim.md index 1f1d75233..677c065bb 100644 --- a/docs/tg/sim.md +++ b/docs/tg/sim.md @@ -1,6 +1,6 @@ # Simulation -This page describes how to simulate Cheshire to *execute baremetal code*. Please first read [Getting Started](../gs.md) to make sure to make sure have all dependencies and built the hardware, software, and simulation scripts. +This page describes how to simulate Cheshire to *execute baremetal programs*. Please first read [Getting Started](../gs.md) to make sure to make sure have all dependencies and built the hardware, software, and simulation scripts. We currently provide working setups for: @@ -10,18 +10,18 @@ We plan on supporting more simulators in the future. If your situation requires ## Testbench -We provide a SystemVerilog testbench for `cheshire_soc` running baremetal code. This code is either preloaded through simulated interface drivers or read from external memory models by the boot ROM and then executed, depending on how the `PRELMODE` and `BOOTMODE` variables are set: +We provide a SystemVerilog testbench for `cheshire_soc` running baremetal programs. This code is either preloaded through simulated interface drivers or read from external memory models by the boot ROM and then executed, depending on how the `PRELMODE` and `BOOTMODE` variables are set: - | `BOOTMODE` | `PRELMODE` | Action | - | ---- | - | ------------------------------------------------------- | - | 0 | 0 | Preload through JTAG | - | 0 | 1 | Preload through serial link | - | 0 | 2 | Preload through UART | - | 1-3 | - | Autonomous boot, see [Boot ROM](../um/arch.md#boot-rom) | + | `BOOTMODE` | `PRELMODE` | Action | + | ---------- | ---------- | ----------------------------------------------------- | + | 0 | 0 | Preload through JTAG | + | 0 | 1 | Preload through serial link | + | 0 | 2 | Preload through UART | + | 1-3 | - | Autonomous boot, see [Boot ROM](../um/sw.md#boot-rom) | -Preloading boot modes expect an ELF executable to be passed through `BINARY`, while autonomous boot modes expect a disk image (GPT formatted or raw code) to be passed through `IMAGE`. For more information on how to build software for Cheshire and its boot process, see [Software](../um/sw.md). +Preloading boot modes expect an ELF executable to be passed through `BINARY`, while autonomous boot modes expect a disk image (GPT formatted or raw code) to be passed through `IMAGE`. For more information on how to build software for Cheshire and its boot process, see [Software Stack](../um/sw.md). -For simulation of Cheshire in other designs, we provide the module `cheshire_vip` encapsulating all verification IPs and their interfaces. +For simulation of Cheshire in other designs, we provide the module `cheshire_vip` encapsulating all verification IPs and their interfaces. For details, see [Verifying Cheshire In-System](integr.md#verifying-cheshire-in-system). ## QuestaSim diff --git a/docs/tg/xilinx.md b/docs/tg/xilinx.md index 86d179514..bb0fa0562 100644 --- a/docs/tg/xilinx.md +++ b/docs/tg/xilinx.md @@ -1,6 +1,6 @@ # Xilinx FGPAs -This page describes how to map Cheshire on Xilinx FPGAs to *execute baremetal code* or *boot CVA6 Linux*. Please first read [Getting Started](../gs.md) to make sure have all dependencies and built the hardware, software, and Xilinx FPGA scripts. Additionally, for on-chip debugging you need: +This page describes how to map Cheshire on Xilinx FPGAs to *execute baremetal programs* or *boot CVA6 Linux*. Please first read [Getting Started](../gs.md) to make sure have all dependencies and built the hardware, software, and Xilinx FPGA scripts. Additionally, for on-chip debugging you need: - OpenOCD `>= 0.10.0` @@ -25,11 +25,11 @@ make -C target/xilinx Before flashing the bitstream to your device, take note of the position of onboard switches, which control important functionality: - | Switch | Function | - | ------ | ------------------------------------------------- | - | 1 .. 0 | Boot mode; see [Boot ROM](../um/arch.md#boot-rom) | - | 5 .. 2 | Fan level; *do not* keep at 0 | - | 7 | Test mode; *leave at zero* | + | Switch | Function | + | ------ | ------------------------------------------------| + | 1 .. 0 | Boot mode; see [Boot ROM](../um/sw.md#boot-rom) | + | 5 .. 2 | Fan level; *do not* keep at 0 | + | 7 | Test mode; *leave at zero* | The reset, JTAG TAP, UART, I2C, and VGA are all connected to their onboard logic or ports. The UART has *no flow control*. The microSD slot is connected to chip select 0 of the SPI host peripheral. Serial link and GPIOs are currently not available. @@ -65,7 +65,7 @@ minicom -cD /dev/ttyUSBX Make sure that hardware flow control matches your board's setup (usually *off*). -In the following examples, we will use the `helloworld` test. As in simulation, you can replace this with any baremetal program of your choosing or design; see [Baremetal Programming](../um/sw#baremetal-programming). +In the following examples, we will use the `helloworld` test. As in simulation, you can replace this with any baremetal program of your choosing or design; see [Baremetal Programs](../um/sw.md#baremetal-programs). ### JTAG Preloading @@ -110,7 +110,7 @@ make -C sw/deps/cva6-sdk images In principle, we can boot Linux through JTAG by loading all images into memory, launching OpenSBI, and instructing U-boot to load the kernel directly from memory. Here, we focus on autonomous boot from SD card. -In this case, OpenSBI is loaded by a regular baremetal program called the [Zero-Stage Loader]() (ZSL). The [boot ROM]() loads the ZSL from SD card, which then loads the device tree and firmware from other SD card partitions into memory and launches OpenSBI. +In this case, OpenSBI is loaded by a regular baremetal program called the [Zero-Stage Loader](../um/sw.md#zero-stage-loader) (ZSL). The [boot ROM]() loads the ZSL from SD card, which then loads the device tree and firmware from other SD card partitions into memory and launches OpenSBI. To create a full Linux disk image from the ZSL, device tree, firmware, and Linux, run: diff --git a/docs/um/arch.md b/docs/um/arch.md index 5feb0b15c..5c92f26bb 100644 --- a/docs/um/arch.md +++ b/docs/um/arch.md @@ -1,91 +1,263 @@ # Architecture -![Image title](../img/arch.svg) +![Cheshire Block Diagram](../img/arch.svg) Cheshire is highly configurable; available features and resources depend on its parameterization. The above block diagram depicts a fully-featured Cheshire SoC, which currently provides: -* **Cores**: - * Up to 16 Linux-capable CVA6 cores with self-invalidation-based coherence - * A RISC-V debug module with JTAG transport +- **Cores**: + - Up to 31 Linux-capable CVA6 cores with self-invalidation-based coherence + - A RISC-V debug module with JTAG transport -* **Peripherals**: - * Various standard IO interfaces (UART, I2C, SPI, and GPIOs) - * A boot ROM enabling boot from SD cards, SPI flash, or I2C EEPROM - * A VGA display controller with built-in DMA - * A fully-digital die-to-die serial link - * A high-throughput system DMA +- **Peripherals**: + - Various standard IO interfaces (UART, I2C, SPI, and GPIOs) + - A boot ROM enabling boot from SD cards, SPI flash, or I2C EEPROM + - A VGA display controller with built-in DMA + - A fully-digital chip-to-chip or die-to-die serial link + - A high-throughput system DMA -* **Interconnect**: - * A last level cache (LLC) configurable as a scratchpad memory (SPM) per-way - * Up to 16 external AXI manager ports and 16 AXI and Regbus subordinate ports - * Per-manager traffic regulators for real-time applications +- **Interconnect**: + - A last level cache (LLC) configurable as a scratchpad memory (SPM) per-way + - Up to 16 external AXI4 manager ports and 16 AXI and Regbus subordinate ports + - Per-manager AXI4 traffic regulators for real-time applications + - Per-manager AXI4 bus error units (UNBENT) for interconnect error handling -* **Interrupts**: - * Core-local (CLINT *and* CLIC) and platform (PLIC) interrupt controllers - * Dynamic interrupt routing from and to internal and external targets. +- **Interrupts**: + - Core-local (CLINT *and* CLIC) and platform (PLIC) interrupt controllers + - Dynamic interrupt routing from and to internal and external targets. -## Parameterization +## Memory Map -Except for external hart info and interface types (see [Instantiating Cheshire](../tg/integr.md#instantiating_cheshire)), Cheshire is fully parameterized through the `Cfg` struct. We will first define SoC-wide parameters, then discuss device-specific parameters for each device. +Cheshire's internal memory map is *static*. While device instantiation and layout may vary, each device is provided an address space of *fixed* location and size. For this, Cheshire *reserves* the address space from `0x0` to `0x2000_0000`, which is currently allocated as follows: ++--------------------+-------------------+---------------+------+-------+ +| Block | Device | Start | Size | Flags | ++====================+===================+===============+======+=======+ +| 256K periphs @ AXI | Debug ROM | `0x0000_0000` | 256K | E | ++--------------------+-------------------+---------------+------+-------+ +| 4K periphs @ AXI | AXI DMA (Cfg) | `0x0100_0000` | 4K | | ++--------------------+-------------------+---------------+------+-------+ +| 256K periphs @ Reg | Boot ROM | `0x0200_0000` | 256K | E | +| +-------------------+---------------+------+-------+ +| | CLINT | `0x0204_0000` | 256K | | +| +-------------------+---------------+------+-------+ +| | IRQ router | `0x0208_0000` | 256K | | ++--------------------+-------------------+---------------+------+-------+ +| 4K periphs @ Reg | SoC Regs | `0x0300_0000` | 4K | | +| +-------------------+---------------+------+-------+ +| | LLC (Cfg) | `0x0300_1000` | 4K | | +| +-------------------+---------------+------+-------+ +| | UART | `0x0300_2000` | 4K | | +| +-------------------+---------------+------+-------+ +| | I2C | `0x0300_3000` | 4K | | +| +-------------------+---------------+------+-------+ +| | SPI Host | `0x0300_4000` | 4K | | +| +-------------------+---------------+------+-------+ +| | GPIO | `0x0300_5000` | 4K | | +| +-------------------+---------------+------+-------+ +| | Serial Link (Cfg) | `0x0300_6000` | 4K | | +| +-------------------+---------------+------+-------+ +| | VGA (Cfg) | `0x0300_7000` | 4K | | +| +-------------------+---------------+------+-------+ +| | AXI RT (Cfg) | `0x0300_8000` | 4K | | +| +-------------------+---------------+------+-------+ +| | UNBENT | `0x0300_9000` | 4K | | ++--------------------+-------------------+---------------+------+-------+ +| INTCs @ Reg | PLIC | `0x0400_0000` | 64M | | +| +-------------------+---------------+------+-------+ +| | CLICs | `0x0800_0000` | 64M | | ++--------------------+-------------------+---------------+------+-------+ +| LLC SPM @ AXI | cached | `0x1000_0000` | 64M | CIE | +| +-------------------+---------------+------+-------+ +| | uncached | `0x1400_0000` | 64M | IE | ++--------------------+-------------------+---------------+------+-------+ +The flags are defined as follows: -## Memory Map +- **C***acheable*: Accessed data may be cached in the L1 or LLC caches +- **I***dempotent*: Multiple identical or composing accesses are equivalent to one access +- **E***xecutable*: Data in this region may be executed. -Cheshire's internal memory map is *static*. While device instantiation and layout may vary, each device is provided an address space of *fixed* location and size. For this, Cheshire *reserves* the address space from `0x0` to `0x2000_0000`, which is currently allocated as follows: +Additionally, Cheshire assumes the following parameterized layout for external resources: -+--------------------+-------------------+-------------+------+-------+ -| Block | Device | Start | Size | Flags | -+====================+===================+=============+======+=======+ -| 256K periphs @ AXI | Debug ROM | 0x0000_0000 | 256K | E | -+--------------------+-------------------+-------------+------+-------+ -| 4K periphs @ AXI | AXI DMA (Cfg) | 0x0100_0000 | 4K | | -+--------------------+-------------------+-------------+------+-------+ -| 256K periphs @ Reg | Boot ROM | 0x0200_0000 | 256K | E | -| +-------------------+-------------+------+-------+ -| | CLINT | 0x0204_0000 | 256K | | -| +-------------------+-------------+------+-------+ -| | IRQ router | 0x0208_0000 | 256K | | -+--------------------+-------------------+-------------+------+-------+ -| 4K periphs @ Reg | SoC Regs | 0x0300_0000 | 4K | | -| +-------------------+-------------+------+-------+ -| | LLC (Cfg) | 0x0300_1000 | 4K | | -| +-------------------+-------------+------+-------+ -| | UART | 0x0300_2000 | 4K | | -| +-------------------+-------------+------+-------+ -| | I2C | 0x0300_3000 | 4K | | -| +-------------------+-------------+------+-------+ -| | SPI Host | 0x0300_4000 | 4K | | -| +-------------------+-------------+------+-------+ -| | GPIO | 0x0300_5000 | 4K | | -| +-------------------+-------------+------+-------+ -| | Serial Link (Cfg) | 0x0300_6000 | 4K | | -| +-------------------+-------------+------+-------+ -| | VGA (Cfg) | 0x0300_7000 | 4K | | -| +-------------------+-------------+------+-------+ -| | AXI RT (Cfg) | 0x0300_8000 | 4K | | -+--------------------+-------------------+-------------+------+-------+ -| INTCs @ Reg | PLIC | 0x0400_0000 | 64M | | -| +-------------------+-------------+------+-------+ -| | CLICs | 0x0800_0000 | 64M | | -+--------------------+-------------------+-------------+------+-------+ -| SPM @ AXI | cached | 0x1000_0000 | 64M | CIE | -| +-------------------+-------------+------+-------+ -| | uncached | 0x1400_0000 | 64M | IE | -+--------------------+-------------------+-------------+------+-------+ +| Block | Start | End | Flags | +| ------------------ | ------------------- | ----------------- | -------- | +| External on-chip | `0x2000_0000` | `0x8000_0000` | (Param.) | +| LLC out (DRAM) | `LlcOutRegionStart` | `LlcOutRegionEnd` | CIE | +| Serial Link | `SlinkRegionStart` | `SlinkRegionEnd` | | -The flags are defined as follows: +The *external on-chip* region is split into one subregion with full `CIE` flags and one without flags to minimize parameterization complexity. The `Cva6ExtCieOnTop` and `Cva6ExtCieLength` parameters control the order and partitioning of these two regions, respectively. + +The *LLC out* region must not collide with any other regions and defaults on starting at the lowest available address, `0x8000_0000`. The *Serial Link* region defaults on starting at `0x1_0000_0000`, configuring the `SlinkTxAddrMask` and `SlinkTxAddrDomain` parameters to mirror the lower 32-bit space of another identical chip from this address base. + + +## Components and Parameters + +Except for external hart debug info and interface types (see [Instantiating Cheshire](../tg/integr.md#instantiating-cheshire)), Cheshire is fully parameterized through its `Cfg` struct parameter. We will first describe global parameters, then discuss the functionality and parameterization of each component individually. + +For defaults of any parameters, `cheshire_pkg::DefaultCfg` is the *single source of truth*. Note, however, that this does *not* mean `DefaultCfg` parameters are suitable for your system or usecase; please carefully consider and choose all parameters in your instantiation. + +The following global parameters control basic functionality and features and can be read by software in the *SoC Registers*: + +| Parameter | Type / Range | Description | +| ------------- | ------------ | -------------------------------------------------- | +| `RtcFreq` | `word_bt` | Frequency (Hz) configured for real-time clock | +| `PlatformRom` | `word_bt` | Address of platform ROM; see [Boot ROM](#boot-rom) | +| `Bootrom` | `bit` | Whether boot ROM is available | +| `Uart` | `bit` | Whether UART is available | +| `I2c` | `bit` | Whether I2C host is available | +| `SpiHost` | `bit` | Whether SPI is available | +| `Gpio` | `bit` | Whether GPIO is available | +| `Dma` | `bit` | Whether DMA is available | +| `SerialLink` | `bit` | Whether serial link is available | +| `Vga` | `bit` | Whether VGA is available | +| `AxiRt` | `bit` | Whether AXI RT is available | +| `Clic` | `bit` | Whether CLIC is available | +| `IrqRouter` | `bit` | Whether IRQ Router is available | +| `BusErr` | `bit` | Whether UNBENT (bus error unit) is available | + +### CVA6 Cores + +Cheshire defaults on using CVA6 with hypervisor and CLIC support enabled; RV32 configurations are *not* supported. Most parameters for the CVA6 cores are derived from Cheshire's configuration or immutable. The available core parameters are listed below: + +| Parameter | Type / Range | Description | +| ---------------------------- | ------------ | ----------------------------------------------- | +| `NumCores` | `1..31` | Number of instantiated CVA6 cores | +| `Cva6RASDepth` | `shrt_bt` | Depth of CVA6 return address stack (RAS) | +| `Cva6(BTB|BHT|NrPMP)Entries` | `shrt_bt` | Number of BTB, BHT, and PMP entries in CVA6 | +| `Cva6ExtCieLength` | `doub_bt` | CIE subregion length in external on-chip region | +| `Cva6ExtCieOnTop` | `bit` | Whether CIE subregion is on top or bottom | +| `CoreMaxTxns` | `dw_bt` | Maximum total AXI4 transactions per core | +| `CoreMaxTxnsPerId` | `dw_bt` | Maximum total AXI4 transactions per core and ID | +| `CoreUserAmoOffs` | `doub_bt` | Base offset for core IDs within user AMO range | + +Each CVA6 core is a standalone AXI4 manager at the crossbar. Coherence is maintained through a self-invalidation scheme and RISC-V atomics are handled through a custom, user-channel-based AXI4 extension. For the latter, we wrap the cores and other managers to give each a default user channel assignment and, for atomics-capable managers, a unique ID on a slice of user bits. + +### Interconnect + +The interconnect is composed of a main [AXI4](https://github.com/pulp-platform/axi) crossbar with AXI5 atomic operations (ATOPs) support and an auxiliary [Regbus](https://github.com/pulp-platform/register_interface) demultiplexer providing access to numerous peripherals and configuration interfaces. The Regbus has a static data width of 32 bit. + +As the Regbus protocol is not capable of bursts, parallel read and writes, or pipelining, it is much less performant than AXI4, but also much cheaper to implement. Thus, our approach of hierarchically combining AXI4 and Regbus significantly improves interconnect scaling. + +The internal interconnect exposes the following parameters: + +| Parameter | Type / Range | Description | +| --------------------------- | ------------ | ----------------------------------------------- | +| `AddrWidth` | `32..64` | AXI4 and Regbus address width | +| `Axi(Data|User|MstId)Width` | `shrt_bt` | AXI4 data, user, and manager ID width | +| `AxiMax(Mst|Slv)Trans` | `shrt_bt` | AXI4 maximum inflight transactions at crossbar | +| `AxiUserDefault` | `doub_bt` | AXI4 default user value amended by user features | +| `AxiUserAmo(Msb|Lsb)` | `dw_bt` | AXI4 user channel bit-range used by RISC-V AMOs | +| `RegMax(Read|Write)Txns` | `dw_bt` | Max. inflight transactions at Regbus AMO filter | +| `RegAmoNumCuts` | `aw_bt` | Number of timing cuts inside Regbus AMO filter | +| `RegAmoPostCut` | `bit` | Whether to insert a cut after Regbus AMO filter | +| `(Axi|Reg)ExtNum(Mst|Slv)` | `0..15` | AXI4 and Regbus number of external Mgrs. or Subs. | +| `(Axi|Reg)ExtNumRules` | `0..15` | AXI4 and Regbus number of external address rules | +| `(Axi|Reg)ExtRegion*` | `doub_bt` | AXI4 and Regbus external address regions | +| `AxiRt*` | `word_bt` | AXI4 real-time traffic regulation parameters | + +Both the AXI4 and Regbus interconnects support exposing a limited number of external manager and subordinate ports; this is the intended mechanism through which Cheshire can be integrated with wrapping SoCs' memory systems. + +The parameters `AxiUserDefault` and `AxiUserAmo(Msb|Lsb)` define the AXI4 default user channel assignment and ID slice for atomics, respectively. + +The AXI4 interconnect has two optional features. `AxiRt` adds traffic regulation units to each AXI4 manager to provide bandwidth and traffic control for real-time applications. `BusErr` adds the UNBENT bus error reporter to all managers spawning requests and imprecisely reports AXI4 error responses through a Regbus-mapped interface. + +### Interrupts + +Cheshire provides a flexible RISC-V interrupt architecture that can route and multiplex internal and external interrupts to both internal and external controllers and targets. For simplicity, the internal interrupt map is static (non-existent interrupts being tied to 0), while the external interrupt map depends on the surrounding system. Interrupts expose the following parameters: + +| Parameter | Type / Range | Description | +| ------------------- | ------------ | ------------------------------------------------------ | +| `NumExtInIntrs` | `doub_bt` | Total number of external interrupt sources | +| `NumExtClicIntrs` | `shrt_bt` | Number of external interrupt sources allocated in CLIC | +| `ClicIntCtlBits` | `shrt_bt` | Number of interrupt control bits in CLIC | +| `NumExtOutIntrTgts` | `byte_bt` | Number of external interrupt targets | +| `NumExtOutIntrs` | `shrt_bt` | Number of sources for external interrupt targets | +| `NumExtIrqHarts` | `doub_bt` | Number of external interruptible harts | + +First, all internal (`intr.intn`) and external (`intr_ext_i`) interrupt sources are collected (`intr`). From here, they either pass through an *interrupt router* if enabled (`IrqRouter`) or are simply fanned out to interrupt *targets*, which may support as many or fewer interrupt sources as provided by `intr`. If a target supports fewer sources, its interrupt sources are *truncated*. + +Cheshire provides both a core-local interruptor (CLINT), grouping all per-core interrupts in one module, and a shared platform-level interrupt controller (PLIC). The former is used only for inter-processor and timer interrupts, while the latter is a proper interrupt target. If enabled (`Clic`), each CVA6 core also has a core-local interrupt controller (CLIC), another interrupt target. In addition to the PLIC and CLICs, any number external interrupt targets may be defined (`NumExtOutIntrTgts`) with their own number of incoming sources (`NumExtIrqHarts`). + +Finally, the PLIC and grouped CLINT also support allocating external harts for which to manage interrupts (`NumExtIrqHarts`), i.e. harts without interrupt controllers of themselves. + +### Debug Module + +Cheshire provides a RISC-V-compliant [Debug Module](https://github.com/pulp-platform/riscv-dbg) with JTAG transport. It supports debugging both internal and external harts as well as system bus access (SBA). It exposes the following parameters: + +| Parameter | Type / Range | Description | +| ------------------------- | ------------ | ------------------------------------------------ | +| `DbgIdCode` | `word_bt` | JTAG ID code reported by Debug module | +| `DbgMaxReqs` | `dw_bt` | Maximum outstanding requests to manager port | +| `DbgMax(Read|Write)Txns` | `dw_bt` | Maximum ourstanding requests to subordinate port | +| `DbgAmoNumCuts` | `aw_bt` | Number of timing cuts inside Debug AMO filter | +| `DbgAmoPostCut` | `bit` | Whether to insert a cut after Debug AMO filter | + +### Last Level Cache + +The [Last Level Cache](https://github.com/pulp-platform/axi_llc) (LLC) sits between Cheshire and its main memory (usually DRAM). It is assumed to be the only manager accessing this memory and caches all accesses to it unless explicitly bypassed through AXI cache control signals. It exposes the following parameters: + +| Parameter | Type / Range | Description | +| -------------------------- | ------------ | ------------------------------------------------- | +| `LlcOutConnect` | `bit` | Whether to create a manager port for the LLC | +| `LlcNotBypass` | `bit` | Whether to instantiate the LLC or create a bypass | +| `LlcOutRegion(Start|End)` | `doub_bt` | Mapped region of outgoing LLC manager port (DRAM) | +| `LlcSetAssoc` | `shrt_bt` | Number of sets in LLC | +| `LlcNum(Lines|Blocks)` | `shrt_bt` | Number of lines and blocks for LLC | +| `LlcMax(Read|Write)Txns` | `dw_bt` | Max. number of outstanding requests to LLC | +| `LlcAmoNumCuts` | `aw_bt` | Number of timing cuts inside manager AMO filter | +| `LlcAmoPostCut` | `bit ` | Whether to insert a cut after manager AMO filter | + +Each way of the LLC can individually be switched between caching and acting as a scratchpad memory (SPM). On initial boot, all ways are configured as SPM and the LLC does not cache any accesses; the SPM is used as a working memory for the boot ROM to enable autonomous bootstrapping from external memory. + +The LLC may be entirely omitted through `LlcNotBypass`, for example if a more elaborate external main memory system is used. In this case, an external substitute scratchpad memory is required *iff* Cheshire should boot and run bare-metal code from scratchpad memory as usual. If the LLC is omitted, its port remains *iff* `LlcOutConnect` is set, providing a manager port with a RISC-V atomics filter and the above parameters only. + +### VGA Controller + +The [VGA Controller](https://github.com/pulp-platform/axi_vga) enables the drawing of video frames in memory over a VGA interface. It autonomously fetches frame data using an AXI manager port. Note that it currently only supports whole-byte pixel formats. It exposes the following parameters: + +| Parameter | Type / Range | Description | +| -------------------------- | ------------ | ------------------------------------------------- | +| `Vga(Red|Green|Blue)Width` | `byte_bt` | Bit width of red, green, and blue output channels | +| `Vga(H|V)CountWidth` | `aw_bt` | Horizontal and vertical sync counter width | + +### Serial Link + +The [Serial Link](https://github.com/pulp-platform/serial_link) is a fully digital, double-data-rate (DDR) chip-to-chip or die-to-die interface serializing AXI4. It can be used to communicate with other SoCs using it, such as other Cheshire instances or FPGAs providing further peripheral or accelerator functionality. It exposes the following parameters: + +| Parameter | Type / Range | Description | +| ------------------------ | ------------ | ------------------------------------------------- | +| `SlinkMaxClkDiv` | `shrt_bt` | Max. system clock divider for DDR interface | +| `SlinkMaxTxnsPerId` | `dw_bt` | Max. number of inflight outgoing requests per ID | +| `SlinkMaxUniqIds` | `dw_bt` | Max. number of inflight IDs for outgoing requests | +| `SlinkRegion(Start|End)` | `doub_bt` | Address range for outgoing requests | +| `SlinkTxAddrMask` | `doub_bt` | Address mask to apply on incoming requests | +| `SlinkTxAddrDomain` | `doub_bt` | Address domain to cast incoming requests into | +| `SlinkUserAmoBit` | `dw_bt` | AXI4 AMO user bit to set on incoming requests | + +### DMA engine + +The [iDMA engine](https://github.com/pulp-platform/iDMA) enables high-throughput asynchronous transfers between any two subordinate address ranges in the system. It exposes the following parameters: + +| Parameter | Type / Range | Description | +| ---------------------------- | ------------ | ------------------------------------------------- | +| `DmaConfMax(Read|Write)Txns` | `dw_bt` | Max. number of outstanding requests to DMA config | +| `DmaConfAmoNumCuts` | `aw_bt` | Number of timing cuts inside config AMO filter | +| `DmaConfAmoPostCut` | `bit` | Whether to insert a cut after config AMO filter | + +### I2C, SPI, GPIOs + +The I2C host, SPI host, and GPIO interface are IPs provided by [OpenTitan](https://github.com/lowRISC/opentitan) and adapted for use in PULP systems. They remain compatible with and use OpenTitan's device interface functions (DIFs) with minor patches. For more information on these peripherals, please consult the [OpenTitan IP Block Documentation](https://opentitan.org/book/hw/ip/index.html). These peripherals expose the following parameters: + +| Parameter | Type / Range | Description | +| ------------------------ | ------------ | -------------------------------------------------- | +| `GpioInputSyncs` | `bit` | Whether to add two-FF synchronizers to GPIO inputs | + +### UART + +Cheshire's [UART](https://github.com/pulp-platform/apb_uart) is compatible with the TI 16750. Thus, it is compatible with OpenSBI, U-Boot, and Linux out of the box. Note that Cheshire exposes the interface's *modem access control* for systems that wish to use it; if you do not, be sure to *correctly* tie off these signals. -* **C***acheable*: accessed data may be cached in the L1 or LLC caches -* **I***dempotent*: -* **E***xecutable*: +### Boot ROM -+--------------------+-------------------+-------------+------+-------+ -| External | CIE | 0x2000_0000 | 512M | CIE | -| +-------------------+-------------+------+-------+ -| | non-CIE | 0x4000_0000 | 1G | | -+--------------------+-------------------+-------------+------+-------+ -| LLC out (DRAM) | | 0x8000_0000 | | CIE | -+--------------------+-------------------+-------------+------+-------+ +The boot ROM contains the first code executed by Cheshire's internal cores after reset. It serves to load a mutable program from an external source in a safe, swift, and verifiable fashion. It deserves particular attention because when implemented in unchangeable hardware, boot ROM bugs may seriously impact or altogether destroy the functionality of silicon implementations. For more information on Cheshire's built-in boot ROM, see the [Boot ROM](sw.md#boot-rom) section in the [Software Stack](sw.md) chapter. -## Boot ROM +The boot ROM can optionally invoke a [Platform ROM](../tg/integr.md#platform-rom) before code loading to set up essential features of the surrounding system; this is done *iff* the platform ROM address parameter (`PlatformRom`) is nonzero. If the boot ROM is not instantiated (`BootRom`), the internal cores will attempt to boot directly from the configured Platform ROM instead. diff --git a/docs/um/index.md b/docs/um/index.md index ff2daf1e8..da1dc7f50 100644 --- a/docs/um/index.md +++ b/docs/um/index.md @@ -1 +1,6 @@ # User Manual + +The *user manual* provides detailed reference information on Cheshire: + +- [Architecture](arch.md): Describes the hardware design, features, and configuration of Cheshire. +- [Software Stack](sw.md): Describes how to run code on Cheshire and its Linux boot flow. diff --git a/docs/um/sw.md b/docs/um/sw.md index 8f3b29f0b..671f4765f 100644 --- a/docs/um/sw.md +++ b/docs/um/sw.md @@ -1,8 +1,110 @@ -# Software +# Software Stack + +Cheshire's software stack currently provides: + +- A baremetal programming environment and hardware abstraction layer. +- A zero-stage bootloader (ZSL) and Linux boot chain. +- A CVA6 Linux with additional drivers and patches. + +## Baremetal programs + +Baremetal programs (BMPs) may be preloaded and invoked either by the boot ROM (see [Boot Flow](#boot-flow)) or through the RISC-V [Debug Module](arch.md#debug-module) interfaced through JTAG. They run directly in M mode. With the provided setup, BMPs can be linked to execute either from the internal scratchpad memory (SPM) or from DRAM. + +The toolchain in `sw` can be used to build custom BMPs; the programs in `sw/tests` and `sw/boot` may serve as references. BMPs are linked against `libcheshire` (`sw/lib` and `sw/include`), which provides a hardware abstraction layer (HAL) and a minimal C runtime. + +The C runtime calls `int main(void)` and forwards traps to the weakly-defined handler `void trap_vector(void)`, which may be left undefined if trap handling is not needed. + +On program termination, bit 0 of scratch register 2 (`scratch[2][0]`) is set to 1 and the return value of `main()` is written to `scratch[2][31:1]`. Furthermore, when preloading through UART, the return value is sent out by the UART debug server (see [Passive Preload](#passive-preload)). In simulation, the testbench catches the return value and terminates the simulator, whose exit code will be nonzero *iff* the return value is. + +To build a baremetal program (here `sw/tests/helloworld.c`) executing from the SPM, run: + +``` +make sw/tests/helloworld.spm.elf +``` + +To create the same program executing from DRAM, `sw/tests/helloworld.spm.dram` can instead be built from the same source. Depending on their assumptions and behavior, not all programs may be built to execute from both locations. ## Boot Flow -## Linux +On reset, Cheshire immediately starts execution and initializes a minimal C execution environment for the boot ROM by: + +1. Resetting all integer registers (the FPU is disabled). +2. Pausing all nonzero harts. +3. Completing the LLC's self test (if present) and switching it to SPM. +4. Invoking the [Platform ROM](../tg/integr.md#platform-rom) (if present). + +### Boot ROM + +The boot ROM is implemented in *hardware* and therefore *immutable*. To guarantee verifiability and prevent silicon bricks, it provides only a handful redundant boot modes loading just enough code to run another *mutable* program or loader. It aims to do this in minimal time and without accessing unnecessary interfaces. + +The boot ROM supports four builtin boot modes chosen from by the `boot_mode_i` pins: + +| `boot_mode_i[1:0]` | Boot Medium | Interface Used | +| ------------------- | --------------------- | -------------------------- | +| `0b00` | Passive Preload | JTAG, Serial Link, or UART | +| `0b01` | SD Card | SPI | +| `0b10` | NOR Flash (S25FS512S) | SPI | +| `0b10` | EEPROM (24FC1025) | I2C | + + +#### Passive Preload + +The *passive preload* boot mode expects code to be preloaded to an executable location and an entry point to be written to `scratch[1:0]`. After preloading, execution is launched when `scratch[2][0]` is set to 1. Unlike for autonomous boot modes, BMPs can directly be preloaded into DRAM and have no size restriction. + +The JTAG and serial link interfaces can preload programs by directly accessing the memory system. Preloading through UART is special, as UART by itself does not provide a memory access protocol. On receiving an `ACK` (`0x06`) byte over UART, the boot ROM launches a *debug server* that waits for and handles the following commands: + +| TX Opcode | TX Arguments | Command Sequence | +| -------------- | ----------------------- | ----------------------------------------- | +| `0x11` (Read) | 64b address, 64b length | RX `ACK`, RX read data, RX `EOT` | +| `0x12` (Write) | 64b address, 64b length | RX `ACK`, TX write data, RX `EOT` | +| `0x13` (Exec) | 64b address | RX `ACK`, execution, RX `ACK`, RX return | -## Baremetal programming +#### Autonomous Boot + +The *autonomous* boot modes load a BMP of at most 48 KiB from their boot medium into SPM, then execute it. The boot medium can either be GPT-formatted or contain raw code. If no GPT header is found, raw code execution starts from sector 0 of the boot medium. + +If the boot medium is GPT-formatted, the boot ROM will search for and preload the first partition under 48 KiB in size that is formatted as a *Cheshire zero-stage loader* (see [Partition GUIDs](#partition-guids)). If no such partition is found, the boot ROM will fall back to booting from the beginning of the boot medium's first partition. + +BMPs that run from SPM and fit into the alotted size can be compiled into raw images (ROMs) or GPT disk images as follows: + +``` +make sw/tests/helloworld.(rom|gpt).(bin|memh) +``` + +The boot ROM is *not* reentrant; when an invoked BMP returns, the system will halt and not reboot. + +### Zero-Stage Loader + +The zero-stage loader (ZSL) is a simple BMP running from SPM that is responsible for chain-loading the OpenSBI firmware, which will take over and manage M mode. The OpenSBI image bundles the U-Boot bootlader as its payload, which will chain-load and invoke Linux. + +Unlike the boot ROM, the ZSL is fully *mutable*. Thus, there is no danger to preloading large amounts of data, printing large messages, or accessing DRAM, as any potential bugs cannot brick silicon. The ZSL: + +1. Prints a first UART output listing essential boot parameters. +2. Loads the *device tree* from the boot medium into DRAM, reusing boot ROM drivers. +3. Loads the *firmware* from the boot medium into DRAM, reusing boot ROM drivers. +4. Invokes the *firmware*, passing the *device tree* as an argument. + +Note that when using preloading boot modes, steps 2 and 3 are skipped as the device tree and firmware are assumed to also be preloaded. If the ZSL is autonomously booted, both are loaded from the first partitions of corresponding type on the boot medium (see [Partition GUIDs](#partition-guids)). + +### Firmware + +OpenSBI takes over M mode and invokes the bundled U-Boot bootloader. U-Boot's behavior is defined by the passed device tree and its default boot command (both target-dependent), but can also dynamically be changed through its command line. + +Both OpenSBI and U-Boot, provided through a fork of the [CVA6 SDK](https://github.com/pulp-platform/cva6-sdk/tree/cheshire), are largely unchanged from their upstream code bases. U-Boot is patched with a driver for Cheshire's SPI host. Non-SPI loading is currently not implemented, but can be added. Alternatively, the ZSL can be modified to directly load the Linux image to invoke into DRAM. + +### Partition GUIDs + +For boot purposes, Cheshire defines the following partition type GUIDs: + +| Partition Type | Type GUID | +| ----------------- | -------------------------------------- | +| Zero-Stage Loader | `0269B26A-FD95-4CE4-98CF-941401412C62` | +| Device Tree | `BA442F61-2AEF-42DE-9233-E4D75D3ACB9D` | +| Firmware | `99EC86DA-3F5B-4B0D-8F4B-C4BACFA5F859` | + +In a Linux context, Cheshire adheres to established partition type GUIDs. + +## Linux + +Cheshire runs a slightly modified version of CVA6 Linux from the [CVA6 SDK](https://github.com/pulp-platform/cva6-sdk/tree/cheshire). Currently, it adds drivers for our SPI host to enable persistent disk IO, for example on SD cards. We plan on extending Linux driver support for Cheshire's hardware in the future. diff --git a/hw/regs/cheshire_regs.hjson b/hw/regs/cheshire_regs.hjson index f8af0f925..e551a9451 100644 --- a/hw/regs/cheshire_regs.hjson +++ b/hw/regs/cheshire_regs.hjson @@ -94,7 +94,7 @@ { bits: "2", name: "uart", desc: "Whether UART is available" } { bits: "3", name: "spi_host", desc: "Whether SPI host is available" } { bits: "4", name: "i2c", desc: "Whether I2C is available" } - { bits: "5", name: "gpio", desc: "Whether I2C is available" } + { bits: "5", name: "gpio", desc: "Whether GPIO is available" } { bits: "6", name: "dma", desc: "Whether DMA is available" } { bits: "7", name: "serial_link", desc: "Whether serial link is available" } { bits: "8", name: "vga", desc: "Whether VGA is available" } diff --git a/mkdocs.yml b/mkdocs.yml index b12cf4e5b..247af2275 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,7 +16,7 @@ theme: markdown_extensions: - toc: - toc_depth: 2 + toc_depth: 3 - markdown_grid_tables: - pymdownx.superfences: custom_fences: