66#include <h2_coproc.h>
77#include <h2_alloc.h>
88
9+ /* Number of context bits in a unit's context mask (one unsigned int). */
10+ #define COPROC_BITS_PER_UNIT (sizeof(unsigned int) * 8)
11+
912static unsigned int * configs [CFG_TYPE_MAX ][CFG_SUBTYPE_MAX ] = {NULL };
1013static unsigned int nunits [CFG_TYPE_MAX ][CFG_SUBTYPE_MAX ] = {0 };
1114static unsigned int * counts [CFG_TYPE_MAX ][CFG_SUBTYPE_MAX ][CFG_MAX ] = {NULL };
15+ static unsigned char * bitpos [CFG_TYPE_MAX ][CFG_SUBTYPE_MAX ][CFG_MAX ] = {NULL };
1216static unsigned int oldstyle = 0 ;
1317static unsigned int init_done = 0 ;
1418
19+ /* Record the bit positions of the set bits in `bits`, in ascending order, into `out`. */
20+ static void coproc_build_bitpos (unsigned int bits , unsigned char * out ) {
21+ unsigned int pos = 0 ;
22+ unsigned int k = 0 ;
23+
24+ while (bits ) {
25+ if (bits & 0x1 ) {
26+ out [k ++ ] = (unsigned char )pos ;
27+ }
28+ bits >>= 1 ;
29+ pos ++ ;
30+ }
31+ }
32+
33+ static int coproc_grow (void * * slot , int newsize ) {
34+ void * p = h2_realloc (* slot , newsize );
35+
36+ if (NULL == p ) {
37+ return -1 ;
38+ }
39+ * slot = p ;
40+ return 0 ;
41+ }
42+
1543int h2_coproc_count (h2_coproc_type_t type , h2_coproc_subtype_t subtype , h2_cfg_unit_entry entry_type , unsigned int unit_mask ) {
1644 unsigned int i ;
1745 int ret = 0 ;
@@ -63,39 +91,22 @@ int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_uni
6391
6492 unsigned int idx = 0 ; // unit being considered
6593 unsigned int ncontexts ;
66- unsigned int bits ;
6794 unsigned int xa ;
6895 unsigned int * entry ;
6996
7097 if (oldstyle || !enable ) {
71- return setbits (type , subtype , entry_type , num , enable ); //
98+ return setbits (type , subtype , entry_type , num , enable );
7299 }
73100
74101 num += 1 ; // num == number of existing contexts left to find
75-
102+
76103 while (num && idx < nunits [type ][subtype ]) { // still searching and in range
77104 if (unit_mask & (0x1 << idx )) { // unit selected
78105 entry = & configs [type ][subtype ][idx * CFG_MAX ];
79- bits = entry [entry_type ];
80- ncontexts = Q6_R_popcount_P (bits );
106+ ncontexts = counts [type ][subtype ][entry_type ][idx ];
81107 if (num <= ncontexts ) { // requested context # is in this unit
82- xa = 0 ; // index of bit
83- do {
84- if (bits & 0x1 ) { // context exists
85- if (0 == (-- num )) { // none left to find; now xa is correct
86- break ;
87- } else {
88- xa ++ ;
89- continue ;
90- }
91- } else { // context is missing
92- bits >>= 1 ; // check next bit
93- xa ++ ;
94- continue ;
95- }
96- } while (1 );
97-
98- // now xa is the index of the bit in the current unit that corresponds to the requested context #
108+ xa = bitpos [type ][subtype ][entry_type ][idx * COPROC_BITS_PER_UNIT + (num - 1 )];
109+
99110 setbits (type , subtype , entry_type , xa , enable );
100111 h2_hwconfig_set_coprocbits (entry [CFG_VXU_UNIT_ID ]); // FIXME: need to get the ID field for this unit type
101112 return 0 ;
@@ -109,33 +120,46 @@ int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_uni
109120 return -1 ;
110121}
111122
123+ /*
124+ * Populate the per-unit context count and logical->physical bit map for one
125+ * entry type (HVX/HLX/HMX) of a unit. Grows the count array to cover `idx`
126+ * and the bitpos array to cover this unit's COPROC_BITS_PER_UNIT slot.
127+ */
128+ static int init_entry_contexts (h2_coproc_type_t type , h2_coproc_subtype_t subtype , h2_cfg_unit_entry entry_type , unsigned int idx , unsigned int bits ) {
129+ if (-1 == coproc_grow ((void * * )& counts [type ][subtype ][entry_type ], (idx + 1 ) * sizeof (unsigned int ))) {
130+ return -1 ;
131+ }
132+ counts [type ][subtype ][entry_type ][idx ] = Q6_R_popcount_P (bits );
133+
134+ if (-1 == coproc_grow ((void * * )& bitpos [type ][subtype ][entry_type ], (idx + 1 ) * COPROC_BITS_PER_UNIT * sizeof (unsigned char ))) {
135+ return -1 ;
136+ }
137+ coproc_build_bitpos (bits , & bitpos [type ][subtype ][entry_type ][idx * COPROC_BITS_PER_UNIT ]);
138+
139+ return 0 ;
140+ }
141+
112142static int init_entry_vxu0 (unsigned int unit , h2_coproc_type_t type , h2_coproc_subtype_t subtype , unsigned int idx ) {
113143 unsigned int * entry ;
114144
115145 entry = & configs [type ][subtype ][idx * CFG_MAX ];
116146 entry [CFG_VXU_UNIT_ID ] = h2_info_unit (unit , CFG_VXU_UNIT_ID );
117147
118148 entry [CFG_HVX_CONTEXTS ] = h2_info_unit (unit , CFG_HVX_CONTEXTS );
119- if (NULL == (counts [type ][subtype ][CFG_HVX_CONTEXTS ] =
120- h2_realloc (counts [type ][subtype ][CFG_HVX_CONTEXTS ], (idx + 1 ) * sizeof (unsigned int )))) {
149+ if (-1 == init_entry_contexts (type , subtype , CFG_HVX_CONTEXTS , idx , entry [CFG_HVX_CONTEXTS ])) {
121150 return -1 ;
122151 }
123- counts [type ][subtype ][CFG_HVX_CONTEXTS ][idx ] = Q6_R_popcount_P (entry [CFG_HVX_CONTEXTS ]);
124-
152+
125153 entry [CFG_HLX_CONTEXTS ] = h2_info_unit (unit , CFG_HLX_CONTEXTS );
126- if (NULL == (counts [type ][subtype ][CFG_HLX_CONTEXTS ] =
127- h2_realloc (counts [type ][subtype ][CFG_HLX_CONTEXTS ], (idx + 1 ) * sizeof (unsigned int )))) {
154+ if (-1 == init_entry_contexts (type , subtype , CFG_HLX_CONTEXTS , idx , entry [CFG_HLX_CONTEXTS ])) {
128155 return -1 ;
129156 }
130- counts [type ][subtype ][CFG_HLX_CONTEXTS ][idx ] = Q6_R_popcount_P (entry [CFG_HLX_CONTEXTS ]);
131-
157+
132158 entry [CFG_HMX_CONTEXTS ] = h2_info_unit (unit , CFG_HMX_CONTEXTS );
133- if (NULL == (counts [type ][subtype ][CFG_HMX_CONTEXTS ] =
134- h2_realloc (counts [type ][subtype ][CFG_HMX_CONTEXTS ], (idx + 1 ) * sizeof (unsigned int )))) {
159+ if (-1 == init_entry_contexts (type , subtype , CFG_HMX_CONTEXTS , idx , entry [CFG_HMX_CONTEXTS ])) {
135160 return -1 ;
136161 }
137- counts [type ][subtype ][CFG_HMX_CONTEXTS ][idx ] = Q6_R_popcount_P (entry [CFG_HMX_CONTEXTS ]);
138-
162+
139163 return 0 ;
140164}
141165
@@ -147,58 +171,35 @@ static const initptr_t inits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {
147171 }
148172};
149173
150- int h2_coproc_init () {
174+ h2_coproc_init_result_t h2_coproc_init () {
151175 unsigned int unit ;
152176 h2_coproc_type_t type ;
153177 h2_coproc_subtype_t subtype ;
154178 unsigned int idx ;
155179
156180 if (init_done ) {
157- return 0 ;
181+ return oldstyle ? H2_COPROC_INIT_OLDSTYLE : H2_COPROC_INIT_OK ;
158182 }
159-
183+
160184 if (0 == (unit = h2_info (INFO_UNIT_START ))) { // old style
161185 oldstyle = 1 ;
162186 init_done = 1 ;
163- return 1 ;
187+ return H2_COPROC_INIT_OLDSTYLE ;
164188 }
165189
166- init_done = 1 ;
167190 while (unit ) {
168191 type = h2_info_unit (unit , CFG_UNIT_ID );
169192 subtype = h2_info_unit (unit , CFG_UNIT_SUBID );
170193 idx = nunits [type ][subtype ];
171- if (NULL == (configs [type ][subtype ] =
172- h2_realloc (configs [type ][subtype ], CFG_MAX * (idx + 1 ) * sizeof (unsigned int )))) {
173- return -1 ;
194+ if (-1 == coproc_grow ((void * * )& configs [type ][subtype ], CFG_MAX * (idx + 1 ) * sizeof (unsigned int ))) {
195+ return H2_COPROC_INIT_ERROR ;
174196 }
175197 nunits [type ][subtype ]++ ;
176- if (-1 == inits [type ][subtype ](unit , type , subtype , idx )) return -1 ;
198+ if (-1 == inits [type ][subtype ](unit , type , subtype , idx )) return H2_COPROC_INIT_ERROR ;
177199 unit = h2_info_unit (unit , CFG_UNIT_NEXT );
178200 }
179201
180- /* printf ("nunits 0x%08x\n", nunits[0][0]); */
181-
182- /* printf ("unit ID 0x%08x\n", configs[0][0][CFG_VXU_UNIT_ID]); */
183-
184- /* printf ("configs 0x%08x\n", configs[0][0][CFG_HVX_CONTEXTS]); */
185- /* printf ("configs 0x%08x\n", configs[0][0][CFG_HLX_CONTEXTS]); */
186- /* printf ("configs 0x%08x\n", configs[0][0][CFG_HMX_CONTEXTS]); */
187-
188- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HVX_CONTEXTS][0]); */
189- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HLX_CONTEXTS][0]); */
190- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HMX_CONTEXTS][0]); */
191-
192- /* printf ("unit ID 0x%08x\n", configs[0][0][CFG_MAX + CFG_VXU_UNIT_ID]); */
193-
194- /* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HVX_CONTEXTS]); */
195- /* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HLX_CONTEXTS]); */
196- /* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HMX_CONTEXTS]); */
197-
198- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HVX_CONTEXTS][1]); */
199- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HLX_CONTEXTS][1]); */
200- /* printf ("counts 0x%08x\n", counts[0][0][CFG_HMX_CONTEXTS][1]); */
201-
202- return 0 ;
202+ init_done = 1 ;
203+ return H2_COPROC_INIT_OK ;
203204}
204205
0 commit comments