1717#define PARTITION_LOCATION_AND_FLAGS_SIZE 2
1818#define PARTITION_ID_SIZE 2
1919#define PARTITION_NAME_MAX 127
20- #define PARTITION_SIZE_MAX (PARTITION_LOCATION_AND_FLAGS_SIZE + PARTITION_ID_SIZE + PARTITION_NAME_MAX + 1 )
20+ #define PARTITION_TABLE_FIXED_INFO_SIZE (4 + PARTITION_TABLE_MAX_PARTITIONS * (PARTITION_LOCATION_AND_FLAGS_SIZE + PARTITION_ID_SIZE) )
2121
2222/*
2323 * Stores partition table information and data read status
2424 */
2525typedef struct {
26- uint32_t workarea [4 + PARTITION_TABLE_MAX_PARTITIONS * PARTITION_SIZE_MAX ];
27- size_t table_size ;
26+ uint32_t table [PARTITION_TABLE_FIXED_INFO_SIZE ];
2827 uint32_t fields ;
2928 int partition_count ;
3029 uint32_t unpartitioned_space_first_sector ;
3130 uint32_t unpartitioned_space_last_sector ;
3231 uint32_t permission ;
3332 int current_partition ;
3433 size_t idx ;
34+ int status ;
3535} pico_partition_table_t ;
3636
3737/*
@@ -40,7 +40,7 @@ typedef struct {
4040typedef struct {
4141 uint32_t first_sector ;
4242 uint32_t last_sector ;
43- uint32_t permission ;
43+ uint32_t flags_and_permissions ;
4444 uint64_t partition_id ;
4545 char name [PARTITION_NAME_MAX + 1 ]; // name length is indicated by 7 bits
4646} pico_partition_t ;
@@ -51,71 +51,74 @@ typedef struct {
5151 *
5252 * See the RP2350 datasheet 5.1.2, 5.4.8.16 for flags and structures that can be specified.
5353 */
54- int pico_partitions_open (pico_partition_table_t * pt , int flags ) {
55- int rc = rom_get_partition_table_info (pt -> workarea , sizeof (pt -> workarea ), flags );
54+ int pico_partitions_open (pico_partition_table_t * pt ) {
55+ // Reads a fixed size fields
56+ int rc = rom_get_partition_table_info (pt -> table , sizeof (pt -> table ),
57+ (PT_INFO_PT_INFO |
58+ PT_INFO_PARTITION_LOCATION_AND_FLAGS |
59+ PT_INFO_PARTITION_ID ));
5660 if (rc < 0 ) {
61+ pt -> status = rc ;
5762 return rc ;
5863 }
59- pt -> table_size = rc * WORD_SIZE ; // word to bytes
6064
6165 size_t pos = 0 ;
62- pt -> fields = pt -> workarea [pos ++ ];
63- pt -> partition_count = pt -> workarea [pos ++ ] & 0x000000FF ;
64- uint32_t location = pt -> workarea [pos ++ ];
66+ pt -> fields = pt -> table [pos ++ ];
67+ pt -> partition_count = pt -> table [pos ++ ] & 0x000000FF ;
68+ uint32_t location = pt -> table [pos ++ ];
6569 pt -> unpartitioned_space_first_sector = PART_LOC_FIRST (location );
6670 pt -> unpartitioned_space_last_sector = PART_LOC_LAST (location );
67- pt -> permission = pt -> workarea [pos ++ ];
68- pt -> idx = pos ; // point to the beggining of eath partition
71+ pt -> permission = pt -> table [pos ++ ];
6972 pt -> current_partition = 0 ;
73+ pt -> idx = pos ;
74+ pt -> status = 0 ;
7075
7176 return 0 ;
7277}
7378
7479/*
75- * Parse a partition table and extract information
80+ * Extract each partition information
7681 */
77- size_t pico_partitions_parse (pico_partition_table_t * pt , pico_partition_t * p ) {
78- size_t idx = pt -> idx ;
79- if (pt -> fields & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
80- uint32_t location = pt -> workarea [idx ++ ];
81- p -> first_sector = PART_LOC_FIRST (location );
82- p -> last_sector = PART_LOC_LAST (location );
83- p -> permission = pt -> workarea [idx ++ ];
84- } else {
85- p -> first_sector = 0 ;
86- p -> last_sector = 0 ;
87- p -> permission = 0 ;
82+ bool pico_partitions_next (pico_partition_table_t * pt , pico_partition_t * p ) {
83+ if (pt -> current_partition >= pt -> partition_count ) {
84+ return false;
8885 }
8986
90- if (pt -> fields & PT_INFO_PARTITION_ID ) {
91- uint32_t id_low = pt -> workarea [idx ++ ];
92- uint32_t id_high = pt -> workarea [idx ++ ];
87+ size_t idx = pt -> idx ;
88+ uint32_t location = pt -> table [idx ++ ];
89+ p -> first_sector = PART_LOC_FIRST (location );
90+ p -> last_sector = PART_LOC_LAST (location );
91+ p -> flags_and_permissions = pt -> table [idx ++ ];
92+
93+ if (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS ) {
94+ uint32_t id_low = pt -> table [idx ++ ];
95+ uint32_t id_high = pt -> table [idx ++ ];
9396 p -> partition_id = ((uint64_t )id_high << 32 ) | id_low ;
9497 } else {
9598 p -> partition_id = 0 ;
9699 }
97-
98- if (pt -> fields & PT_INFO_PARTITION_NAME ) {
99- uint8_t * name_field = (uint8_t * )& pt -> workarea [idx ];
100- uint8_t name_length = name_field [0 ];
101- memcpy (p -> name , name_field + 1 , name_length );
100+ pt -> idx = idx ;
101+
102+ if (p -> flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ) {
103+ // Read variable length fields
104+ uint32_t name_buf [(PARTITION_NAME_MAX + 1 ) / WORD_SIZE ] = {0 };
105+ int rc = rom_get_partition_table_info (name_buf , sizeof (name_buf ),
106+ (pt -> current_partition << 24 |
107+ PT_INFO_SINGLE_PARTITION |
108+ PT_INFO_PARTITION_NAME ));
109+ if (rc < 0 ) {
110+ pt -> status = rc ;
111+ return false;
112+ }
113+ uint32_t __attribute__((unused )) fields = name_buf [0 ];
114+ uint8_t * name_buf_u8 = (uint8_t * )& name_buf [1 ];
115+ uint8_t name_length = * name_buf_u8 ++ ;
116+ memcpy (p -> name , name_buf_u8 , name_length );
102117 p -> name [name_length ] = '\0' ;
103- size_t total_name_field_length = 1 + name_length ;
104- idx += WORD_PADDED_BYTES (total_name_field_length ) / WORD_SIZE ;
105118 } else {
106119 p -> name [0 ] = '\0' ;
107120 }
108- return idx ;
109- }
110121
111- /*
112- * Extract one partition information
113- */
114- bool pico_partitions_next (pico_partition_table_t * pt , pico_partition_t * p ) {
115- if (pt -> current_partition >= pt -> partition_count ) {
116- return false;
117- }
118- pt -> idx = pico_partitions_parse (pt , p );
119122 pt -> current_partition ++ ;
120123 return true;
121124}
@@ -124,8 +127,7 @@ int main() {
124127 stdio_init_all ();
125128
126129 pico_partition_table_t pt ;
127- pico_partitions_open (& pt , PT_INFO_PT_INFO | PT_INFO_PARTITION_LOCATION_AND_FLAGS |
128- PT_INFO_PARTITION_ID | PT_INFO_PARTITION_NAME );
130+ pico_partitions_open (& pt );
129131 printf ("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s)\n" ,
130132 (pt .permission & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
131133 (pt .permission & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : "" ),
@@ -137,24 +139,26 @@ int main() {
137139 pico_partition_t p ;
138140 while (pico_partitions_next (& pt , & p )) {
139141 printf ("%3d:" , pt .current_partition - 1 );
140- if (pt .fields & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
141- printf (" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)" ,
142- p .first_sector * 4096 , p .last_sector * 4096 ,
143- (p .permission & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
144- (p .permission & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : "" ),
145- (p .permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : "" ),
146- (p .permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : "" ),
147- (p .permission & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : "" ),
148- (p .permission & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ));
149- }
150- if (pt .fields & PT_INFO_PARTITION_ID ) {
142+ printf (" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)" ,
143+ p .first_sector * 4096 , p .last_sector * 4096 ,
144+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
145+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : "" ),
146+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : "" ),
147+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : "" ),
148+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : "" ),
149+ (p .flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ));
150+ if (p .flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS ) {
151151 printf (", id=%016llx" , p .partition_id );
152152 }
153- if (pt . fields & PT_INFO_PARTITION_NAME ) {
153+ if (p . flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS ) {
154154 printf (", \"%s\"" , p .name );
155155 }
156156 printf ("\n" );
157157 }
158+ if (pt .status != 0 ) {
159+ fprintf (stderr , "rom_get_partition_table_info rc=%d\n" , pt .status );
160+ return 1 ;
161+ }
158162
159163 return 0 ;
160164}
0 commit comments