1414#include "htool.h"
1515#include "htool_cmd.h"
1616#include "protocol/dfu_hostcmd.h"
17+ #include "protocol/opentitan_version.h"
18+
19+ void process_image (struct libhoth_device * dev , const uint8_t * image , struct opentitan_image_version * rom_ext , struct opentitan_image_version * app , struct opentitan_get_version_resp * resp ) {
20+
21+ // Extract the offset that contains the ROM_EXT version information
22+ uint32_t offset = (image [OPENTITAN_OFFSET_HEADER_DATA ] | image [OPENTITAN_OFFSET_HEADER_DATA + 1 ] << 8 | image [OPENTITAN_OFFSET_HEADER_DATA + 2 ] << 16 | image [OPENTITAN_OFFSET_HEADER_DATA + 3 ] << 24 );
23+ rom_ext -> major = image [offset + OPENTITAN_OFFSET_VERSION_MAJOR ] | image [offset + OPENTITAN_OFFSET_VERSION_MAJOR + 1 ] << 8 | image [offset + OPENTITAN_OFFSET_VERSION_MAJOR + 2 ] << 16 | image [offset + OPENTITAN_OFFSET_VERSION_MAJOR + 3 ] << 24 ;
24+ rom_ext -> minor = image [offset + OPENTITAN_OFFSET_VERSION_MINOR ] | image [offset + OPENTITAN_OFFSET_VERSION_MINOR + 1 ] << 8 | image [offset + OPENTITAN_OFFSET_VERSION_MINOR + 2 ] << 16 | image [offset + OPENTITAN_OFFSET_VERSION_MINOR + 3 ] << 24 ;
25+
26+ // Extract the offset that contains the APP version information
27+ uint32_t offset_app = offset + 65536 ;
28+ app -> major = image [offset_app + OPENTITAN_OFFSET_VERSION_MAJOR ] | image [offset_app + OPENTITAN_OFFSET_VERSION_MAJOR + 1 ] << 8 | image [offset_app + OPENTITAN_OFFSET_VERSION_MAJOR + 2 ] << 16 | image [offset_app + OPENTITAN_OFFSET_VERSION_MAJOR + 3 ] << 24 ;
29+ app -> minor = image [offset_app + OPENTITAN_OFFSET_VERSION_MINOR ] | image [offset_app + OPENTITAN_OFFSET_VERSION_MINOR + 1 ] << 8 | image [offset_app + OPENTITAN_OFFSET_VERSION_MINOR + 2 ] << 16 | image [offset_app + OPENTITAN_OFFSET_VERSION_MINOR + 3 ] << 24 ;
30+
31+ // Get the current version of the device
32+ libhoth_opentitan_version (dev , resp );
33+
34+ }
1735
1836int htool_dfu_update (const struct htool_invocation * inv ) {
1937 struct libhoth_device * dev = htool_libhoth_device ();
2038 if (!dev ) {
2139 return -1 ;
2240 }
2341
42+ struct opentitan_image_version rom_ext = {0 };
43+ struct opentitan_image_version app = {0 };
44+ struct opentitan_get_version_resp resp = {0 };
45+
2446 uint32_t complete_flags = 0 ;
2547 const char * reset_arg ;
2648 if (htool_get_param_string (inv , "reset" , & reset_arg )) {
@@ -68,25 +90,46 @@ int htool_dfu_update(const struct htool_invocation* inv) {
6890 if (image == MAP_FAILED ) {
6991 fprintf (stderr , "mmap error: %s\n" , strerror (errno ));
7092 goto cleanup ;
71- }
93+ }
94+
95+ process_image (dev , image , & rom_ext , & app , & resp );
7296
73- if (libhoth_dfu_update (dev , image , statbuf .st_size , complete_flags ) != 0 ) {
74- fprintf (stderr , "DFU update failed.\n" );
75- goto cleanup2 ;
97+ // Process the current boot slot
98+ uint32_t boot_slot = resp .primary_bl0_slot == kOpentitanBootSlotA ? 0 : 1 ;
99+
100+ if (resp .rom_ext .slots [boot_slot ].major != rom_ext .major || resp .rom_ext .slots [boot_slot ].minor != rom_ext .minor || resp .app .slots [boot_slot ].major != app .major || resp .app .slots [boot_slot ].minor != app .minor ) {
101+ printf ("Version mismatch\n" );
102+ // Perform the DFU update 2x to ensure the device is updated for both partitions
103+ for (int i = 0 ; i < 2 ; i ++ ) {
104+ if (libhoth_dfu_update (dev , image , statbuf .st_size , complete_flags ) != 0 ) {
105+ fprintf (stderr , "DFU update failed.\n" );
106+ goto cleanup2 ;
107+ }
108+ }
109+ }
110+ else {
111+ printf ("Version match\n" );
112+ return 0 ;
76113 }
114+
77115 retval = 0 ;
78116
79117 int ret ;
80- cleanup2 :
81- ret = munmap (image , statbuf .st_size );
82- if (ret != 0 ) {
83- fprintf (stderr , "munmap error: %d\n" , ret );
84- }
85118
86- cleanup :
87- ret = close (fd );
88- if (ret != 0 ) {
89- fprintf (stderr , "close error: %d\n" , ret );
90- }
119+ goto cleanup2 ;
120+ goto cleanup ;
121+
122+ cleanup2 :
123+ ret = munmap (image , statbuf .st_size );
124+ if (ret != 0 ) {
125+ fprintf (stderr , "munmap error: %d\n" , ret );
126+ }
127+
128+
129+ cleanup :
130+ ret = close (fd );
131+ if (ret != 0 ) {
132+ fprintf (stderr , "close error: %d\n" , ret );
133+ }
91134 return retval ;
92- }
135+ }
0 commit comments