From a0ce957f10cb8051eb9a1e12f8c3486636bbd037 Mon Sep 17 00:00:00 2001 From: Daniel Jobson Date: Fri, 30 Aug 2024 14:58:19 +0200 Subject: [PATCH] WIP partition table --- hw/application_fpga/Makefile | 12 ++- hw/application_fpga/fw/tk1/main.c | 6 ++ hw/application_fpga/fw/tk1/partition_table.c | 50 +++++++++ hw/application_fpga/fw/tk1/partition_table.h | 105 +++++++++++++++++++ 4 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 hw/application_fpga/fw/tk1/partition_table.c create mode 100644 hw/application_fpga/fw/tk1/partition_table.h diff --git a/hw/application_fpga/Makefile b/hw/application_fpga/Makefile index cf23242..fee21f3 100644 --- a/hw/application_fpga/Makefile +++ b/hw/application_fpga/Makefile @@ -109,7 +109,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 \ @@ -120,7 +124,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 \ @@ -130,7 +135,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 5ae6155..3251a0f 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,8 +421,12 @@ int main(void) /*@+mustfreeonly@*/ ctx.use_uss = false; + readbyte(); + scramble_ram(); + part_table_read(&part_table); + for (;;) { switch (state) { case FW_STATE_INITIAL: 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..b202f78 --- /dev/null +++ b/hw/application_fpga/fw/tk1/partition_table.c @@ -0,0 +1,50 @@ +// 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_read(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)); + + // TODO: Implement redundancy and consistency check + + if (part_table->header.version != PART_TABLE_VERSION) { + // Partition table is not ours. Make a new one, and store it. + memset(part_table, 0x00, sizeof(*part_table)); + + part_table->header.version = PART_TABLE_VERSION; + + 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..7a3c390 --- /dev/null +++ b/hw/application_fpga/fw/tk1/partition_table.h @@ -0,0 +1,105 @@ +// Copyright (C) 2024 - Tillitis AB +// SPDX-License-Identifier: GPL-2.0-only + +#ifndef PARTITION_TABLE_H +#define PARTITION_TABLE_H + +#include + +/* ---- Flash ---- ---- */ +/* name size start addr */ +/* ---- ---- ---- */ +/* bitstream 128KiB 0x00 */ +/* ---- ---- ---- */ +/* Partition 64KiB 0x20000 */ +/* ---- ---- ---- */ +/* Pre load 128KiB 0x30000 */ +/* ---- ---- ---- */ +/* storage 1 128KiB 0x50000 */ +/* storage 2 128KiB 0x70000 */ +/* storage 3 128KiB 0x90000 */ +/* storage 4 128KiB 0xB0000 */ +/* ---- ---- ---- */ + +/* To simplify all blocks are aligned with the 64KiB blocks on the W25Q80DL + * flash. */ + +#define PART_TABLE_VERSION 1 + +#define ADDR_BITSTREAM 0UL +#define SIZE_BITSTREAM 0x20000UL // 128KiB + +#define ADDR_PARTITION_TABLE (ADDR_BITSTREAM + SIZE_BITSTREAM) +#define SIZE_PARTITION_TABLE \ + 0x10000UL // 64KiB, 60 KiB reserved, 2 flash pages (2 x 4KiB) for the + // partition table + +#define ADDR_PRE_LOADED_APP (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE) +#define SIZE_PRE_LOADED_APP 0x20000UL // 128KiB + +#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + SIZE_PRE_LOADED_APP) +#define SIZE_STORAGE_AREA 0x20000UL // 128KiB +#define N_STORAGE_AREA 4 + +#define EMPTY_AREA + +/* Partition Table */ +/*- Table header */ +/* - 1 bytes Version */ +/**/ +/*- Management device app */ +/* - Status. */ +/* - 16 byte random nonce. */ +/* - 16 byte authentication digest. */ +/**/ +/*- Pre-loaded device app */ +/* - 1 byte status. */ +/* - 4 bytes length. */ +/* - 16 bytes random nonce. */ +/* - 16 bytes authentication digest. */ +/**/ +/*- Device app storage area */ +/* - 1 byte status. */ +/* - 16 bytes random nonce. */ +/* - 16 bytes authentication tag. */ +/* - 4 bytes physical start address. */ +/* - 4 bytes physical end address. */ + +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; +} table_header_t; + +typedef struct __attribute__((packed)) { + table_header_t header; + 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_read(partition_table_t *part_table); +int part_table_write(partition_table_t *part_table); + +#endif