99#include "pico/bootrom.h"
1010#include "boot/picobin.h"
1111#include "hardware/flash.h"
12+ #include "uf2_family_ids.h"
1213
1314#define PART_LOC_FIRST (x ) ( ((x) & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB )
1415#define PART_LOC_LAST (x ) ( ((x) & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB )
1516
1617#define PARTITION_LOCATION_AND_FLAGS_SIZE 2
1718#define PARTITION_ID_SIZE 2
1819#define PARTITION_NAME_MAX 127
20+ #define PARTITION_EXTRA_FAMILY_ID_MAX 3
1921#define PARTITION_TABLE_FIXED_INFO_SIZE (4 + PARTITION_TABLE_MAX_PARTITIONS * (PARTITION_LOCATION_AND_FLAGS_SIZE + PARTITION_ID_SIZE))
2022
2123/*
@@ -43,6 +45,8 @@ typedef struct {
4345 uint32_t flags_and_permissions ;
4446 uint64_t partition_id ;
4547 char name [PARTITION_NAME_MAX + 1 ]; // name length is indicated by 7 bits
48+ uint32_t extra_family_id_count ;
49+ uint32_t extra_family_ids [PARTITION_EXTRA_FAMILY_ID_MAX ];
4650} pico_partition_t ;
4751
4852
@@ -101,25 +105,34 @@ bool read_next_partition(pico_partition_table_t *pt, pico_partition_t *p) {
101105 }
102106 pt -> pos = pos ;
103107
104- if (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ) {
108+ p -> extra_family_id_count = (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_BITS )
109+ >> PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_LSB ;
110+ if (p -> extra_family_id_count | (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS )) {
105111 // Read variable length fields
106- uint32_t name_buf [(( PARTITION_NAME_MAX + 1 ) / sizeof (uint32_t )) + 1 ] = { 0 } ;
107- uint32_t flags = PT_INFO_SINGLE_PARTITION | PT_INFO_PARTITION_NAME ;
108- int rc = rom_get_partition_table_info (name_buf , sizeof (name_buf ),
112+ uint32_t extra_family_id_and_name [ PARTITION_EXTRA_FAMILY_ID_MAX + ((( PARTITION_NAME_MAX + 1 ) / sizeof (uint32_t )) + 1 )] ;
113+ uint32_t flags = PT_INFO_SINGLE_PARTITION | PT_INFO_PARTITION_FAMILY_IDS | PT_INFO_PARTITION_NAME ;
114+ int rc = rom_get_partition_table_info (extra_family_id_and_name , sizeof (extra_family_id_and_name ),
109115 (pt -> current_partition << 24 | flags ));
110116 if (rc < 0 ) {
111117 pt -> status = rc ;
112118 return false;
113119 }
114- uint32_t __attribute__((unused )) fields = name_buf [0 ];
120+ size_t pos = 0 ;
121+ uint32_t __attribute__((unused )) fields = extra_family_id_and_name [pos ++ ];
115122 assert (fields == flags );
116- uint8_t * name_buf_u8 = (uint8_t * )& name_buf [1 ];
117- uint8_t name_length = * name_buf_u8 ++ & 0x7F ;
118- memcpy (p -> name , name_buf_u8 , name_length );
119- p -> name [name_length ] = '\0' ;
120- } else {
121- p -> name [0 ] = '\0' ;
123+ for (size_t i = 0 ; i < p -> extra_family_id_count ; i ++ , pos ++ ) {
124+ p -> extra_family_ids [i ] = extra_family_id_and_name [pos ];
125+ }
126+
127+ if (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ) {
128+ uint8_t * name_buf = (uint8_t * )& extra_family_id_and_name [pos ];
129+ uint8_t name_length = * name_buf ++ & 0x7F ;
130+ memcpy (p -> name , name_buf , name_length );
131+ p -> name [name_length ] = '\0' ;
132+ }
122133 }
134+ if (!(p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ))
135+ p -> name [0 ] = '\0' ;
123136
124137 pt -> current_partition ++ ;
125138 return true;
@@ -139,13 +152,20 @@ int main() {
139152 } else if (pt .partition_count == 0 ) {
140153 printf ("the partition table is empty\n" );
141154 }
142- printf ("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s)\n" ,
155+
156+ uf2_family_ids_t * family_ids = uf2_family_ids_new ();
157+ uf2_family_ids_add_default_families (family_ids , pt .flags_and_permissions );
158+ char * str_family_ids = uf2_family_ids_join (family_ids , ", " );
159+ printf ("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s) uf2 { %s }\n" ,
143160 (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
144161 (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : "" ),
145162 (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : "" ),
146163 (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : "" ),
147164 (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : "" ),
148- (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ));
165+ (pt .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ),
166+ str_family_ids );
167+ free (str_family_ids );
168+ uf2_family_ids_free (family_ids );
149169
150170 if (pt .partition_count == 0 ) {
151171 return 0 ;
@@ -154,6 +174,7 @@ int main() {
154174 pico_partition_t p ;
155175 while (read_next_partition (& pt , & p )) {
156176 printf ("%3d:" , pt .current_partition - 1 );
177+
157178 printf (" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)" ,
158179 p .first_sector * FLASH_SECTOR_SIZE , (p .last_sector + 1 ) * FLASH_SECTOR_SIZE ,
159180 (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
@@ -168,6 +189,18 @@ int main() {
168189 if (p .flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ) {
169190 printf (", \"%s\"" , p .name );
170191 }
192+
193+ // print UF2 family ID
194+ family_ids = uf2_family_ids_new ();
195+ uf2_family_ids_add_default_families (family_ids , p .flags_and_permissions );
196+ for (size_t i = 0 ; i < p .extra_family_id_count ; i ++ ) {
197+ uf2_family_ids_add_extra_family_id (family_ids , p .extra_family_ids [i ]);
198+ }
199+ str_family_ids = uf2_family_ids_join (family_ids , ", " );
200+ printf (", uf2 { %s }" , str_family_ids );
201+ uf2_family_ids_free (family_ids );
202+ free (str_family_ids );
203+
171204 printf ("\n" );
172205 }
173206 if (pt .status != 0 ) {
0 commit comments