Skip to content

Commit

Permalink
WIP on docs and config file structure
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanstraten committed Jul 25, 2019
1 parent 932b6d8 commit 6aa39de
Show file tree
Hide file tree
Showing 43 changed files with 2,719 additions and 408 deletions.
1 change: 1 addition & 0 deletions mdbook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
book
5 changes: 5 additions & 0 deletions mdbook/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[book]
authors = ["Jeroen van Straten"]
multilingual = false
src = "src"
title = "vhdMMIO"
25 changes: 25 additions & 0 deletions mdbook/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Summary

- [Field descriptor](fielddescriptor.md)
- [`primitive` behavior](primitive.md)
- [`constant` behavior](constant.md)
- [`config` behavior](config.md)
- [`status` behavior](status.md)
- [`internal-status` behavior](internalstatus.md)
- [`latching` behavior](latching.md)
- [`control` behavior](control.md)
- [`internal-control` behavior](internalcontrol.md)
- [`flag` behavior](flag.md)
- [`volatile-flag` behavior](volatileflag.md)
- [`internal-flag` behavior](internalflag.md)
- [`volatile-internal-flag` behavior](volatileinternalflag.md)
- [`strobe` behavior](strobe.md)
- [`request` behavior](request.md)
- [`multi-request` behavior](multirequest.md)
- [`counter` behavior](counter.md)
- [`volatile-counter` behavior](volatilecounter.md)
- [`internal-counter` behavior](internalcounter.md)
- [`volatile-internal-counter` behavior](volatileinternalcounter.md)
- [`Metadata`](metadata.md)
- [Access privileges](accessprivileges.md)
- [VHDL interface options](interfaceoptions.md)
105 changes: 105 additions & 0 deletions mdbook/src/accessprivileges.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Access privileges

This configuration structure defines the privilege levels that are
allowed to access a field based on the `aw_prot` and `ar_prot` AXI4L
signals. This is primarily intended to help you identify problems during
development (such as a softcore deciding to jump to a register file).

**If you're using `vhdmmio` in an environment where security is in any way
meaningful, restrict yourself to using single-word, non-blocking registers.
Even then, `vhdmmio` has not undergone any kind of auditing or
certification process and therefore does not make ANY guarantees that
your system will be secure.**

The following best-effort logic is included based on access privileges:

- Accessing a field for which the master has insufficient privileges
makes the field behave like it does not exist. Depending on whether
there are other fields in the surrounding register that can be
accessed, a decode error may or may not be generated. Read data is
always blanked out, and there will not be any side effects.

- When a higher-privileged master is in the process of accessing a
multi-word register, lower-privileged accesses are rejected. An access
is considered less privileged when the ongoing access is privileged
(`--1`) while the interrupting access is unprivileged (`--0`), OR
when the ongoing access is secure (`-0-`) while the interrupting access
is nonsecure (`-1-`). Such accesses are rejected by means of a slave
error. Even though it would normally be ignored, the read data is
forced to all zeros during this error to prevent leaks.

- When a multi-word read completes, the holding register is cleared.

The latter two features may be disabled within the register file features
structure to save a small amount of logic.

`vhdmmio` certainly will *NOT* protect against:

- Timing attacks on blocking fields. This is impossible to avoid by
`vhdmmio`, since AXI4L does not support reordering.

- Denial-of-service and man-in-the-middle style attacks for multi-word
accesses on the same privilege level. This is impossible to avoid by
`vhdmmio`, since AXI4L does not support locking.

- Powerline side-channel attacks, as well as undervolting, overclocking,
radiation, etc.. Basically, anything that can be used to circumvent the
semantics of VHDL. This is impossible to avoid in a vendor-agnostic way,
and would be extremely difficult even for a specific FPGA/ASIC.

To the best of my knowledge, barring the above, a register file with only
single-word, non-blocking, non-deferring registers should be fairly secure.
But please take this statement with a big grain of salt, as I am not a
security expert.

This structure supports the following configuration keys.

## `user`

Whether unprivileged masters (`--0`) can access the field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `privileged`

Whether privileged masters (`--1`) can access the field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `secure`

Whether secure transactions (`-0-`) can be used to can access the
field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `nonsecure`

Whether nonsecure transactions (`-1-`) can be used to can access the
field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `data`

Whether data transactions (`0--`) can access the field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `instruction`

Whether instruction transactions (`1--`) can access the field.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.
6 changes: 6 additions & 0 deletions mdbook/src/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# `config` behavior

Fields with `config` behavior always return the value specified by a
VHDL generic. They cannot be written.

This structure does not support any configuration keys.
12 changes: 12 additions & 0 deletions mdbook/src/constant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# `constant` behavior

Fields with `constant` behavior always return the value specified
through the `value` option when read. They cannot be written.

This structure supports the following configuration key.

## `value`

Configures the value using an integer or boolean.

This key is required.
119 changes: 119 additions & 0 deletions mdbook/src/control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# `control` behavior

Fields with `control` behavior are used to push runtime configuration
values from software to hardware. They are normally read-write on the MMIO
bus and respect the AXI4L byte strobe bits so they can be easily (though
not necessarily atomically) updated partially, but read access can be
disabled and write access can be simplified if this is desirable.

The hardware interface by default consists of just an `std_logic` or
`std_logic_vector` with the current value of the field, but you can also
enable a valid bit by setting `hw-read` to `enabled` if you so desire.
You'll also need to set `bus-write` to `enabled` and `after-bus-write` to
`validate` to make that work as you would expect: the value will be marked
invalid from reset to when it's first written. You can also make the field
one-time-programmable by selecting `invalid` or `invalid-only` for
`bus-write` instead of `enabled`.

This structure supports the following configuration keys.

## `bus-read`

Configures what happens when a bus read occurs.

The following values are supported:

- `enabled` (default): normal read access to field, ignoring valid bit.

- `error`: reads always return a slave error.

- `disabled`: read access is disabled.

This key is optional unless required by context. If not specified, the default value (`enabled`) is used.

## `bus-write`

Configures what happens when a bus write occurs.

The following values are supported:

- `masked` (default): Write access respects strobe bits. Precludes after-bus-write.

- `enabled`: Normal write access to register. Masked bits are written 0.

- `invalid`: As above, but ignores the write when the register is valid.

- `invalid-only`: As above, but fails when register is already valid.

This key is optional unless required by context. If not specified, the default value (`masked`) is used.

## `after-bus-write`

Configures what happens after a bus write.

The following values are supported:

- `nothing` (default): no extra operation after write.

- `validate`: register is validated after write.

This key is optional unless required by context. If not specified, the default value (`nothing`) is used.

## `hw-read`

Configure the existence and behavior of the hardware read port.

The following values are supported:

- `simple` (default): only the data output is generated.

- `enabled`: both a data and a valid output signal are generated.

This key is optional unless required by context. If not specified, the default value (`simple`) is used.

## `reset`

Configures the reset value.

The following values are supported:

- `no`: the internal data register resets to 0, with the valid flag set.

- `yes`: the internal data register resets to 1, with the valid flag set.

- `null` (default): the internal data register resets to 0, with the valid flag cleared.

- an integer: the internal data register resets to the given value, with the valid flag set.

- `generic`: the reset value is controlled through a VHDL generic.

This key is optional unless required by context. If not specified, the default value (`null`) is used.

## `ctrl-lock`

Controls the existence of the `ctrl_lock` control input signal. When
this signal is asserted, writes are ignored.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `ctrl-invalidate`

Controls the existence of the `ctrl_invalidate` control input
signal. When this signal is asserted, the internal valid flag is
cleared. The data register is also set to 0.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `ctrl-reset`

Controls the existence of the `ctrl_reset` control input
signal. When this signal is asserted, the field is reset, as if the
register file `reset` input were asserted.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.
95 changes: 95 additions & 0 deletions mdbook/src/counter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# `counter` behavior

Similar to `flag` fields, `counter`s are used to signal events from
hardware to software. However, counters allow multiple events occurring
between consecutive software read cycles to be registered by counting
instead of bit-setting. Like `flag`, software should use fields of this
type by reading the value and then writing the read value to it in order
to avoid missing events; the write operation subtracts the written value
from the internal register.

This structure supports the following configuration keys.

## `hw-read`

Configure the existence and behavior of the hardware read port.

The following values are supported:

- `disabled` (default): no read port is generated.

- `simple`: only the data output is generated.

This key is optional unless required by context. If not specified, the default value (`disabled`) is used.

## `hw-write`

Configure the existence and behavior of the hardware write port.

The following values are supported:

- `disabled` (default): no write port is generated.

- `enabled`: a record consisting of a write enable flag and data is generated.

- `accumulate`: like enabled, but the data is accumulated instead of written.

- `subtract`: like enabled, but the data is subtracted instead of written.

This key is optional unless required by context. If not specified, the default value (`disabled`) is used.

## `reset`

Configures the reset value.

The following values are supported:

- `no` (default): the internal data register resets to 0, with the valid flag set.

- `yes`: the internal data register resets to 1, with the valid flag set.

- an integer: the internal data register resets to the given value, with the valid flag set.

- `generic`: the reset value is controlled through a VHDL generic.

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `ctrl-clear`

Controls the existence of the `ctrl_clear` control input
signal. When this signal is asserted, the internal data register is
cleared. The valid flag is not affected.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `ctrl-reset`

Controls the existence of the `ctrl_reset` control input
signal. When this signal is asserted, the field is reset, as if the
register file `reset` input were asserted.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `ctrl-increment`

Controls the existence of the `ctrl_increment` control input
signal. When this signal is asserted, the internal data register is
incremented.

The value must be a boolean (default `yes`).

This key is optional unless required by context. If not specified, the default value (`yes`) is used.

## `ctrl-decrement`

Controls the existence of the `ctrl_decrement` control input
signal. When this signal is asserted, the internal data register is
decremented.

The value must be a boolean (default `no`).

This key is optional unless required by context. If not specified, the default value (`no`) is used.
Loading

0 comments on commit 6aa39de

Please # to comment.