From a14662c622deecf974c3d555ef6cf45a4aa3ecb1 Mon Sep 17 00:00:00 2001 From: Daniel Lublin Date: Mon, 31 Oct 2022 15:02:48 +0100 Subject: [PATCH] Change to max 100 KB app with 28 KB stack --- README.md | 5 +++-- doc/system_description/software.md | 10 ++++++---- hw/application_fpga/fw/tk1/main.c | 15 ++++++--------- hw/application_fpga/fw/tk1/start.S | 8 ++++---- hw/application_fpga/fw/tk1_mem.h | 6 +++++- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f14acd7..77d2ed8 100644 --- a/README.md +++ b/README.md @@ -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* diff --git a/doc/system_description/software.md b/doc/system_description/software.md index 9e92ddf..3589912 100644 --- a/doc/system_description/software.md +++ b/doc/system_description/software.md @@ -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 | diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index b8ea921..19de43d 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -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;" diff --git a/hw/application_fpga/fw/tk1/start.S b/hw/application_fpga/fw/tk1/start.S index 2a327bb..0b7d139 100644 --- a/hw/application_fpga/fw/tk1/start.S +++ b/hw/application_fpga/fw/tk1/start.S @@ -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 diff --git a/hw/application_fpga/fw/tk1_mem.h b/hw/application_fpga/fw/tk1_mem.h index 9567a5a..dcd341b 100644 --- a/hw/application_fpga/fw/tk1_mem.h +++ b/hw/application_fpga/fw/tk1_mem.h @@ -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.