Rename to TK1

This commit is contained in:
Daniel Lublin 2022-10-20 14:50:21 +02:00
parent 5e80b4ae15
commit 4b4f014d38
No known key found for this signature in database
GPG Key ID: 75BD0FEB8D3E7830
27 changed files with 281 additions and 284 deletions

View File

@ -31,7 +31,7 @@ applications up to 64 KB with a 64 KB stack.
* [Framing Protocol](doc/framing_protocol/framing_protocol.md)
* [Boards](hw/boards/README.md)
* [Software](doc/system_description/software.md)
* [Firmware](hw/application_fpga/fw/mta1_mkdf/README.md)
* [Firmware](hw/application_fpga/fw/tk1/README.md)
* [Toolchain setup](doc/toolchain_setup.md)
* [Quickstart](doc/quickstart.md) to program the Tillitis Key 1
* [Release Notes](doc/release_notes.md)

View File

@ -7,21 +7,21 @@
## 1 Introduction
This document describes a proposal for a transport level communication
protocol for the mta1_mkdf USB connected secure application device. The
proposal describes the different endpoints, the different levels in the
stack, framing and encoding.
protocol for the TK1 USB connected secure application device. The
proposal describes the different endpoints, the different levels in
the stack, framing and encoding.
## 2 System description and problem statement
The mta1_mkdf is a USB connected device. The device provides a secure
compute platform and environment for applications providing some service
and function to (the user of) the USB host. Examples of applications
that can be implemented are AUTH token generators, Root of Trust, and
signing oracles.
The TK1 is a USB connected device. The device provides a secure
compute platform and environment for applications providing some
service and function to (the user of) the USB host. Examples of
applications that can be implemented are AUTH token generators, Root
of Trust, and signing oracles.
The mta1_mkdf is implemented using FPGA devices, and the computer
functionality is based on RISC-V. Conceptually, the mta1_mkdf consists
of three levels:
The TK1 is implemented using FPGA devices, and the computer
functionality is based on RISC-V. Conceptually, the TK1 consists of
three levels:
1. The hardware level. The actual FPGA devices and the hardware
implemented in them, for example the RISC-V core, the application and
@ -29,33 +29,33 @@ of three levels:
hardware access control.
2. The mta1_mkdf firmware and SDK level. The mta1_mkdf contains SW
functionality (called firmware - FW) used to set up the application
environment, but also provide the applications with things like host
communication (the protocol described in this document), key
2. The TK1 firmware and SDK level. The TK1 contains SW functionality
(called firmware - FW) used to set up the application environment,
but also provide the applications with things like host
communication (the protocol described in this document), key
generation, timers etc.
Similarly, the SDK provides similar convenience functions for the
host side applications. Allowing host side applications to load
applications on the mta1_mkdf, and then communicate with, use the
applications running on the mta1_mkdf.
applications on the TK1, and then communicate with, use the
applications running on the TK1.
3. The applications running on the mta1_mkdf, the corresponding host SW.
3. The applications running on the TK1, the corresponding host SW.
The hardware, the FW as well as the applications can be endpoints with
which programs on the host may communicate. This means that we need to
be able to address different endpoints in the mta1_mkdf. And, crucially,
the applications and their corresponding host SW may communicate using
be able to address different endpoints in the TK1. And, crucially, the
applications and their corresponding host SW may communicate using
custom protocols that are not known today.
This means that we need a general transport mechanism for commands to,
and responses from the endpoints in the mta1_mkdf. Due to the
constrained environment the transport mechanism must be “light”, that is
both easy to implement and to require few resources
and responses from the endpoints in the TK1. Due to the constrained
environment the transport mechanism must be “light”, that is both easy
to implement and to require few resources
### 2.1 mta1_mkdf system description details
The mta1_mkdf consists of two FPGA devices - interface_fpga and
### 2.1 TK1 system description details
The TK1 consists of two FPGA devices - interface_fpga and
application_fpga.
The interface_fpga contains a USB core and FPGA-local control
@ -91,9 +91,9 @@ and sending responses.
## 3 Protocol description
The communication is driven by the host and the protocol is
command-response based. The host sends a command, and the mta1_mkdf must
always send a response to a given command. Commands are processed by the
mta1_mkdf in order. If the host sends a new command before receiving a
command-response based. The host sends a command, and the TK1 must
always send a response to a given command. Commands are processed by
the TK1 in order. If the host sends a new command before receiving a
response to the previous command, it is the responsibility of the host
to determine to which command a received response belongs to.
@ -154,7 +154,7 @@ Some examples to clarify endpoints and commands:
* 0x1a: A command to the application running in the application_fpga
with 32 bytes of data. The data could be a 32 byte challenge to be
signed using a private key derived in the mta1_mkdf.
signed using a private key derived in the TK1.
### 3.2 Response frame format

View File

@ -184,7 +184,7 @@ Available commands/reponses:
#### `FW_{CMD,RSP}_VERIFY_DEVICE`
Verification that the device is an authentic Mullvad
Verification that the device is an authentic Tillitis
device. Implemented using challenge/response.
#### `FW_{CMD,RSP}_GET_APP_DIGEST`
@ -305,8 +305,7 @@ v v
The memory exposes SoC functionality to the software when in firmware
mode. It is a set of memory mapped registers (MMIO), starting at base
address `0xc000_0000`. For specific offsets/bitmasks, see the file
[mta1_mkdf_mem.h](../../hw/application_fpga/fw/mta1_mkdf_mem.h) (in
this repo).
[tk1_mem.h](../../hw/application_fpga/fw/tk1_mem.h) (in this repo).
Assigned core prefixes:
@ -320,7 +319,7 @@ Assigned core prefixes:
| UART | 0xc3 |
| TOUCH | 0xc4 |
| FW_RAM | 0xd0 |
| MTA1 | 0xff |
| TK1 | 0xff |
*Nota bene*: MMIO accesses should be 32 bit wide, e.g use `lw` and
`sw`. Exceptions are `FW_RAM` and `QEMU_DEBUG`.
@ -349,7 +348,7 @@ Assigned core prefixes:
| `UDA` | r | invisible | 16B | u8[16] | | Unique Device Authentication key. |
| `UDI` | r | r | 8B | u64 | | Unique Device ID (UDI). |
| `QEMU_DEBUG` | w | w | | u8 | | Debug console (only in QEMU) |
| `NAME0` | r | r | 4B | char[4] | "mta1" | ID of core/stick |
| `NAME0` | r | r | 4B | char[4] | "tk1 " | ID of core/stick |
| `NAME1` | r | r | 4B | char[4] | "mkdf" | ID of core/stick |
| `VERSION` | r | r | 4B | u32 | 1 | Current version. |
| `SWITCH_APP` | w | invisible? | 1B | u8 | | Switch to application mode. Write non-zero to trigger. |

View File

@ -2,9 +2,9 @@
## Purpose and Revision
The purpose of this document is to provide a description of the
Tillitis Key 1 (TK1). What it is, what is supposed to be used for, by whom,
where and possible use cases. The document also provides a functional level
description of features and components of the mta1_mkdf.
Tillitis Key 1 (TK1). What it is, what is supposed to be used for, by
whom, where and possible use cases. The document also provides a
functional level description of features and components of the TK1.
Finally, the document acts as a requirement description. For the
requirements, the document follows
@ -60,7 +60,7 @@ The TK1 store and use the following assets internally:
- UDS - Unique Device Secret. Provisioned and stored during
device manufacturing. Never to be replaced during the life time of
a given device. Used to derive application secrets. Must never leave
the device. Mullvad must NOT store a copy of the UDS.
the device. Tillitis must NOT store a copy of the UDS.
- UDI - Unique Device ID. Provisioned and stored during
device manufacturing. Never to be replaced or altered during the life
@ -69,7 +69,7 @@ The TK1 store and use the following assets internally:
- UDA - Unique Device Authentication Secret. Provisioned and stored during
device manufacturing. Never to be replaced during the life time of
a given device. Used to authenticate a specific device. Must never
leave the device. Mullvad MUST have a copy of the UDA.
leave the device. Tillitis MUST have a copy of the UDA.
Additionally the following asset could be provided from the host:
@ -100,8 +100,8 @@ libraries etc. Roughly these can be divided into:
- host side application loader. Software that talks to the FW in the
application_fpga to load a secure application
- host side boot, management. Support software to boot, authenticate the
mta1_mkdf board connected to a host
- host side boot, management. Support software to boot, authenticate
the TK1 board connected to a host
- host side secure application. Software that communicates with the
secure application running in the application_fpga as needed to solve
@ -125,27 +125,27 @@ The Application FPGA hardware should provide the following:
- Unique Device ID (UDI)
- 64 bits
- Readable via API before application start
- Generated and stored by Mullvad
- Generated and stored by Tillitis
- Unique Device Authentication key (UDA)
- At least 128 bits number
- Readable by FW before application start
- Generated and stored by Mullvad
- Generated and stored by Tillitis
- Unique Device Secret (UDS)
- 256 bits
- Readable by HW before application start
- Generated but NOT stored by Mullvad
- Generated but NOT stored by Tillitis
- NAME
- 64 bits. ASCII string. "mta1_mkdf"
- 64 bits. ASCII string. "TK1 MKDF"
- Readable via API before application start
- Set by Mullvad as part of FPGA design
- Set by Tillitis as part of FPGA design
- VERSION: version
- 32 bits. 32 bit data, for example 1
- Readable via API before application start
- Set by Mullvad as part of FPGA design
- Set by Tillitis as part of FPGA design
2. Communication
- Rx-FIFO with status (data_available)

View File

@ -61,30 +61,30 @@ VERILOG_SRCS = \
$(P)/core/timer/rtl/timer.v \
$(P)/core/uds/rtl/uds.v \
$(P)/core/touch_sense/rtl/touch_sense.v \
$(P)/core/mta1/rtl/mta1.v \
$(P)/core/tk1/rtl/tk1.v \
$(P)/core/uart/rtl/uart_core.v \
$(P)/core/uart/rtl/uart_fifo.v \
$(P)/core/uart/rtl/uart.v \
$(P)/core/trng/rtl/rosc.v
FIRMWARE_DEPS = \
$(P)/fw/mta1_mkdf_mem.h \
$(P)/fw/mta1_mkdf/types.h \
$(P)/fw/mta1_mkdf/lib.h \
$(P)/fw/mta1_mkdf/proto.h
$(P)/fw/tk1_mem.h \
$(P)/fw/tk1/types.h \
$(P)/fw/tk1/lib.h \
$(P)/fw/tk1/proto.h
FIRMWARE_OBJS = \
$(P)/fw/mta1_mkdf/main.o \
$(P)/fw/mta1_mkdf/start.o \
$(P)/fw/mta1_mkdf/proto.o \
$(P)/fw/mta1_mkdf/lib.o \
$(P)/fw/mta1_mkdf/blake2s/blake2s.o
$(P)/fw/tk1/main.o \
$(P)/fw/tk1/start.o \
$(P)/fw/tk1/proto.o \
$(P)/fw/tk1/lib.o \
$(P)/fw/tk1/blake2s/blake2s.o
TESTFW_OBJS = \
$(P)/fw/testfw/main.o \
$(P)/fw/mta1_mkdf/start.o \
$(P)/fw/mta1_mkdf/proto.o \
$(P)/fw/mta1_mkdf/lib.o
$(P)/fw/tk1/start.o \
$(P)/fw/tk1/proto.o \
$(P)/fw/tk1/lib.o
#-------------------------------------------------------------------
# All: Complete build of HW and FW.
@ -116,15 +116,15 @@ secret:
# Firmware generation.
# Included in the bitstream.
#-------------------------------------------------------------------
LDFLAGS=-T $(P)/fw/mta1_mkdf/firmware.lds
LDFLAGS=-T $(P)/fw/tk1/firmware.lds
$(FIRMWARE_OBJS): $(FIRMWARE_DEPS)
$(TESTFW_OBJS): $(FIRMWARE_DEPS)
firmware.elf: $(FIRMWARE_OBJS) $(P)/fw/mta1_mkdf/firmware.lds
firmware.elf: $(FIRMWARE_OBJS) $(P)/fw/tk1/firmware.lds
$(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@
testfw.elf: $(TESTFW_OBJS) $(P)/fw/mta1_mkdf/firmware.lds
testfw.elf: $(TESTFW_OBJS) $(P)/fw/tk1/firmware.lds
$(CC) $(CFLAGS) $(TESTFW_OBJS) $(LDFLAGS) -o $@
# Generate a fake BRAM file that will be filled in later after place-n-route

View File

@ -1,4 +1,4 @@
# mta1
# tk1
## Introduction
Top level core that provides chip info, debug support and chip level control.

View File

@ -1,8 +1,8 @@
//======================================================================
//
// mta1.v
// ------
// Top level information, debug and control core for the mta1 design.
// tk1.v
// -----
// Top level information, debug and control core for the tk1 design.
//
//
// Author: Joachim Strombergson
@ -13,29 +13,29 @@
`default_nettype none
module mta1(
input wire clk,
input wire reset_n,
module tk1(
input wire clk,
input wire reset_n,
output wire fw_app_mode,
output wire fw_app_mode,
output wire led_r,
output wire led_g,
output wire led_b,
output wire led_r,
output wire led_g,
output wire led_b,
input wire gpio1,
input wire gpio2,
output wire gpio3,
output wire gpio4,
input wire gpio1,
input wire gpio2,
output wire gpio3,
output wire gpio4,
input wire cs,
input wire we,
input wire cs,
input wire we,
input wire [7 : 0] address,
input wire [31 : 0] write_data,
output wire [31 : 0] read_data,
output wire ready
);
input wire [7 : 0] address,
input wire [31 : 0] write_data,
output wire [31 : 0] read_data,
output wire ready
);
//----------------------------------------------------------------
@ -67,9 +67,9 @@ module mta1(
localparam ADDR_UDI_FIRST = 8'h30;
localparam ADDR_UDI_LAST = 8'h31;
localparam MTA1_NAME0 = 32'h6d746131; // "mta1"
localparam MTA1_NAME1 = 32'h6d6b6466; // "mkdf"
localparam MTA1_VERSION = 32'h00000004;
localparam TK1_NAME0 = 32'h746B3120; // "tk1 "
localparam TK1_NAME1 = 32'h6d6b6466; // "mkdf"
localparam TK1_VERSION = 32'h00000004;
//----------------------------------------------------------------
@ -259,15 +259,15 @@ module mta1(
else begin
if (address == ADDR_NAME0) begin
tmp_read_data = MTA1_NAME0;
tmp_read_data = TK1_NAME0;
end
if (address == ADDR_NAME1) begin
tmp_read_data = MTA1_NAME1;
tmp_read_data = TK1_NAME1;
end
if (address == ADDR_VERSION) begin
tmp_read_data = MTA1_VERSION;
tmp_read_data = TK1_VERSION;
end
if (address == ADDR_SWITCH_APP) begin
@ -302,8 +302,8 @@ module mta1(
end
end // api
endmodule // mta1
endmodule // tk1
//======================================================================
// EOF mta1.v
// EOF tk1.v
//======================================================================

View File

@ -3,7 +3,7 @@
# application_fpga_mta1_usb_dev.pcf
# ---------------------------------
# Pin constraints file for the Application FPGA design used on the
# Mullvad MTA1_USB_DEV board.
# Tillitis MTA1_USB_DEV board.
#
#
# Copyright (C) 2022 - Tillitis AB

View File

@ -1,92 +0,0 @@
/*
* QEMU RISC-V Board Compatible with Mullvad MTA1-MKDF platform
*
* Copyright (c) 2022 Tillitis AB
* SPDX-License-Identifier: GPL-2.0-only
*/
// clang-format off
#ifndef HW_MTA1_MKDF_MEM_H
#define HW_MTA1_MKDF_MEM_H
// The canonical location of this file is:
// repo: https://github.com/tillitis/tillitis-key1
// path: /hw/application_fpga/fw/mta1_mkdf_mem.h
// The contents are derived from the Verilog code. For use by QEMU model,
// firmware, and apps.
enum {
MTA1_MKDF_ROM_BASE = 0x00000000, // 0b00000000...
MTA1_MKDF_RAM_BASE = 0x40000000, // 0b01000000...
MTA1_MKDF_RESERVED_BASE = 0x80000000, // 0b10000000...
MTA1_MKDF_MMIO_BASE = 0xc0000000, // 0b11000000...
MTA1_MKDF_MMIO_SIZE = 0xffffffff - MTA1_MKDF_MMIO_BASE,
MTA1_MKDF_MMIO_TRNG_BASE = MTA1_MKDF_MMIO_BASE | 0x00000000,
MTA1_MKDF_MMIO_TIMER_BASE = MTA1_MKDF_MMIO_BASE | 0x01000000,
MTA1_MKDF_MMIO_UDS_BASE = MTA1_MKDF_MMIO_BASE | 0x02000000,
MTA1_MKDF_MMIO_UART_BASE = MTA1_MKDF_MMIO_BASE | 0x03000000,
MTA1_MKDF_MMIO_TOUCH_BASE = MTA1_MKDF_MMIO_BASE | 0x04000000,
MTA1_MKDF_MMIO_FW_RAM_BASE = MTA1_MKDF_MMIO_BASE | 0x10000000,
MTA1_MKDF_MMIO_FW_RAM_SIZE = 1024,
// This "core" only exists in QEMU
MTA1_MKDF_MMIO_QEMU_BASE = MTA1_MKDF_MMIO_BASE | 0x3e000000,
MTA1_MKDF_MMIO_MTA1_BASE = MTA1_MKDF_MMIO_BASE | 0x3f000000, // 0xff000000
MTA1_MKDF_NAME0_SUFFIX = 0x00,
MTA1_MKDF_NAME1_SUFFIX = 0x04,
MTA1_MKDF_VERSION_SUFFIX = 0x08,
MTA1_MKDF_MMIO_TRNG_STATUS = MTA1_MKDF_MMIO_TRNG_BASE | 0x24,
MTA1_MKDF_MMIO_TRNG_STATUS_READY_BIT = 0,
MTA1_MKDF_MMIO_TRNG_ENTROPY = MTA1_MKDF_MMIO_TRNG_BASE | 0x80,
MTA1_MKDF_MMIO_TIMER_CTRL = MTA1_MKDF_MMIO_TIMER_BASE | 0x20,
MTA1_MKDF_MMIO_TIMER_STATUS = MTA1_MKDF_MMIO_TIMER_BASE | 0x24,
MTA1_MKDF_MMIO_TIMER_STATUS_READY_BIT = 0,
MTA1_MKDF_MMIO_TIMER_PRESCALER = MTA1_MKDF_MMIO_TIMER_BASE | 0x28,
MTA1_MKDF_MMIO_TIMER_TIMER = MTA1_MKDF_MMIO_TIMER_BASE | 0x2c,
MTA1_MKDF_MMIO_UDS_FIRST = MTA1_MKDF_MMIO_UDS_BASE | 0x40,
MTA1_MKDF_MMIO_UDS_LAST = MTA1_MKDF_MMIO_UDS_BASE | 0x5c, // Address of last 32-bit word of UDS
MTA1_MKDF_MMIO_UART_BIT_RATE = MTA1_MKDF_MMIO_UART_BASE | 0x40,
MTA1_MKDF_MMIO_UART_DATA_BITS = MTA1_MKDF_MMIO_UART_BASE | 0x44,
MTA1_MKDF_MMIO_UART_STOP_BITS = MTA1_MKDF_MMIO_UART_BASE | 0x48,
MTA1_MKDF_MMIO_UART_RX_STATUS = MTA1_MKDF_MMIO_UART_BASE | 0x80,
MTA1_MKDF_MMIO_UART_RX_DATA = MTA1_MKDF_MMIO_UART_BASE | 0x84,
MTA1_MKDF_MMIO_UART_TX_STATUS = MTA1_MKDF_MMIO_UART_BASE | 0x100,
MTA1_MKDF_MMIO_UART_TX_DATA = MTA1_MKDF_MMIO_UART_BASE | 0x104,
MTA1_MKDF_MMIO_TOUCH_STATUS = MTA1_MKDF_MMIO_TOUCH_BASE | 0x24,
MTA1_MKDF_MMIO_TOUCH_STATUS_EVENT_BIT = 0,
// TODO HW core/addr is not yet defined for this:
MTA1_MKDF_MMIO_QEMU_UDA = MTA1_MKDF_MMIO_QEMU_BASE | 0x20,
// This will only ever exist in QEMU:
MTA1_MKDF_MMIO_QEMU_DEBUG = MTA1_MKDF_MMIO_QEMU_BASE | 0x1000,
MTA1_MKDF_MMIO_MTA1_NAME0 = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_NAME0_SUFFIX,
MTA1_MKDF_MMIO_MTA1_NAME1 = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_NAME1_SUFFIX,
MTA1_MKDF_MMIO_MTA1_VERSION = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_VERSION_SUFFIX,
MTA1_MKDF_MMIO_MTA1_SWITCH_APP = MTA1_MKDF_MMIO_MTA1_BASE | 0x20,
MTA1_MKDF_MMIO_MTA1_LED = MTA1_MKDF_MMIO_MTA1_BASE | 0x24,
MTA1_MKDF_MMIO_MTA1_LED_R_BIT = 2,
MTA1_MKDF_MMIO_MTA1_LED_G_BIT = 1,
MTA1_MKDF_MMIO_MTA1_LED_B_BIT = 0,
MTA1_MKDF_MMIO_MTA1_GPIO = MTA1_MKDF_MMIO_MTA1_BASE | 0x28,
MTA1_MKDF_MMIO_MTA1_GPIO1_BIT = 0,
MTA1_MKDF_MMIO_MTA1_GPIO2_BIT = 1,
MTA1_MKDF_MMIO_MTA1_GPIO3_BIT = 2,
MTA1_MKDF_MMIO_MTA1_GPIO4_BIT = 3,
MTA1_MKDF_MMIO_MTA1_APP_ADDR = MTA1_MKDF_MMIO_MTA1_BASE | 0x30, // 0x4000_0000
MTA1_MKDF_MMIO_MTA1_APP_SIZE = MTA1_MKDF_MMIO_MTA1_BASE | 0x34,
MTA1_MKDF_MMIO_MTA1_CDI_FIRST = MTA1_MKDF_MMIO_MTA1_BASE | 0x80,
MTA1_MKDF_MMIO_MTA1_CDI_LAST = MTA1_MKDF_MMIO_MTA1_BASE | 0x9c, // Address of last 32-bit word of CDI.
MTA1_MKDF_MMIO_MTA1_UDI_FIRST = MTA1_MKDF_MMIO_MTA1_BASE | 0xc0,
MTA1_MKDF_MMIO_MTA1_UDI_LAST = MTA1_MKDF_MMIO_MTA1_BASE | 0xc4, // Address of last 32-bit word of UDI.
};
#endif

View File

@ -3,26 +3,26 @@
* SPDX-License-Identifier: GPL-2.0-only
*/
#include "../mta1_mkdf/lib.h"
#include "../mta1_mkdf/proto.h"
#include "../mta1_mkdf/types.h"
#include "../mta1_mkdf_mem.h"
#include "../tk1/lib.h"
#include "../tk1/proto.h"
#include "../tk1/types.h"
#include "../tk1_mem.h"
// clang-format off
volatile uint32_t *mta1name0 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME0;
volatile uint32_t *mta1name1 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME1;
volatile uint32_t *uds = (volatile uint32_t *)MTA1_MKDF_MMIO_UDS_FIRST;
volatile uint32_t *uda = (volatile uint32_t *)MTA1_MKDF_MMIO_QEMU_UDA; // Only in QEMU right now
volatile uint32_t *cdi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_CDI_FIRST;
volatile uint32_t *udi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_UDI_FIRST;
volatile uint32_t *switch_app = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_SWITCH_APP;
volatile uint8_t *fw_ram = (volatile uint8_t *)MTA1_MKDF_MMIO_FW_RAM_BASE;
volatile uint32_t *timer = (volatile uint32_t *)MTA1_MKDF_MMIO_TIMER_TIMER;
volatile uint32_t *timer_prescaler = (volatile uint32_t *)MTA1_MKDF_MMIO_TIMER_PRESCALER;
volatile uint32_t *timer_status = (volatile uint32_t *)MTA1_MKDF_MMIO_TIMER_STATUS;
volatile uint32_t *timer_ctrl = (volatile uint32_t *)MTA1_MKDF_MMIO_TIMER_CTRL;
volatile uint32_t *trng_status = (volatile uint32_t *)MTA1_MKDF_MMIO_TRNG_STATUS;
volatile uint32_t *trng_entropy = (volatile uint32_t *)MTA1_MKDF_MMIO_TRNG_ENTROPY;
volatile uint32_t *tk1name0 = (volatile uint32_t *)TK1_MMIO_TK1_NAME0;
volatile uint32_t *tk1name1 = (volatile uint32_t *)TK1_MMIO_TK1_NAME1;
volatile uint32_t *uds = (volatile uint32_t *)TK1_MMIO_UDS_FIRST;
volatile uint32_t *uda = (volatile uint32_t *)TK1_MMIO_QEMU_UDA; // Only in QEMU right now
volatile uint32_t *cdi = (volatile uint32_t *)TK1_MMIO_TK1_CDI_FIRST;
volatile uint32_t *udi = (volatile uint32_t *)TK1_MMIO_TK1_UDI_FIRST;
volatile uint32_t *switch_app = (volatile uint32_t *)TK1_MMIO_TK1_SWITCH_APP;
volatile uint8_t *fw_ram = (volatile uint8_t *)TK1_MMIO_FW_RAM_BASE;
volatile uint32_t *timer = (volatile uint32_t *)TK1_MMIO_TIMER_TIMER;
volatile uint32_t *timer_prescaler = (volatile uint32_t *)TK1_MMIO_TIMER_PRESCALER;
volatile uint32_t *timer_status = (volatile uint32_t *)TK1_MMIO_TIMER_STATUS;
volatile uint32_t *timer_ctrl = (volatile uint32_t *)TK1_MMIO_TIMER_CTRL;
volatile uint32_t *trng_status = (volatile uint32_t *)TK1_MMIO_TRNG_STATUS;
volatile uint32_t *trng_entropy = (volatile uint32_t *)TK1_MMIO_TRNG_ENTROPY;
// clang-format on
// TODO Real UDA is 4 words (16 bytes)
@ -82,13 +82,13 @@ int main()
in = readbyte();
test_puts("I'm testfw on:");
// Output the MTA1 core's NAME0 and NAME1
// Output the TK1 core's NAME0 and NAME1
uint32_t name;
wordcpy(&name, (void *)mta1name0, 1);
wordcpy(&name, (void *)tk1name0, 1);
test_reverseword(&name);
test_putsn((char *)&name, 4);
test_puts(" ");
wordcpy(&name, (void *)mta1name1, 1);
wordcpy(&name, (void *)tk1name1, 1);
test_reverseword(&name);
test_putsn((char *)&name, 4);
test_puts("\r\n");
@ -199,8 +199,7 @@ int main()
// Write anything to start timer
*timer_ctrl = 1;
for (;;) {
if (*timer_status &
(1 << MTA1_MKDF_MMIO_TIMER_STATUS_READY_BIT)) {
if (*timer_status & (1 << TK1_MMIO_TIMER_STATUS_READY_BIT)) {
// Timer expired (it is ready to start again)
break;
}
@ -217,7 +216,7 @@ int main()
// Write anything to stop the timer
*timer_ctrl = 1;
if (!(*timer_status & (1 << MTA1_MKDF_MMIO_TIMER_STATUS_READY_BIT))) {
if (!(*timer_status & (1 << TK1_MMIO_TIMER_STATUS_READY_BIT))) {
test_puts("FAIL: Timer didn't stop\r\n");
anyfailed = 1;
}
@ -238,8 +237,7 @@ int main()
for (int j = 0; j < 8; j++) {
for (int i = 0; i < 8; i++) {
while ((*trng_status &
(1 << MTA1_MKDF_MMIO_TRNG_STATUS_READY_BIT)) ==
0) {
(1 << TK1_MMIO_TRNG_STATUS_READY_BIT)) == 0) {
}
uint32_t rnd = *trng_entropy;
test_puthexn((uint8_t *)&rnd, 4);

View File

@ -20,11 +20,11 @@ the default `llvm-objcopy-14` and `llvm-size-14` define `OBJCOPY` and
## Using QEMU
Checkout the `mta1` branch of [our version of the
Checkout the `tk1` branch of [our version of the
qemu](https://github.com/tillitis/qemu) and build:
```
$ git clone -b mta1 https://github.com/tillitis/qemu
$ git clone -b tk1 https://github.com/tillitis/qemu
$ mkdir qemu/build
$ cd qemu/build
$ ../configure --target-list=riscv32-softmmu --disable-werror
@ -37,7 +37,7 @@ issue](https://github.com/tillitis/qemu/issues/3).)
Run it like this:
```
$ /path/to/qemu/build/qemu-system-riscv32 -nographic -M mta1_mkdf,fifo=chrid -bios firmware.elf \
$ /path/to/qemu/build/qemu-system-riscv32 -nographic -M tk1,fifo=chrid -bios firmware.elf \
-chardev pty,id=chrid
```

View File

@ -3,30 +3,30 @@
* SPDX-License-Identifier: GPL-2.0-only
*/
#include "../mta1_mkdf_mem.h"
#include "../tk1_mem.h"
#include "blake2s/blake2s.h"
#include "lib.h"
#include "proto.h"
#include "types.h"
// In RAM + above the stack (0x40010000)
#define APP_RAM_ADDR (MTA1_MKDF_RAM_BASE + 0x10000)
#define APP_RAM_ADDR (TK1_RAM_BASE + 0x10000)
#define APP_MAX_SIZE 65536
// clang-format off
static volatile uint32_t *uds = (volatile uint32_t *)MTA1_MKDF_MMIO_UDS_FIRST;
static volatile uint32_t *switch_app = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_SWITCH_APP;
static volatile uint32_t *name0 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME0;
static volatile uint32_t *name1 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME1;
static volatile uint32_t *ver = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_VERSION;
static volatile uint32_t *cdi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_CDI_FIRST;
static volatile uint32_t *app_addr = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_APP_ADDR;
static volatile uint32_t *app_size = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_APP_SIZE;
static volatile uint8_t *fw_ram = (volatile uint8_t *)MTA1_MKDF_MMIO_FW_RAM_BASE;
static volatile uint32_t *uds = (volatile uint32_t *)TK1_MMIO_UDS_FIRST;
static volatile uint32_t *switch_app = (volatile uint32_t *)TK1_MMIO_TK1_SWITCH_APP;
static volatile uint32_t *name0 = (volatile uint32_t *)TK1_MMIO_TK1_NAME0;
static volatile uint32_t *name1 = (volatile uint32_t *)TK1_MMIO_TK1_NAME1;
static volatile uint32_t *ver = (volatile uint32_t *)TK1_MMIO_TK1_VERSION;
static volatile uint32_t *cdi = (volatile uint32_t *)TK1_MMIO_TK1_CDI_FIRST;
static volatile uint32_t *app_addr = (volatile uint32_t *)TK1_MMIO_TK1_APP_ADDR;
static volatile uint32_t *app_size = (volatile uint32_t *)TK1_MMIO_TK1_APP_SIZE;
static volatile uint8_t *fw_ram = (volatile uint8_t *)TK1_MMIO_FW_RAM_BASE;
#define LED_RED (1 << MTA1_MKDF_MMIO_MTA1_LED_R_BIT)
#define LED_GREEN (1 << MTA1_MKDF_MMIO_MTA1_LED_G_BIT)
#define LED_BLUE (1 << MTA1_MKDF_MMIO_MTA1_LED_B_BIT)
#define LED_RED (1 << TK1_MMIO_TK1_LED_R_BIT)
#define LED_GREEN (1 << TK1_MMIO_TK1_LED_G_BIT)
#define LED_BLUE (1 << TK1_MMIO_TK1_LED_B_BIT)
#define LED_WHITE (LED_RED | LED_GREEN | LED_BLUE)
// clang-format on
@ -81,7 +81,7 @@ static void compute_cdi(uint8_t digest[32], uint8_t uss[32])
(const void *)fw_ram, 96, secure_ctx);
// Write over the firmware-only RAM
memset((void *)fw_ram, 0, MTA1_MKDF_MMIO_FW_RAM_SIZE);
memset((void *)fw_ram, 0, TK1_MMIO_FW_RAM_SIZE);
// Only word aligned access to CDI
wordcpy((void *)cdi, (void *)local_cdi, 8);
@ -265,13 +265,13 @@ int main()
lf();
// clang-format off
asm volatile(
"li a0, 0x40000000;" // MTA1_MKDF_RAM_BASE
"li a0, 0x40000000;" // TK1_RAM_BASE
"li a1, 0x40010000;"
"loop:;"
"sw zero, 0(a0);"
"addi a0, a0, 4;"
"blt a0, a1, loop;"
// Get value at MTA1_MKDF_MMIO_MTA1_APP_ADDR
// Get value at TK1_MMIO_TK1_APP_ADDR
"lui a0,0xff000;"
"lw a0,0x030(a0);"
"jalr x0,0(a0);"

View File

@ -4,16 +4,16 @@
*/
#include "proto.h"
#include "../mta1_mkdf_mem.h"
#include "../tk1_mem.h"
#include "lib.h"
#include "types.h"
// clang-format off
static volatile uint32_t *can_rx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_RX_STATUS;
static volatile uint32_t *rx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_RX_DATA;
static volatile uint32_t *can_tx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_TX_STATUS;
static volatile uint32_t *tx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_TX_DATA;
static volatile uint32_t *led = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_LED;
static volatile uint32_t *can_rx = (volatile uint32_t *)TK1_MMIO_UART_RX_STATUS;
static volatile uint32_t *rx = (volatile uint32_t *)TK1_MMIO_UART_RX_DATA;
static volatile uint32_t *can_tx = (volatile uint32_t *)TK1_MMIO_UART_TX_STATUS;
static volatile uint32_t *tx = (volatile uint32_t *)TK1_MMIO_UART_TX_DATA;
static volatile uint32_t *led = (volatile uint32_t *)TK1_MMIO_TK1_LED;
// clang-format on
uint8_t genhdr(uint8_t id, uint8_t endpoint, uint8_t status, enum cmdlen len)

View File

@ -0,0 +1,92 @@
/*
* QEMU RISC-V Board Compatible with Tillitis TK1 platform
*
* Copyright (c) 2022 Tillitis AB
* SPDX-License-Identifier: GPL-2.0-only
*/
// clang-format off
#ifndef TK1_MEM_H
#define TK1_MEM_H
// The canonical location of this file is:
// repo: https://github.com/tillitis/tillitis-key1
// path: /hw/application_fpga/fw/tk1_mem.h
// The contents are derived from the Verilog code. For use by QEMU model,
// firmware, and apps.
enum {
TK1_ROM_BASE = 0x00000000, // 0b00000000...
TK1_RAM_BASE = 0x40000000, // 0b01000000...
TK1_RESERVED_BASE = 0x80000000, // 0b10000000...
TK1_MMIO_BASE = 0xc0000000, // 0b11000000...
TK1_MMIO_SIZE = 0xffffffff - TK1_MMIO_BASE,
TK1_MMIO_TRNG_BASE = TK1_MMIO_BASE | 0x00000000,
TK1_MMIO_TIMER_BASE = TK1_MMIO_BASE | 0x01000000,
TK1_MMIO_UDS_BASE = TK1_MMIO_BASE | 0x02000000,
TK1_MMIO_UART_BASE = TK1_MMIO_BASE | 0x03000000,
TK1_MMIO_TOUCH_BASE = TK1_MMIO_BASE | 0x04000000,
TK1_MMIO_FW_RAM_BASE = TK1_MMIO_BASE | 0x10000000,
TK1_MMIO_FW_RAM_SIZE = 1024,
// This "core" only exists in QEMU
TK1_MMIO_QEMU_BASE = TK1_MMIO_BASE | 0x3e000000,
TK1_MMIO_TK1_BASE = TK1_MMIO_BASE | 0x3f000000, // 0xff000000
TK1_NAME0_SUFFIX = 0x00,
TK1_NAME1_SUFFIX = 0x04,
TK1_VERSION_SUFFIX = 0x08,
TK1_MMIO_TRNG_STATUS = TK1_MMIO_TRNG_BASE | 0x24,
TK1_MMIO_TRNG_STATUS_READY_BIT = 0,
TK1_MMIO_TRNG_ENTROPY = TK1_MMIO_TRNG_BASE | 0x80,
TK1_MMIO_TIMER_CTRL = TK1_MMIO_TIMER_BASE | 0x20,
TK1_MMIO_TIMER_STATUS = TK1_MMIO_TIMER_BASE | 0x24,
TK1_MMIO_TIMER_STATUS_READY_BIT = 0,
TK1_MMIO_TIMER_PRESCALER = TK1_MMIO_TIMER_BASE | 0x28,
TK1_MMIO_TIMER_TIMER = TK1_MMIO_TIMER_BASE | 0x2c,
TK1_MMIO_UDS_FIRST = TK1_MMIO_UDS_BASE | 0x40,
TK1_MMIO_UDS_LAST = TK1_MMIO_UDS_BASE | 0x5c, // Address of last 32-bit word of UDS
TK1_MMIO_UART_BIT_RATE = TK1_MMIO_UART_BASE | 0x40,
TK1_MMIO_UART_DATA_BITS = TK1_MMIO_UART_BASE | 0x44,
TK1_MMIO_UART_STOP_BITS = TK1_MMIO_UART_BASE | 0x48,
TK1_MMIO_UART_RX_STATUS = TK1_MMIO_UART_BASE | 0x80,
TK1_MMIO_UART_RX_DATA = TK1_MMIO_UART_BASE | 0x84,
TK1_MMIO_UART_TX_STATUS = TK1_MMIO_UART_BASE | 0x100,
TK1_MMIO_UART_TX_DATA = TK1_MMIO_UART_BASE | 0x104,
TK1_MMIO_TOUCH_STATUS = TK1_MMIO_TOUCH_BASE | 0x24,
TK1_MMIO_TOUCH_STATUS_EVENT_BIT = 0,
// TODO HW core/addr is not yet defined for this:
TK1_MMIO_QEMU_UDA = TK1_MMIO_QEMU_BASE | 0x20,
// This will only ever exist in QEMU:
TK1_MMIO_QEMU_DEBUG = TK1_MMIO_QEMU_BASE | 0x1000,
TK1_MMIO_TK1_NAME0 = TK1_MMIO_TK1_BASE | TK1_NAME0_SUFFIX,
TK1_MMIO_TK1_NAME1 = TK1_MMIO_TK1_BASE | TK1_NAME1_SUFFIX,
TK1_MMIO_TK1_VERSION = TK1_MMIO_TK1_BASE | TK1_VERSION_SUFFIX,
TK1_MMIO_TK1_SWITCH_APP = TK1_MMIO_TK1_BASE | 0x20,
TK1_MMIO_TK1_LED = TK1_MMIO_TK1_BASE | 0x24,
TK1_MMIO_TK1_LED_R_BIT = 2,
TK1_MMIO_TK1_LED_G_BIT = 1,
TK1_MMIO_TK1_LED_B_BIT = 0,
TK1_MMIO_TK1_GPIO = TK1_MMIO_TK1_BASE | 0x28,
TK1_MMIO_TK1_GPIO1_BIT = 0,
TK1_MMIO_TK1_GPIO2_BIT = 1,
TK1_MMIO_TK1_GPIO3_BIT = 2,
TK1_MMIO_TK1_GPIO4_BIT = 3,
TK1_MMIO_TK1_APP_ADDR = TK1_MMIO_TK1_BASE | 0x30, // 0x4000_0000
TK1_MMIO_TK1_APP_SIZE = TK1_MMIO_TK1_BASE | 0x34,
TK1_MMIO_TK1_CDI_FIRST = TK1_MMIO_TK1_BASE | 0x80,
TK1_MMIO_TK1_CDI_LAST = TK1_MMIO_TK1_BASE | 0x9c, // Address of last 32-bit word of CDI.
TK1_MMIO_TK1_UDI_FIRST = TK1_MMIO_TK1_BASE | 0xc0,
TK1_MMIO_TK1_UDI_LAST = TK1_MMIO_TK1_BASE | 0xc4, // Address of last 32-bit word of UDI.
};
#endif

View File

@ -49,7 +49,7 @@ module application_fpga(
localparam UART_PREFIX = 6'h03;
localparam TOUCH_SENSE_PREFIX = 6'h04;
localparam FW_RAM_PREFIX = 6'h10;
localparam MTA1_PREFIX = 6'h3f;
localparam TK1_PREFIX = 6'h3f;
//----------------------------------------------------------------
@ -141,13 +141,13 @@ module application_fpga(
wire touch_sense_ready;
/* verilator lint_off UNOPTFLAT */
reg mta1_cs;
reg tk1_cs;
/* verilator lint_on UNOPTFLAT */
reg mta1_we;
reg [7 : 0] mta1_address;
reg [31 : 0] mta1_write_data;
wire [31 : 0] mta1_read_data;
wire mta1_ready;
reg tk1_we;
reg [7 : 0] tk1_address;
reg [31 : 0] tk1_write_data;
wire [31 : 0] tk1_read_data;
wire tk1_ready;
wire fw_app_mode;
@ -310,7 +310,7 @@ module application_fpga(
);
mta1 mta1_inst(
tk1 tk1_inst(
.clk(clk),
.reset_n(reset_n),
@ -325,12 +325,12 @@ module application_fpga(
.gpio3(app_gpio3),
.gpio4(app_gpio4),
.cs(mta1_cs),
.we(mta1_we),
.address(mta1_address),
.write_data(mta1_write_data),
.read_data(mta1_read_data),
.ready(mta1_ready)
.cs(tk1_cs),
.we(tk1_we),
.address(tk1_address),
.write_data(tk1_write_data),
.read_data(tk1_read_data),
.ready(tk1_ready)
);
@ -402,10 +402,10 @@ module application_fpga(
touch_sense_we = |cpu_wstrb;
touch_sense_address = cpu_addr[9 : 2];
mta1_cs = 1'h0;
mta1_we = |cpu_wstrb;
mta1_address = cpu_addr[9 : 2];
mta1_write_data = cpu_wdata;
tk1_cs = 1'h0;
tk1_we = |cpu_wstrb;
tk1_address = cpu_addr[9 : 2];
tk1_write_data = cpu_wdata;
if (cpu_valid && !muxed_ready_reg) begin
case (area_prefix)
@ -464,10 +464,10 @@ module application_fpga(
muxed_ready_new = fw_ram_ready;
end
MTA1_PREFIX: begin
mta1_cs = 1'h1;
muxed_rdata_new = mta1_read_data;
muxed_ready_new = mta1_ready;
TK1_PREFIX: begin
tk1_cs = 1'h1;
muxed_rdata_new = tk1_read_data;
muxed_ready_new = tk1_ready;
end
default: begin

View File

@ -65,7 +65,7 @@ module application_fpga(
localparam UDS_PREFIX = 6'h02;
localparam UART_PREFIX = 6'h03;
localparam TOUCH_SENSE_PREFIX = 6'h04;
localparam MTA1_PREFIX = 6'h3f;
localparam TK1_PREFIX = 6'h3f;
//----------------------------------------------------------------
@ -145,13 +145,13 @@ module application_fpga(
wire touch_sense_ready;
/* verilator lint_off UNOPTFLAT */
reg mta1_cs;
reg tk1_cs;
/* verilator lint_on UNOPTFLAT */
reg mta1_we;
reg [7 : 0] mta1_address;
reg [31 : 0] mta1_write_data;
wire [31 : 0] mta1_read_data;
wire mta1_ready;
reg tk1_we;
reg [7 : 0] tk1_address;
reg [31 : 0] tk1_write_data;
wire [31 : 0] tk1_read_data;
wire tk1_ready;
wire fw_app_mode;
@ -296,7 +296,7 @@ module application_fpga(
);
mta1 mta1_inst(
tk1 tk1_inst(
.clk(clk),
.reset_n(reset_n),
@ -311,12 +311,12 @@ module application_fpga(
.gpio3(app_gpio3),
.gpio4(app_gpio4),
.cs(mta1_cs),
.we(mta1_we),
.address(mta1_address),
.write_data(mta1_write_data),
.read_data(mta1_read_data),
.ready(mta1_ready)
.cs(tk1_cs),
.we(tk1_we),
.address(tk1_address),
.write_data(tk1_write_data),
.read_data(tk1_read_data),
.ready(tk1_ready)
);
@ -383,10 +383,10 @@ module application_fpga(
touch_sense_we = |cpu_wstrb;
touch_sense_address = cpu_addr[9 : 2];
mta1_cs = 1'h0;
mta1_we = |cpu_wstrb;
mta1_address = cpu_addr[9 : 2];
mta1_write_data = cpu_wdata;
tk1_cs = 1'h0;
tk1_we = |cpu_wstrb;
tk1_address = cpu_addr[9 : 2];
tk1_write_data = cpu_wdata;
if (cpu_valid && !muxed_ready_reg) begin
case (area_prefix)
@ -448,11 +448,11 @@ module application_fpga(
muxed_ready_new = touch_sense_ready;
end
MTA1_PREFIX: begin
`verbose($display("Access to MTA1 core");)
mta1_cs = 1'h1;
muxed_rdata_new = mta1_read_data;
muxed_ready_new = mta1_ready;
TK1_PREFIX: begin
`verbose($display("Access to TK1 core");)
tk1_cs = 1'h1;
muxed_rdata_new = tk1_read_data;
muxed_ready_new = tk1_ready;
end
default: begin