Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 1 | --- |
| 2 | title: "Writing and building software for OTBN" |
| 3 | --- |
| 4 | |
| 5 | OTBN is the OpenTitan Big Number accelerator and this document describes how to write and build software for it. |
| 6 | The [OTBN reference manual]({{< relref "hw/ip/otbn/doc" >}}) describes the hardware and associated ISA. |
| 7 | |
| 8 | Since OTBN is designed for cryptographic offload, not general computation, it has no C compiler. |
| 9 | However, it does have the usual binutils programs: an assembler, linker and disassembler. |
| 10 | The core of OTBN's instruction set is based on RV32I, the RISC-V base integer instruction set. |
| 11 | As such, we implement the toolchain as a thin wrapper around RISC-V binutils. |
| 12 | |
Philipp Wagner | c120b18 | 2020-09-17 11:53:03 +0100 | [diff] [blame] | 13 | ## Assembly format and examples |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 14 | |
| 15 | The OTBN ISA and programmer model are described in the [OTBN reference manual]({{< relref "hw/ip/otbn/doc" >}}). |
| 16 | In particular, note that the register `x1` has special stack-like behaviour. |
Philipp Wagner | 0f643e1 | 2020-08-17 16:50:05 +0100 | [diff] [blame] | 17 | There are some example programs at `sw/otbn/code-snippets`. |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 18 | These range from simple examples of how to use pseudo-operations up to example cryptographic primitives. |
| 19 | |
Philipp Wagner | c120b18 | 2020-09-17 11:53:03 +0100 | [diff] [blame] | 20 | ## The tools |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 21 | |
Philipp Wagner | c120b18 | 2020-09-17 11:53:03 +0100 | [diff] [blame] | 22 | ### Assembler |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 23 | |
| 24 | The OTBN assembler is called `otbn-as` and can be found at `hw/ip/otbn/util/otbn-as`. |
| 25 | This has the same command line interface as `riscv32-unknown-elf-as` (indeed, it's a wrapper around that program). |
| 26 | The only difference in default flags is that `otbn-as` passes `-mno-relax`, telling the assembler not to request linker relaxation. |
| 27 | This is needed because one of these relaxations generates GP-relative loads, which assume `x3` is treated as a global pointer (not true for OTBN code). |
| 28 | |
Philipp Wagner | b5b8c7f | 2020-10-27 10:44:27 +0000 | [diff] [blame] | 29 | To assemble some code in `foo.s` to an ELF object called `foo.o`, run: |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 30 | ```shell |
Philipp Wagner | b5b8c7f | 2020-10-27 10:44:27 +0000 | [diff] [blame] | 31 | hw/ip/otbn/util/otbn-as -o foo.o foo.s |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 32 | ``` |
| 33 | |
Philipp Wagner | c120b18 | 2020-09-17 11:53:03 +0100 | [diff] [blame] | 34 | ### Linker |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 35 | |
| 36 | The OTBN linker is called `otbn-ld` and can be found at `hw/ip/otbn/util/otbn-ld`. |
| 37 | This is a thin wrapper around `riscv32-unknown-elf-ld`, but supplies a default linker script that matches the OTBN memory layout. |
| 38 | This linker script creates a `.text` and a `.data` section. |
| 39 | Since OTBN has a strict Harvard architecture (instructions and data both starting at address zero), the linker script places them both at VMA zero. |
| 40 | The instruction and data segments have distinct LMAs (for addresses, see the IMEM and DMEM windows at `hw/ip/otbn/data/otbn.hjson`). |
| 41 | |
| 42 | To link ELF object files to an OTBN ELF binary, run |
| 43 | ```shell |
| 44 | hw/ip/otbn/util/otbn-ld -o foo foo0.o foo1.o foo2.o |
| 45 | ``` |
| 46 | |
Philipp Wagner | c120b18 | 2020-09-17 11:53:03 +0100 | [diff] [blame] | 47 | ### Objdump |
Rupert Swarbrick | 9a47a36 | 2020-08-07 12:23:23 +0100 | [diff] [blame] | 48 | |
| 49 | To disassemble OTBN code, use `otbn-objdump`, which can be found at `hw/ip/otbn/util/otbn-objdump`. |
| 50 | This wraps `riscv32-unknown-elf-objdump`, but correctly disassembles OTBN instructions when run with the `-d` flag. |
| 51 | |
| 52 | To disassemble the ELF binary linked in the previous section, run |
| 53 | ```shell |
| 54 | hw/ip/otbn/util/otbn-objdump -d foo |
| 55 | ``` |