Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for DMA, MBX and SoCProxy #51

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a93b85b
[ot] scripts/opentitan: pyot.py: use abspath rather than normpath
rivos-eblot Nov 30, 2023
3327cd2
[ot] scripts/opentitan: pyot.py: add an optional summary table
rivos-eblot Nov 30, 2023
575a3fc
[ot] scripts/opentitan: pyot.py: add a timeout multiplier
rivos-eblot Dec 4, 2023
47d1a90
[ot] scripts/opentitan: pyot.py: add variables in test context
rivos-eblot Dec 4, 2023
28170f4
[ot] scripts/opentitan: pyot.py: handle errors from context tools
rivos-eblot Dec 5, 2023
eadb410
[ot] scripts/opentitan: pyot.py: add support for conditional test lists.
rivos-eblot Dec 5, 2023
96ac239
[ot] scripts/opentitan: pyot.py: simplify executable paths
rivos-eblot Dec 5, 2023
cea0b0e
[ot] hw/riscv: ot_darjeeling: add MBX support
rivos-eblot Dec 5, 2023
230321f
[ot] hw/riscv: ot_darjeeling: add dev proxy support
rivos-eblot Dec 5, 2023
5faf46f
[ot] scripts/opentitan: devproxy.py: add device and memory enumerators
rivos-eblot Dec 6, 2023
6e8eb80
[ot] hw/riscv: ot_darjeeling: add DMA support
rivos-eblot Dec 5, 2023
f06605a
[ot] hw/opentitan: ot_random_src: remove invalid imported comment
rivos-eblot Nov 14, 2023
3b91ddf
[ot] hw/riscv: apply IBEX resetvec/mtvec constraints to ibex_load_kernel
rivos-eblot Dec 6, 2023
169d07b
[ot] hw/riscv: clean up type_init syntax
rivos-eblot Nov 15, 2023
f78c4a2
[ot] hw/opentitan: clean up type_init syntax
rivos-eblot Nov 15, 2023
1445a6d
[ot] hw/riscv: ibex_common: improve support for remote device links
rivos-eblot Nov 15, 2023
f8e7a79
[ot] hw/opentitan: add initial SocProxy device implementation
rivos-eblot Dec 4, 2023
3eb23af
[ot] hw/riscv: add SocProxy device to Darjeeling machine
rivos-eblot Dec 4, 2023
a0f5d37
[ot] hw/opentitan: add SocProxy to DevProxy managed devices
rivos-eblot Dec 4, 2023
72c5fa9
[ot] target/riscv: pmp: add more details to guest errors traces
loiclefort Dec 6, 2023
a98c7d6
[ot] target/riscv: pmp: exit csr writes early if value was not changed
loiclefort Dec 6, 2023
b4ec5c6
[ot] disas: Split Zbr extension into its own file
rbradford Dec 6, 2023
4b7bf88
[ot] hw/opentitan: devproxy: add a new feature to remotely trigger IRQs
rivos-eblot Dec 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion disas/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
'riscv.c',
'riscv-xthead.c',
'riscv-xventana.c'
'riscv-xventana.c',
'riscv-zbr.c'
))
common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
Expand Down
76 changes: 76 additions & 0 deletions disas/riscv-zbr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* QEMU RISC-V Disassembler for Zbr
*
* Copyright (c) 2023 Rivos Inc
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "disas/riscv.h"
#include "disas/riscv-zbr.h"

typedef enum {
/* 0 is reserved for rv_op_illegal. */
rv_op_crc32_b = 1,
rv_op_crc32_h = 2,
rv_op_crc32_w = 3,
rv_op_crc32_d = 4,
rv_op_crc32c_b = 5,
rv_op_crc32c_h = 6,
rv_op_crc32c_w = 7,
rv_op_crc32c_d = 8,
} rv_zbr_op;

const rv_opcode_data rv_zbr_opcode_data[] = {
{ "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
{ "crc32.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
};

void decode_zbr(rv_decode *dec, rv_isa isa)
{
rv_inst inst = dec->inst;
rv_opcode op = rv_op_illegal;

switch ((inst >> 0) & 0b1111111) {
case 0b0010011:
switch ((inst >> 12) & 0b111) {
case 0b001:
switch ((inst >> 20 & 0b111111111111)) {
case 0b011000010000:
op = rv_op_crc32_b;
break;
case 0b011000010001:
op = rv_op_crc32_h;
break;
case 0b011000010010:
op = rv_op_crc32_w;
break;
case 0b011000010011:
op = rv_op_crc32_d;
break;
case 0b011000011000:
op = rv_op_crc32c_b;
break;
case 0b011000011001:
op = rv_op_crc32c_h;
break;
case 0b011000011010:
op = rv_op_crc32c_w;
break;
case 0b011000011011:
op = rv_op_crc32c_d;
break;
}
break;
}
break;
}
dec->op = op;
}
18 changes: 18 additions & 0 deletions disas/riscv-zbr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* QEMU RISC-V Disassembler for Zbr
*
* Copyright (c) 2023 Rivos Inc
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef DISAS_RISCV_ZBR_H
#define DISAS_RISCV_ZBR_H

#include "disas/riscv.h"

extern const rv_opcode_data rv_zbr_opcode_data[];

void decode_zbr(rv_decode *, rv_isa);

#endif /* DISAS_RISCV_ZBR_H */
28 changes: 6 additions & 22 deletions disas/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "disas/riscv-xthead.h"
#include "disas/riscv-xventana.h"

/* Extensions that are not yet upstream */
#include "disas/riscv-zbr.h"

typedef enum {
/* 0 is reserved for rv_op_illegal. */
rv_op_lui = 1,
Expand Down Expand Up @@ -862,14 +865,6 @@ typedef enum {
rv_op_fltq_q = 831,
rv_op_fleq_h = 832,
rv_op_fltq_h = 833,
rv_op_crc32_b = 834,
rv_op_crc32_h = 835,
rv_op_crc32_w = 836,
rv_op_crc32_d = 837,
rv_op_crc32c_b = 838,
rv_op_crc32c_h = 839,
rv_op_crc32c_w = 840,
rv_op_crc32c_d = 841,
} rv_op;

/* register names */
Expand Down Expand Up @@ -2016,14 +2011,6 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "fltq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
{ "fleq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
{ "fltq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
{ "crc32.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.w", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "crc32c.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }
};

/* CSR names */
Expand Down Expand Up @@ -2620,12 +2607,6 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
/* 0b0000011 */
case 0b0000100: op = rv_op_sext_b; break;
case 0b0000101: op = rv_op_sext_h; break;
case 0b0010000: op = rv_op_crc32_b; break;
case 0b0010001: op = rv_op_crc32_h; break;
case 0b0010010: op = rv_op_crc32_w; break;
case 0b0011000: op = rv_op_crc32c_b; break;
case 0b0011001: op = rv_op_crc32c_h; break;
case 0b0011010: op = rv_op_crc32c_w; break;
}
break;
}
Expand Down Expand Up @@ -5004,6 +4985,9 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
{ has_xtheadmempair_p, xthead_opcode_data, decode_xtheadmempair },
{ has_xtheadsync_p, xthead_opcode_data, decode_xtheadsync },
{ has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },

/* Instructions that are not yet upstream */
{ has_zbr_p, rv_zbr_opcode_data, decode_zbr },
};

for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
Expand Down
113 changes: 111 additions & 2 deletions docs/opentitan/devproxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,6 @@ This is the last command, as QEMU should exit upon receiving this request.

Route one or more device output interrupt to the proxy (vs. the internal PLIC)

* `Role` is the initiator role to use to access the device
* `Device` is the device to access (see [Enumerate](#enumerate-devices))
* `Interrupt mask` define which interrupt should be routed (1 bit per interrupt)

Expand Down Expand Up @@ -819,7 +818,6 @@ Route one or more device output interrupt to the proxy (vs. the internal PLIC)
Revert any previous interception, reconnecting selected IRQ to their original
destination device.

* `Role` is the initiator role to use to access the device
* `Device` is the device to access (see [Enumerate](#enumerate-devices))
* `Interrupt mask` define which interrupt should be released (1 bit per interrupt)

Expand Down Expand Up @@ -851,6 +849,117 @@ destination device.
+---------------+---------------+---------------+---------------+
```

#### Signal Interrupt [signal-interrupt]

Set or Reset an input interrupt line.

* `Device` is the device to access (see [Enumerate](#enumerate-devices))
* `GID` the identifier of the IRQ group.
* The group identifier can be retrieved using the [Enumerate Device Interrupt](#enumerate-irq)
API.
* `Interrupt line` the number of the interrupt line to signal within the group. The interrupt line
should range between 0 and the input IRQ count for this group.
* `Level` the new interrupt line level. Usually `1` to assert/set (1) or `0` to deassert/release,
even if any 32-bit value is accepted.

##### Request
```
+---------------+---------------+---------------+---------------+
| 0 | 1 | 2 | 3 |
|0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F|
+---------------+---------------+---------------+---------------+
| 'IS' | 12 |
+---------------+---------------+---------------+---------------+
| UID |0|
+---------------+---------------+---------------+---------------+
| GID | Device | - |
+---------------+---------------+---------------+---------------+
| Interrupt line | - |
+---------------+---------------+---------------+---------------+
| Level |
+---------------+---------------+---------------+---------------+
```

##### Response
```
+---------------+---------------+---------------+---------------+
| 0 | 1 | 2 | 3 |
|0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F|
+---------------+---------------+---------------+---------------+
| 'is' | 0 |
+---------------+---------------+---------------+---------------+
| UID |0|
+---------------+---------------+---------------+---------------+
```

#### Enumerate Device Interrupt [enumerate-irq]

Enumerate can be called by the Application to retrieve the list of interrupt
group of a supported device. The group position in the response can be further
use with the [Signal Interrupt API](#signal-interrupt) to set the level of
each individual IRQ line.

##### Request
```
+---------------+---------------+---------------+---------------+
| 0 | 1 | 2 | 3 |
+---------------+---------------+---------------+---------------+
|0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F|
+---------------+---------------+---------------+---------------+
| 'IE' | 4 |
+---------------+---------------+---------------+---------------+
| UID |0|
+---------------+---------------+---------------+---------------+
| - | Device | - |
+---------------+---------------+---------------+---------------+
```

##### Response
```
+---------------+---------------+---------------+---------------+
| 0 | 1 | 2 | 3 |
+---------------+---------------+---------------+---------------+
|0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F|
+---------------+---------------+---------------+---------------+
| 'ie' | 0..20N |
+---------------+---------------+---------------+---------------+
| UID |0|
+---------------+---------------+---------------+---------------+
| IRQ input count | IRQ output count |
+---------------+---------------+---------------+---------------+
| |
| |
| Identifier |
| |
| |
+---------------+---------------+---------------+---------------+
| IRQ input count | IRQ output count |
+---------------+---------------+---------------+---------------+
| |
| |
| Identifier |
| |
| |
+---------------+---------------+---------------+---------------+
| .... |
+---------------+---------------+---------------+---------------+
| IRQ input count | IRQ output count |
+---------------+---------------+---------------+---------------+
| |
| |
| Identifier |
| |
| |
+---------------+---------------+---------------+---------------+
```
Reponse contains 0 up to N interrupt groups, each group is described with a 20-byte entry, where:

* `IRQ input count` is the count of the input interrupts for this group,
* `IRQ output count` is the count of the output interrupts for this group,
* `Identifier` is an arbitrary 16-character string that describes this group.

The count of address spaces can be retrieved from the `LENGTH` field.

#### Intercept arbitrary MMIO region

It is possible to get intercept access to a memory region. Any intercepted region cannot
Expand Down
22 changes: 19 additions & 3 deletions docs/opentitan/pyot.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Usage

````text
usage: pyot.py [-h] [-c JSON] [-w CSV] [-k SECONDS] [-v] [-d] [-q QEMU]
usage: pyot.py [-h] [-c JSON] [-w CSV] [-R] [-k SECONDS] [-v] [-d] [-q QEMU]
[-Q OPTS] [-m MACHINE] [-p DEVICE] [-L LOG_FILE] [-M LOG]
[-t TRACE] [-i N] [-r ELF] [-O RAW] [-o VMEM] [-f RAW] [-x file]
[-b file]
Expand All @@ -17,6 +17,7 @@ options:
-c JSON, --config JSON
path to configuration file
-w CSV, --result CSV path to output result file
-R, --summary show a result summary
-k SECONDS, --timeout SECONDS
exit after the specified seconds (default: 60 secs)
-F TEST, --filter TEST
Expand All @@ -39,6 +40,8 @@ Virtual machine:
trace event definition file
-i N, --icount N virtual instruction counter with 2^N clock ticks per inst.
-s, --singlestep enable "single stepping" QEMU execution mode
-T SECS, --timeout-factor SECS
timeout factor
-U, --muxserial enable multiple virtual UARTs to be muxed into same host output channel

Files:
Expand All @@ -64,6 +67,7 @@ This tool may be used in two ways, which can be combined:
[Configuration](#Configurationfile) section for details.
* `-w` / `--result` specify an output CSV report file where the result of all the QEMU sessions,
one per test, are reported.
* `-R` / `--summary` show a execution result summary on exit
* `-k` / `--timeout` define the maximal duration of each QEMU session. QEMU is terminated or killed
after this delay if the executed test has not completed in time.
* `-F` / `--filter` when used, only tests whose filenames match one of the selected filter are
Expand Down Expand Up @@ -103,6 +107,8 @@ This tool may be used in two ways, which can be combined:
matches the expected FPGA-based lowRISC CPU.
Note that this option slows down the execution of guest applications.
* `-s` / `--singlestep` enable QEMU "single stepping" mode.
* `-T` / `--timeout-factor` apply a multiplier factor to all timeouts. Specified as a real number,
it can be greater to increase timeouts or lower than 1 to decrease timeouts.
* `-U` / `--muxserial` enable muxing QEMU VCP. This option is required when several virtual UARTs
are routed to the same host output channel.

Expand Down Expand Up @@ -389,15 +395,20 @@ Sample config for running some non-OpenTitan tests:
* `aliases`
This section may be used to define string aliases to simplify further definitions.

Note that the resulting aliases are always uppercased.
Note that the resulting aliases are always uppercased. To use an alias, use the `${ALIAS}` syntax.
Environment variables may also be used as aliases.

To use an alias, use the `${ALIAS}` syntax. Environment variables may also be used as aliases.
Several special variables are automatically defined:
* `${CONFIG}` refers to the path of the configuration file itself,
* `${TESTDIR}` refers to the default test path (see `testdir` below).
* `${QEMU_SRC_DIR}` refers to the path to the QEMU source directory
* `${QEMU_BIN_DIR}` refers to the directory than contains the QEMU executable.

Moreover, the following special variables are defined for each executed test:
* `${UTPATH}` absolute path to the executed OT test
* `${UTDIR}` absolute path to the directory containing the executed OT test
* `${UTFILE}` file name of the executed OT test (without directory specifier)

* `testdir`
This section may be used to define the default path where to look for tests to run.

Expand All @@ -418,6 +429,11 @@ Sample config for running some non-OpenTitan tests:
It is possible to exclude some tests from this list with the `exclude` and `exclude_from`
sections.

It is possible to define sub-sections as items of the list. Each subsection should be a map, where
the sub-section is only evaluated if an environment variable exists and evaluates to true. This
enables configuring lists based on environment variables, such as running is some specific
contexts such as a CI environment.

* `include_from`
This section contains a list of files defining the tests to be run.

Expand Down
3 changes: 3 additions & 0 deletions hw/opentitan/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ config OT_RSTMGR
config OT_SENSOR
bool

config OT_SOC_PROXY
bool

config OT_SPI_DEVICE
bool

Expand Down
1 change: 1 addition & 0 deletions hw/opentitan/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ system_ss.add(when: 'CONFIG_OT_RANDOM_SRC', if_true: files('ot_random_src.c'))
system_ss.add(when: 'CONFIG_OT_ROM_CTRL', if_true: files('ot_rom_ctrl.c', 'ot_rom_ctrl_img.c'))
system_ss.add(when: 'CONFIG_OT_RSTMGR', if_true: files('ot_rstmgr.c'))
system_ss.add(when: 'CONFIG_OT_SENSOR', if_true: files('ot_sensor.c'))
system_ss.add(when: 'CONFIG_OT_SOC_PROXY', if_true: files('ot_soc_proxy.c'))
system_ss.add(when: 'CONFIG_OT_SPI_DEVICE', if_true: files('ot_spi_device.c'))
system_ss.add(when: 'CONFIG_OT_SPI_HOST', if_true: files('ot_spi_host.c'))
system_ss.add(when: 'CONFIG_OT_SRAM_CTRL', if_true: files('ot_sram_ctrl.c'))
Expand Down
Loading