Change to max 100 KB app with 28 KB stack

This commit is contained in:
Daniel Lublin 2022-10-31 15:02:48 +01:00
parent fdda69745e
commit a14662c622
No known key found for this signature in database
GPG Key ID: 75BD0FEB8D3E7830
5 changed files with 24 additions and 20 deletions

View File

@ -18,8 +18,9 @@ user-provided seed, is used to derive key material unique to each
application. This allows users to build and load their own apps, while
ensuring that each app loaded will have its own cryptographic
identity. The design is similar to TCG DICE. The Tillitis Key 1
platform has 128 KB of RAM. The current firmware design allows for
applications up to 64 KB with a 64 KB stack.
platform has 128 KB of RAM. The current firmware is designed to load
an app that is up to 100 KB in size, and gives it a stack of 28 KB. A
smaller ap may move itself in memory, in order to have a larger stack.
![Tillitis Key 1 PCB, first implementation](doc/images/mta1-usb-v1.jpg)
*Tillitis Key 1 PCB, first implementation*

View File

@ -63,7 +63,9 @@ between the host and the device.
## Firmware
The device has 128 KB RAM. The current firmware loads the app at the
upper 64 KB. The lower 64 KB is currently set up as stack for the app.
upper 100 KB. The lower 28 KB is set up as stack for the app. A
smaller app that wants a larger stack could relocate itself on
startup.
The firmware is part of FPGA bitstream (ROM), and is loaded at
`0x0000_0000`.
@ -73,7 +75,7 @@ The firmware is part of FPGA bitstream (ROM), and is loaded at
The PicoRV32 starts executing at `0x0000_0000`. Our firmware starts at
`_start` from `start.S` which initializes the `.data`, and `.bss` at
`0x4000_0000` and upwards. A stack is also initialized, starting at
0x4000_fff0 and downwards. When the initialization is finished, the
0x4000_6ff0 and downwards. When the initialization is finished, the
firmware waits for incoming commands from the host, by busy-polling
the `UART_RX_{STATUS,DATA}` registers. When a complete command is
read, the firmware executes the command.
@ -355,8 +357,8 @@ Assigned core prefixes:
| | | | | | | returns 0 if device is in firmware mode, 0xffffffff if in app mode. |
| `LED` | w | w | 1B | u8 | | |
| `GPIO` | | | | | | |
| `APP_ADDR` | r/w | r | 4B | u32 | | Application address (0x4000_0000) |
| `APP_SIZE` | r/w | r | 4B | u32 | | Application size |
| `APP_ADDR` | r/w | r | 4B | u32 | | Firmware stores app load address here, so app can read its own location|
| `APP_SIZE` | r/w | r | 4B | u32 | | Firmware stores app app size here, so app can read its own size |
| `CDI_FIRST` | r/w | r | 32B | u8[32] | | Compound Device Identifier (CDI). UDS+measurement... |
| `CDI_LAST` | | r | | | | Last word of CDI |

View File

@ -9,10 +9,6 @@
#include "proto.h"
#include "types.h"
// In RAM + above the stack (0x40010000)
#define APP_RAM_ADDR (TK1_RAM_BASE + 0x10000)
#define APP_MAX_SIZE 65536
// clang-format off
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;
@ -95,7 +91,7 @@ int main()
struct frame_header hdr; // Used in both directions
uint8_t cmd[CMDLEN_MAXBYTES];
uint8_t rsp[CMDLEN_MAXBYTES];
uint8_t *loadaddr = (uint8_t *)APP_RAM_ADDR;
uint8_t *loadaddr = (uint8_t *)TK1_APP_ADDR;
int left = 0; // Bytes left to receive
uint8_t uss[32] = {0};
uint8_t digest[32] = {0};
@ -177,7 +173,7 @@ int main()
putinthex(local_app_size);
lf();
if (local_app_size > APP_MAX_SIZE) {
if (local_app_size > TK1_APP_MAX_SIZE) {
rsp[0] = STATUS_BAD;
fwreply(hdr, FW_RSP_LOAD_APP_SIZE, rsp);
break;
@ -190,7 +186,7 @@ int main()
memset(digest, 0, 32);
// Reset where to start loading the program
loadaddr = (uint8_t *)APP_RAM_ADDR;
loadaddr = (uint8_t *)TK1_APP_ADDR;
left = *app_size;
rsp[0] = STATUS_OK;
@ -224,7 +220,7 @@ int main()
putinthex(*app_size);
lf();
*app_addr = APP_RAM_ADDR;
*app_addr = TK1_APP_ADDR;
// Get the Blake2S digest of the app - store it
// for later queries
blake2s_ctx ctx;
@ -266,8 +262,9 @@ int main()
lf();
// clang-format off
asm volatile(
// Clear the stack
"li a0, 0x40000000;" // TK1_RAM_BASE
"li a1, 0x40010000;"
"li a1, 0x40007000;" // APP_RAM_ADDR
"loop:;"
"sw zero, 0(a0);"
"addi a0, a0, 4;"

View File

@ -39,15 +39,15 @@ _start:
li x31,0
/* Clear all RAM */
li a0, 0x40000000 // RAM base
li a1, 0x40020000 // To end of SRAM
li a0, 0x40000000 // TK1_RAM_BASE
li a1, 0x40020000 // TK1_RAM_BASE + TK1_RAM_SIZE
clear:
sw zero, 0(a0)
addi a0, a0, 4
blt a0, a1, clear
/* init stack to right under where we load app at 0x40010000 */
li sp, 0x4000fff0
/* init stack below 0x40007000 (TK1_APP_ADDR) where we load app */
li sp, 0x40006ff0
/* copy data section */
la a0, _sidata

View File

@ -20,10 +20,14 @@
enum {
TK1_ROM_BASE = 0x00000000, // 0b00000000...
TK1_RAM_BASE = 0x40000000, // 0b01000000...
TK1_RAM_SIZE = 0x20000, // 128 KB
TK1_RESERVED_BASE = 0x80000000, // 0b10000000...
TK1_MMIO_BASE = 0xc0000000, // 0b11000000...
TK1_MMIO_SIZE = 0xffffffff - TK1_MMIO_BASE,
TK1_APP_ADDR = TK1_RAM_BASE + 0x7000, // 28 KB of stack
TK1_APP_MAX_SIZE = TK1_RAM_SIZE - (TK1_APP_ADDR - TK1_RAM_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,
@ -81,7 +85,7 @@ enum {
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_ADDR = TK1_MMIO_TK1_BASE | 0x30,
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.