fw: Introduce reset()

- New function reset.c:reset(). Move code from syscall handler switch
  to this function.

- Rename resetinfo.h to reset.h.
This commit is contained in:
Michael Cardell Widerkrantz 2025-04-29 17:10:19 +02:00
parent 9d1bbffbaa
commit c2fd52ab1a
No known key found for this signature in database
GPG key ID: D3DB3DDF57E704E5
9 changed files with 55 additions and 34 deletions

View file

@ -134,6 +134,7 @@ FIRMWARE_OBJS = \
$(P)/fw/tk1/partition_table.o \ $(P)/fw/tk1/partition_table.o \
$(P)/fw/tk1/auth_app.o \ $(P)/fw/tk1/auth_app.o \
$(P)/fw/tk1/rng.o \ $(P)/fw/tk1/rng.o \
$(P)/fw/tk1/reset.o \
$(P)/fw/tk1/preload_app.o \ $(P)/fw/tk1/preload_app.o \
$(P)/fw/tk1/mgmt_app.o $(P)/fw/tk1/mgmt_app.o

View file

@ -534,8 +534,9 @@ struct reset {
}; };
struct reset rst; 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. 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 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 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* | | *Name* | *Comment* |
|--------------------|------------------------------------------------| |--------------------|------------------------------------------------|

View file

@ -13,7 +13,7 @@
#include "../testapp/syscall.h" #include "../testapp/syscall.h"
#include "../tk1/proto.h" #include "../tk1/proto.h"
#include "../tk1/resetinfo.h" #include "../tk1/reset.h"
#include "../tk1/syscall_num.h" #include "../tk1/syscall_num.h"
// Converts a single hex character to its integer value // Converts a single hex character to its integer value

View file

@ -11,7 +11,7 @@
#include <tkey/tk1_mem.h> #include <tkey/tk1_mem.h>
#include "../tk1/proto.h" #include "../tk1/proto.h"
#include "../tk1/resetinfo.h" #include "../tk1/reset.h"
#include "../tk1/syscall_num.h" #include "../tk1/syscall_num.h"
#include "syscall.h" #include "syscall.h"

View file

@ -7,7 +7,7 @@
#include <tkey/tk1_mem.h> #include <tkey/tk1_mem.h>
#include "../testapp/syscall.h" #include "../testapp/syscall.h"
#include "../tk1/resetinfo.h" #include "../tk1/reset.h"
#include "../tk1/syscall_num.h" #include "../tk1/syscall_num.h"
#include "blink.h" #include "blink.h"
#include "tkey/assert.h" #include "tkey/assert.h"

View file

@ -17,7 +17,7 @@
#include "partition_table.h" #include "partition_table.h"
#include "preload_app.h" #include "preload_app.h"
#include "proto.h" #include "proto.h"
#include "resetinfo.h" #include "reset.h"
#include "state.h" #include "state.h"
#include "syscall_enable.h" #include "syscall_enable.h"

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2025 - Tillitis AB
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <stdint.h>
#include <tkey/assert.h>
#include <tkey/lib.h>
#include <tkey/tk1_mem.h>
#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();
}

View file

@ -1,8 +1,8 @@
// Copyright (C) 2025 - Tillitis AB // Copyright (C) 2025 - Tillitis AB
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#ifndef TKEY_RESETINFO_H #ifndef TKEY_RESET_H
#define TKEY_RESETINFO_H #define TKEY_RESET_H
#include <stdint.h> #include <stdint.h>
@ -25,4 +25,5 @@ struct reset {
uint8_t next_app_data[220]; // Data to leave around for next app uint8_t next_app_data[220]; // Data to leave around for next app
}; };
int reset(struct reset *userreset, size_t nextlen);
#endif #endif

View file

@ -13,13 +13,11 @@
#include "preload_app.h" #include "preload_app.h"
#include "storage.h" #include "storage.h"
#include "../tk1/resetinfo.h" #include "../tk1/reset.h"
#include "../tk1/syscall_num.h" #include "../tk1/syscall_num.h"
// clang-format off // 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 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 // clang-format on
extern struct partition_table_storage part_table_storage; extern struct partition_table_storage part_table_storage;
@ -30,29 +28,7 @@ int32_t syscall_handler(uint32_t number, uint32_t arg1, uint32_t arg2,
{ {
switch (number) { switch (number) {
case TK1_SYSCALL_RESET: { case TK1_SYSCALL_RESET: {
struct reset *userreset; reset((struct reset *)arg1, (size_t)arg2);
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);
break; break;
} }