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 application. This allows users to build and load their own apps, while
ensuring that each app loaded will have its own cryptographic ensuring that each app loaded will have its own cryptographic
identity. The design is similar to TCG DICE. The Tillitis Key 1 identity. The design is similar to TCG DICE. The Tillitis Key 1
platform has 128 KB of RAM. The current firmware design allows for platform has 128 KB of RAM. The current firmware is designed to load
applications up to 64 KB with a 64 KB stack. 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](doc/images/mta1-usb-v1.jpg)
*Tillitis Key 1 PCB, first implementation* *Tillitis Key 1 PCB, first implementation*

View File

@ -63,7 +63,9 @@ between the host and the device.
## Firmware ## Firmware
The device has 128 KB RAM. The current firmware loads the app at the 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 The firmware is part of FPGA bitstream (ROM), and is loaded at
`0x0000_0000`. `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 The PicoRV32 starts executing at `0x0000_0000`. Our firmware starts at
`_start` from `start.S` which initializes the `.data`, and `.bss` at `_start` from `start.S` which initializes the `.data`, and `.bss` at
`0x4000_0000` and upwards. A stack is also initialized, starting 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 firmware waits for incoming commands from the host, by busy-polling
the `UART_RX_{STATUS,DATA}` registers. When a complete command is the `UART_RX_{STATUS,DATA}` registers. When a complete command is
read, the firmware executes the command. 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. | | | | | | | | returns 0 if device is in firmware mode, 0xffffffff if in app mode. |
| `LED` | w | w | 1B | u8 | | | | `LED` | w | w | 1B | u8 | | |
| `GPIO` | | | | | | | | `GPIO` | | | | | | |
| `APP_ADDR` | r/w | r | 4B | u32 | | Application address (0x4000_0000) | | `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 | | Application size | | `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_FIRST` | r/w | r | 32B | u8[32] | | Compound Device Identifier (CDI). UDS+measurement... |
| `CDI_LAST` | | r | | | | Last word of CDI | | `CDI_LAST` | | r | | | | Last word of CDI |

View File

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

View File

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

View File

@ -20,10 +20,14 @@
enum { enum {
TK1_ROM_BASE = 0x00000000, // 0b00000000... TK1_ROM_BASE = 0x00000000, // 0b00000000...
TK1_RAM_BASE = 0x40000000, // 0b01000000... TK1_RAM_BASE = 0x40000000, // 0b01000000...
TK1_RAM_SIZE = 0x20000, // 128 KB
TK1_RESERVED_BASE = 0x80000000, // 0b10000000... TK1_RESERVED_BASE = 0x80000000, // 0b10000000...
TK1_MMIO_BASE = 0xc0000000, // 0b11000000... TK1_MMIO_BASE = 0xc0000000, // 0b11000000...
TK1_MMIO_SIZE = 0xffffffff - TK1_MMIO_BASE, 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_TRNG_BASE = TK1_MMIO_BASE | 0x00000000,
TK1_MMIO_TIMER_BASE = TK1_MMIO_BASE | 0x01000000, TK1_MMIO_TIMER_BASE = TK1_MMIO_BASE | 0x01000000,
TK1_MMIO_UDS_BASE = TK1_MMIO_BASE | 0x02000000, TK1_MMIO_UDS_BASE = TK1_MMIO_BASE | 0x02000000,
@ -81,7 +85,7 @@ enum {
TK1_MMIO_TK1_GPIO2_BIT = 1, TK1_MMIO_TK1_GPIO2_BIT = 1,
TK1_MMIO_TK1_GPIO3_BIT = 2, TK1_MMIO_TK1_GPIO3_BIT = 2,
TK1_MMIO_TK1_GPIO4_BIT = 3, 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_APP_SIZE = TK1_MMIO_TK1_BASE | 0x34,
TK1_MMIO_TK1_CDI_FIRST = TK1_MMIO_TK1_BASE | 0x80, 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_CDI_LAST = TK1_MMIO_TK1_BASE | 0x9c, // Address of last 32-bit word of CDI.