diff --git a/hw/application_fpga/Makefile b/hw/application_fpga/Makefile index e9f8696..4ba722e 100644 --- a/hw/application_fpga/Makefile +++ b/hw/application_fpga/Makefile @@ -84,7 +84,11 @@ FIRMWARE_DEPS = \ $(P)/fw/tk1/lib.h \ $(P)/fw/tk1/proto.h \ $(P)/fw/tk1/assert.h \ - $(P)/fw/tk1/led.h + $(P)/fw/tk1/led.h \ + $(P)/fw/tk1/blake2s/blake2s.h \ + $(P)/fw/tk1/spi.h \ + $(P)/fw/tk1/flash.h \ + $(P)/fw/tk1/partition_table.h FIRMWARE_OBJS = \ $(P)/fw/tk1/main.o \ @@ -95,7 +99,8 @@ FIRMWARE_OBJS = \ $(P)/fw/tk1/led.o \ $(P)/fw/tk1/blake2s/blake2s.o \ $(P)/fw/tk1/spi.o \ - $(P)/fw/tk1/flash.o + $(P)/fw/tk1/flash.o \ + $(P)/fw/tk1/partition_table.o FIRMWARE_SOURCES = \ $(P)/fw/tk1/main.c \ @@ -105,7 +110,8 @@ FIRMWARE_SOURCES = \ $(P)/fw/tk1/led.c \ $(P)/fw/tk1/blake2s/blake2s.c \ $(P)/fw/tk1/spi.c \ - $(P)/fw/tk1/flash.c + $(P)/fw/tk1/flash.c \ + $(P)/fw/tk1/partition_table.c TESTFW_OBJS = \ $(P)/fw/testfw/main.o \ diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index fe2abfc..0f7db4f 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -7,6 +7,7 @@ #include "assert.h" #include "blake2s/blake2s.h" #include "lib.h" +#include "partition_table.h" #include "proto.h" #include "state.h" @@ -405,6 +406,7 @@ int main(void) struct frame_header hdr = {0}; uint8_t cmd[CMDLEN_MAXBYTES] = {0}; enum state state = FW_STATE_INITIAL; + partition_table_t part_table; print_hw_version(); @@ -419,7 +421,10 @@ int main(void) /*@+mustfreeonly@*/ ctx.use_uss = false; + readbyte(); + scramble_ram(); + part_table_init(&part_table); for (;;) { switch (state) { diff --git a/hw/application_fpga/fw/tk1/partition_table.c b/hw/application_fpga/fw/tk1/partition_table.c new file mode 100644 index 0000000..8e2b591 --- /dev/null +++ b/hw/application_fpga/fw/tk1/partition_table.c @@ -0,0 +1,48 @@ +// Copyright (C) 2024 - Tillitis AB +// SPDX-License-Identifier: GPL-2.0-only + +#include "partition_table.h" +#include "flash.h" +#include "lib.h" +#include "proto.h" + +#include + +int part_table_init(partition_table_t *part_table) +{ + // Read from flash, if it exists, otherwise create a new one. + + flash_release_powerdown(); + memset(part_table, 0x00, sizeof(*part_table)); + + flash_read_data(ADDR_PARTITION_TABLE, (uint8_t *)part_table, + sizeof(*part_table)); + + if (part_table->version != PART_TABLE_VER) { + // Partition table is not ours. Make a new one, and store it. + memset(part_table, 0x00, sizeof(*part_table)); + + part_table->version = PART_TABLE_VER; + + for (int i = 0; i < 4; i++) { + part_table->app_storage[i].addr_start = + (ADDR_STORAGE_AREA + i * SIZE_STORAGE_AREA); + part_table->app_storage[i].size = SIZE_STORAGE_AREA; + } + + part_table_write(part_table); + } + + // Now the partition table is synced between flash and RAM. + + return 0; +} + +int part_table_write(partition_table_t *part_table) +{ + flash_sector_erase(ADDR_PARTITION_TABLE); + flash_write_data(ADDR_PARTITION_TABLE, (uint8_t *)part_table, + sizeof(*part_table)); + + return 0; +} diff --git a/hw/application_fpga/fw/tk1/partition_table.h b/hw/application_fpga/fw/tk1/partition_table.h new file mode 100644 index 0000000..d70f032 --- /dev/null +++ b/hw/application_fpga/fw/tk1/partition_table.h @@ -0,0 +1,79 @@ +// Copyright (C) 2024 - Tillitis AB +// SPDX-License-Identifier: GPL-2.0-only + +#ifndef PARTITION_TABLE_H +#define PARTITION_TABLE_H + + +#include + +#define PART_TABLE_VER 1 + +#define ADDR_BITSTREAM 0UL +#define SIZE_BITSTREAM 0x20000UL + +#define ADDR_PARTITION_TABLE (ADDR_BITSTREAM + SIZE_BITSTREAM) +#define SIZE_PARTITION_TABLE 0x3000UL /* 3 flash sectors */ + +#define ADDR_PRE_LOADED_APP (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE) +#define SIZE_PRE_LOADED_APP 0x20000UL + +#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + SIZE_PARTITION_TABLE) +#define SIZE_STORAGE_AREA 0x1F000UL +#define N_STORAGE_AREA 4 + +/*- Table header*/ +/* - 4 bytes Version*/ +/**/ +/*- Management device app*/ +/* - Status - Registered or not.*/ +/* - 16 byte random nonce.*/ +/* - 16 byte authentication digest.*/ +/**/ +/*- Pre-loaded device app*/ +/* - 1 byte status - Pre-loaded device app exists or not. Active or not.*/ +/* - 4 bytes length of pre-loaded device app in bytes.*/ +/* - 16 bytes random nonce.*/ +/* - 16 bytes authentication digest.*/ +/**/ +/*- Device app storage area*/ +/* - 1 byte status - Allocated or not.*/ +/* - 16 bytes random nonce.*/ +/* - 16 bytes authentication tag.*/ +/* - 4 bytes physical start address in the persistent store.*/ +/* - 4 bytes physical end address in the persistent store.*/ + +typedef struct __attribute__((packed)) { + uint8_t nonce[16]; + uint8_t authentication_digest[16]; +} auth_metadata_t; + +typedef struct __attribute__((packed)) { + uint8_t status; + auth_metadata_t auth; +} management_app_metadata_t; + +typedef struct __attribute__((packed)) { + uint8_t status; + uint32_t size; + auth_metadata_t auth; +} pre_loaded_app_metadata_t; + +typedef struct __attribute__((packed)) { + uint8_t status; + auth_metadata_t auth; + uint32_t addr_start; + uint32_t size; +} app_storage_area_t; + +typedef struct __attribute__((packed)) { + uint8_t version; + management_app_metadata_t mgmt_app_data; + pre_loaded_app_metadata_t pre_app_data; + app_storage_area_t app_storage[N_STORAGE_AREA]; +} partition_table_t; + +int part_table_init(partition_table_t *part_table); +int part_table_write(partition_table_t *part_table); + +#endif