diff --git a/hw/application_fpga/Makefile b/hw/application_fpga/Makefile index e7ab9f4..8a27968 100644 --- a/hw/application_fpga/Makefile +++ b/hw/application_fpga/Makefile @@ -134,6 +134,7 @@ FIRMWARE_OBJS = \ $(P)/fw/tk1/partition_table.o \ $(P)/fw/tk1/auth_app.o \ $(P)/fw/tk1/rng.o \ + $(P)/fw/tk1/reset.o \ $(P)/fw/tk1/preload_app.o \ $(P)/fw/tk1/mgmt_app.o diff --git a/hw/application_fpga/fw/README.md b/hw/application_fpga/fw/README.md index aed25a9..9058514 100644 --- a/hw/application_fpga/fw/README.md +++ b/hw/application_fpga/fw/README.md @@ -534,8 +534,9 @@ struct reset { }; struct reset rst; +uint32_t len; // Length of data in next_app_data. -syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0); +syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, len, 0); ``` Resets the TKey. Does not return. @@ -544,7 +545,7 @@ You can pass data to the firmware about the reset type `type` and a digest that the next app must have. You can also leave some data to the next app in the chain in `next_app_data`. -The types of the reset are defined in `resetinfo.h`: +The types of the reset are defined in `reset.h`: | *Name* | *Comment* | |--------------------|------------------------------------------------| diff --git a/hw/application_fpga/fw/reset_test/main.c b/hw/application_fpga/fw/reset_test/main.c index 154e24d..2be91cb 100644 --- a/hw/application_fpga/fw/reset_test/main.c +++ b/hw/application_fpga/fw/reset_test/main.c @@ -13,7 +13,7 @@ #include "../testapp/syscall.h" #include "../tk1/proto.h" -#include "../tk1/resetinfo.h" +#include "../tk1/reset.h" #include "../tk1/syscall_num.h" // Converts a single hex character to its integer value diff --git a/hw/application_fpga/fw/testapp/main.c b/hw/application_fpga/fw/testapp/main.c index 5619ebd..be4e6bc 100644 --- a/hw/application_fpga/fw/testapp/main.c +++ b/hw/application_fpga/fw/testapp/main.c @@ -11,7 +11,7 @@ #include #include "../tk1/proto.h" -#include "../tk1/resetinfo.h" +#include "../tk1/reset.h" #include "../tk1/syscall_num.h" #include "syscall.h" diff --git a/hw/application_fpga/fw/testloadapp/main.c b/hw/application_fpga/fw/testloadapp/main.c index 01dbd8b..f3ccd3c 100644 --- a/hw/application_fpga/fw/testloadapp/main.c +++ b/hw/application_fpga/fw/testloadapp/main.c @@ -7,7 +7,7 @@ #include #include "../testapp/syscall.h" -#include "../tk1/resetinfo.h" +#include "../tk1/reset.h" #include "../tk1/syscall_num.h" #include "blink.h" #include "tkey/assert.h" diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index 3cbcc1f..ae577af 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -17,7 +17,7 @@ #include "partition_table.h" #include "preload_app.h" #include "proto.h" -#include "resetinfo.h" +#include "reset.h" #include "state.h" #include "syscall_enable.h" diff --git a/hw/application_fpga/fw/tk1/reset.c b/hw/application_fpga/fw/tk1/reset.c new file mode 100644 index 0000000..4f37429 --- /dev/null +++ b/hw/application_fpga/fw/tk1/reset.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2025 - Tillitis AB + * SPDX-License-Identifier: GPL-2.0-only + */ + +#include +#include +#include +#include + +#include "reset.h" + +// clang-format off +static volatile uint32_t *system_reset = (volatile uint32_t *)TK1_MMIO_TK1_SYSTEM_RESET; +static volatile struct reset *resetinfo = (volatile struct reset *)TK1_MMIO_RESETINFO_BASE; +// clang-format on + +int reset(struct reset *userreset, size_t nextlen) +{ + if ((uint32_t)userreset < TK1_RAM_BASE || + (uint32_t)userreset >= TK1_RAM_BASE + TK1_RAM_SIZE) { + return -1; + } + + if (nextlen > sizeof(resetinfo->next_app_data)) { + return -1; + } + + (void)memset((void *)resetinfo, 0, sizeof(*resetinfo)); + resetinfo->type = userreset->type; + memcpy((void *)resetinfo->app_digest, userreset->app_digest, 32); + memcpy((void *)resetinfo->next_app_data, userreset->next_app_data, + nextlen); + + // Do the actual reset. + *system_reset = 1; + + // Should not be reached. + assert(1 == 2); + + __builtin_unreachable(); +} diff --git a/hw/application_fpga/fw/tk1/resetinfo.h b/hw/application_fpga/fw/tk1/reset.h similarity index 82% rename from hw/application_fpga/fw/tk1/resetinfo.h rename to hw/application_fpga/fw/tk1/reset.h index 0a26ace..a434d38 100644 --- a/hw/application_fpga/fw/tk1/resetinfo.h +++ b/hw/application_fpga/fw/tk1/reset.h @@ -1,9 +1,10 @@ // Copyright (C) 2025 - Tillitis AB // SPDX-License-Identifier: GPL-2.0-only -#ifndef TKEY_RESETINFO_H -#define TKEY_RESETINFO_H +#ifndef TKEY_RESET_H +#define TKEY_RESET_H +#include #include #define TK1_MMIO_RESETINFO_BASE 0xd0000f00 @@ -25,4 +26,5 @@ struct reset { uint8_t next_app_data[220]; // Data to leave around for next app }; +int reset(struct reset *userreset, size_t nextlen); #endif diff --git a/hw/application_fpga/fw/tk1/syscall_handler.c b/hw/application_fpga/fw/tk1/syscall_handler.c index a042966..18bba35 100644 --- a/hw/application_fpga/fw/tk1/syscall_handler.c +++ b/hw/application_fpga/fw/tk1/syscall_handler.c @@ -13,13 +13,11 @@ #include "preload_app.h" #include "storage.h" -#include "../tk1/resetinfo.h" +#include "../tk1/reset.h" #include "../tk1/syscall_num.h" // clang-format off -static volatile uint32_t *system_reset = (volatile uint32_t *)TK1_MMIO_TK1_SYSTEM_RESET; static volatile uint32_t *udi = (volatile uint32_t *)TK1_MMIO_TK1_UDI_FIRST; -static volatile struct reset *resetinfo = (volatile struct reset *)TK1_MMIO_RESETINFO_BASE; // clang-format on extern struct partition_table_storage part_table_storage; @@ -29,32 +27,9 @@ int32_t syscall_handler(uint32_t number, uint32_t arg1, uint32_t arg2, uint32_t arg3) { switch (number) { - case TK1_SYSCALL_RESET: { - struct reset *userreset; - - if (arg1 < TK1_RAM_BASE || - arg1 >= TK1_RAM_BASE + TK1_RAM_SIZE) { - return -1; - } - - userreset = (struct reset *)arg1; - - if (arg2 > sizeof(resetinfo->next_app_data)) { - return -1; - } - - (void)memset((void *)resetinfo, 0, sizeof(*resetinfo)); - resetinfo->type = userreset->type; - memcpy((void *)resetinfo->app_digest, userreset->app_digest, - 32); - memcpy((void *)resetinfo->next_app_data, - userreset->next_app_data, arg2); - *system_reset = 1; - - // Should not be reached. - assert(1 == 2); + case TK1_SYSCALL_RESET: + reset((struct reset *)arg1, (size_t)arg2); break; - } case TK1_SYSCALL_ALLOC_AREA: if (storage_allocate_area(&part_table_storage) < 0) {