Skip to content

Commit 94fefd7

Browse files
committed
coproc/vecaccess/mxaccess/lxaccess: extend test suite and refactor
Add comprehensive unit tests for mxaccess and lxaccess (previously untested), and replace the vecaccess smoke test with a full path-testing suite. All three tests share the same structure: unit_init with state verification, acquire/release/reuse bounded by a hardware-queried limit, a limit+1 blocking acquire via a second thread, double-release rejection, and a legacy-wrapper check. The tests derive the context limit by calling unit_init first (which latches the hardware style), then using h2_coproc_count() sign to mirror the impl's semaphore init logic for both oldstyle and newstyle hardware. Refactors in the implementation: - h2_coproc_init: fix one-shot regression (re-report OLDSTYLE on every call once latched; set init_done only after the full unit loop succeeds); add h2_coproc_init_result_t enum replacing magic 0/1/-1 - h2_coproc_set: replace per-call bit-scan with O(1) bitpos table lookup built at init time; remove redundant Q6_R_popcount_P call (use pre-computed counts[] array); remove dead `bits` local - h2_coproc: extract coproc_grow() helper, eliminating repeated realloc-assign-null-check pattern across init_entry_contexts and h2_coproc_init - h2_vecaccess/mxaccess/lxaccess release: add double-release guard (check active bit before releasing); fix idx passed to h2_coproc_set (was hardcoded 0); remove redundant h2_hwconfig_extbits call in vecaccess release - h2_vecaccess new-style branch: add missing HVX_64 case; align SILVER/SILVER_MAX sem init to use h2_coproc_count (was h2_info) - h2_vecaccess.h: add H2_VECACCESS_MAX_VLENGTH_BYTES replacing bare 128 Signed-off-by: Zeev Belinsky <zbelinsk@qti.qualcomm.com>
1 parent 9b0ddb8 commit 94fefd7

14 files changed

Lines changed: 757 additions & 103 deletions

File tree

libs/h2_compat/coproc/h2_coproc.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ Count coprocessor (context) instances
4141
*/
4242
int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int unit_mask, unsigned int num, unsigned int enable);
4343

44+
typedef enum {
45+
H2_COPROC_INIT_OK = 0,
46+
H2_COPROC_INIT_OLDSTYLE = 1,
47+
H2_COPROC_INIT_ERROR = -1,
48+
} h2_coproc_init_result_t;
49+
4450
/**
4551
Initialize coprocessor data
46-
@returns 0 on success; 1 to indicate absence of multi-unit configuration; -1 on error
52+
@returns H2_COPROC_INIT_OK on success; H2_COPROC_INIT_OLDSTYLE if multi-unit configuration is absent; H2_COPROC_INIT_ERROR on error
4753
@dependencies None
4854
*/
49-
int h2_coproc_init();
55+
h2_coproc_init_result_t h2_coproc_init();
5056

5157
/** @} */
5258

libs/h2_compat/coproc/h2_coproc.ref.c

Lines changed: 67 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,40 @@
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+
912
static unsigned int *configs[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {NULL};
1013
static unsigned int nunits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {0};
1114
static 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};
1216
static unsigned int oldstyle = 0;
1317
static 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+
1543
int 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+
112142
static 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

libs/h2_compat/lxaccess/h2_lxaccess.ref.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
int h2_lxaccess_unit_init(h2_lxaccess_state_t *lxacc, h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int unit_mask) {
1313
#ifdef HMX_HLX_SUPPORT
14-
int ret;
15-
14+
h2_coproc_init_result_t ret;
15+
1616
if ((ret = h2_coproc_init()) < 0) return ret;
1717

18-
if (1 == ret) { // old style
18+
if (H2_COPROC_INIT_OLDSTYLE == ret) { // old style
1919
h2_sem_init_val(&lxacc->sem, h2_info(INFO_HLX_CONTEXTS));
2020
} else {
2121
h2_sem_init_val(&lxacc->sem, h2_coproc_count(type, subtype, entry_type, unit_mask));
@@ -63,12 +63,16 @@ int h2_lxaccess_acquire(h2_lxaccess_state_t *lxacc) {
6363
#endif
6464
}
6565

66-
int h2_lxaccess_release(h2_lxaccess_state_t *lxacc, int idx)
66+
int h2_lxaccess_release(h2_lxaccess_state_t *lxacc, int idx)
6767
{
6868
#ifdef HMX_HLX_SUPPORT
6969
int ret;
7070

71-
ret = h2_coproc_set(lxacc->type, lxacc->subtype, lxacc->entry_type, lxacc->unit_mask, 0, 0);
71+
if (!(lxacc->active & (1u << idx))) {
72+
return -1;
73+
}
74+
75+
ret = h2_coproc_set(lxacc->type, lxacc->subtype, lxacc->entry_type, lxacc->unit_mask, idx, 0);
7276
h2_atomic_clrbit32(&lxacc->active, idx);
7377
h2_sem_up(&lxacc->sem);
7478

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#Hey emacs this is a -*- Makefile -*-
2+
BOOT=1
3+
OBJS+=test.o
4+
EXEC=test.elf
5+
6+
include Makefile.inc
7+
8+
CFLAGS += -v -G0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Hey emacs this is a -*- Makefile -*-
2+
3+
H2DIR=${UPDIR}../../../..
4+
5+
include ${H2DIR}/scripts/Makefile.inc.test

0 commit comments

Comments
 (0)