11/**
2- * Copyright (c) 2025 Hiroyuki OYAMA <[email protected] > 32 * Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
43 *
54 * SPDX-License-Identifier: BSD-3-Clause
1211
1312#define PART_LOC_FIRST (x ) ( ((x) & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB )
1413#define PART_LOC_LAST (x ) ( ((x) & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB )
14+ #define WORD_PADDED_BYTES (x ) ((x + 3) & ~3)
1515
1616#define WORD_SIZE 4
17+ #define PARTITION_LOCATION_AND_FLAGS_SIZE 2
18+ #define PARTITION_ID_SIZE 2
19+ #define PARTITION_NAME_MAX 127
20+ #define PARTITION_SIZE_MAX (PARTITION_LOCATION_AND_FLAGS_SIZE + PARTITION_ID_SIZE + PARTITION_NAME_MAX + 1)
1721
1822/*
1923 * Stores partition table information and data read status
2024 */
2125typedef struct {
22- int flags ;
23- uint32_t * table ;
26+ uint32_t workarea [4 + PARTITION_TABLE_MAX_PARTITIONS * PARTITION_SIZE_MAX ];
2427 size_t table_size ;
28+ uint32_t fields ;
2529 int partition_count ;
2630 uint32_t unpartitioned_space_first_sector ;
2731 uint32_t unpartitioned_space_last_sector ;
2832 uint32_t permission ;
2933 int current_partition ;
3034 size_t idx ;
31- } pico_partition_t ;
35+ } pico_partition_table_t ;
3236
3337/*
3438 * Stores information on each partition
@@ -38,30 +42,30 @@ typedef struct {
3842 uint32_t last_sector ;
3943 uint32_t permission ;
4044 uint64_t partition_id ;
41- char name [127 + 1 ]; // name length is indicated by 7 bits
42- } pico_partition_entry_t ;
45+ char name [PARTITION_NAME_MAX + 1 ]; // name length is indicated by 7 bits
46+ } pico_partition_t ;
4347
4448
4549/*
4650 * Read the partition table information.
4751 *
4852 * See the RP2350 datasheet 5.1.2, 5.4.8.16 for flags and structures that can be specified.
4953 */
50- int pico_partitions_open (pico_partition_t * pt , int flags ) {
51- pt -> flags = flags ;
52- static uint32_t workarea [816 ];
53- int rc = rom_get_partition_table_info (workarea , sizeof (workarea ), flags );
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 );
5456 if (rc < 0 ) {
5557 return rc ;
5658 }
57- pt -> table = workarea ;
5859 pt -> table_size = rc * WORD_SIZE ; // word to bytes
59- uint32_t location = workarea [2 ];
60+
61+ 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 ++ ];
6065 pt -> unpartitioned_space_first_sector = PART_LOC_FIRST (location );
6166 pt -> unpartitioned_space_last_sector = PART_LOC_LAST (location );
62- pt -> permission = workarea [3 ];
63- pt -> partition_count = ((uint8_t * )workarea )[4 ];
64- pt -> idx = 4 ; // point to the beggining of eath table
67+ pt -> permission = pt -> workarea [pos ++ ];
68+ pt -> idx = pos ; // point to the beggining of eath partition
6569 pt -> current_partition = 0 ;
6670
6771 return 0 ;
@@ -70,37 +74,34 @@ int pico_partitions_open(pico_partition_t *pt, int flags) {
7074/*
7175 * Parse a partition table and extract information
7276 */
73- size_t pico_partitions_parse (pico_partition_t * pt , pico_partition_entry_t * p ) {
77+ size_t pico_partitions_parse (pico_partition_table_t * pt , pico_partition_t * p ) {
7478 size_t idx = pt -> idx ;
75- if (pt -> flags & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
76- uint32_t location = pt -> table [idx ++ ];
79+ if (pt -> fields & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
80+ uint32_t location = pt -> workarea [idx ++ ];
7781 p -> first_sector = PART_LOC_FIRST (location );
7882 p -> last_sector = PART_LOC_LAST (location );
79- p -> permission = pt -> table [idx ++ ];
83+ p -> permission = pt -> workarea [idx ++ ];
8084 } else {
8185 p -> first_sector = 0 ;
8286 p -> last_sector = 0 ;
8387 p -> permission = 0 ;
8488 }
8589
86- if (pt -> flags & PT_INFO_PARTITION_ID ) {
87- uint32_t id_low = pt -> table [idx ++ ];
88- uint32_t id_high = pt -> table [idx ++ ];
90+ if (pt -> fields & PT_INFO_PARTITION_ID ) {
91+ uint32_t id_low = pt -> workarea [idx ++ ];
92+ uint32_t id_high = pt -> workarea [idx ++ ];
8993 p -> partition_id = ((uint64_t )id_high << 32 ) | id_low ;
9094 } else {
9195 p -> partition_id = 0 ;
9296 }
9397
94- if (pt -> flags & PT_INFO_PARTITION_NAME ) {
95- uint8_t * name_field = (uint8_t * )& pt -> table [idx ];
98+ if (pt -> fields & PT_INFO_PARTITION_NAME ) {
99+ uint8_t * name_field = (uint8_t * )& pt -> workarea [idx ];
96100 uint8_t name_length = name_field [0 ];
97- uint8_t * name_src = name_field + 1 ;
98- memcpy (p -> name , name_src , name_length );
101+ memcpy (p -> name , name_field + 1 , name_length );
99102 p -> name [name_length ] = '\0' ;
100103 size_t total_name_field_length = 1 + name_length ;
101- // Name field is padded to word size
102- size_t padded_bytes = (total_name_field_length + 3 ) & ~((size_t )3 );
103- idx += padded_bytes / WORD_SIZE ;
104+ idx += WORD_PADDED_BYTES (total_name_field_length ) / WORD_SIZE ;
104105 } else {
105106 p -> name [0 ] = '\0' ;
106107 }
@@ -110,7 +111,7 @@ size_t pico_partitions_parse(pico_partition_t *pt, pico_partition_entry_t *p) {
110111/*
111112 * Extract one partition information
112113 */
113- bool pico_partitions_next (pico_partition_t * pt , pico_partition_entry_t * p ) {
114+ bool pico_partitions_next (pico_partition_table_t * pt , pico_partition_t * p ) {
114115 if (pt -> current_partition >= pt -> partition_count ) {
115116 return false;
116117 }
@@ -122,7 +123,7 @@ bool pico_partitions_next(pico_partition_t *pt, pico_partition_entry_t *p) {
122123int main () {
123124 stdio_init_all ();
124125
125- pico_partition_t pt ;
126+ pico_partition_table_t pt ;
126127 pico_partitions_open (& pt , PT_INFO_PT_INFO | PT_INFO_PARTITION_LOCATION_AND_FLAGS |
127128 PT_INFO_PARTITION_ID | PT_INFO_PARTITION_NAME );
128129 printf ("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s)\n" ,
@@ -133,10 +134,10 @@ int main() {
133134 (pt .permission & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : "" ),
134135 (pt .permission & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ));
135136 printf ("patitions:\n" );
136- pico_partition_entry_t p ;
137+ pico_partition_t p ;
137138 while (pico_partitions_next (& pt , & p )) {
138139 printf ("%3d:" , pt .current_partition - 1 );
139- if (pt .flags & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
140+ if (pt .fields & PT_INFO_PARTITION_LOCATION_AND_FLAGS ) {
140141 printf (" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)" ,
141142 p .first_sector * 4096 , p .last_sector * 4096 ,
142143 (p .permission & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : "" ),
@@ -145,12 +146,11 @@ int main() {
145146 (p .permission & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : "" ),
146147 (p .permission & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : "" ),
147148 (p .permission & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "" ));
148-
149149 }
150- if (pt .flags & PT_INFO_PARTITION_ID ) {
150+ if (pt .fields & PT_INFO_PARTITION_ID ) {
151151 printf (", id=%016llx" , p .partition_id );
152152 }
153- if (pt .flags & PT_INFO_PARTITION_NAME ) {
153+ if (pt .fields & PT_INFO_PARTITION_NAME ) {
154154 printf (", \"%s\"" , p .name );
155155 }
156156 printf ("\n" );
0 commit comments